Filtrar um DataGrid em WPF

carrego uma lista de objectos num datagrid com isto:

dataGrid1.Items.Add(model);

OS model tornam-se dados de uma base de dados. Tem um Id(int), Name(string) e Text(string)

No meu datagrid só mostro o nome do model. Como posso filtrar o datagrid agora, quando eu digito algo em uma caixa de texto?

Eu estava nesta página. http://msdn.microsoft.com/en-us/library/vstudio/ff407126 (V = vs. 100).aspx mas eu não entendo o código de lá e não posso explicar como devo transpor isso para o meu problema.

Author: Karl_Schuhmann, 2013-03-22

5 answers

Existem várias formas de filtrar a recolha

Vamos sugerir que esta é a sua classe de itens.
public class Model
{
    public string Name
    {
        get;
        set;
    }
}

E a tua colecção parece

       var ObColl = new ObservableCollection<Model>();

        ObColl.Add(new Model() { Name = "John" });
        ObColl.Add(new Model() { Name = "Karl" });
        ObColl.Add(new Model() { Name = "Max" });
        ObColl.Add(new Model() { Name = "Mary" });
Via 1 (Predicado):
    public MainWindow()
    {
        InitializeComponent();

        // Collection which will take your ObservableCollection
        var _itemSourceList = new CollectionViewSource() { Source = ObColl };

        // ICollectionView the View/UI part 
        ICollectionView Itemlist = _itemSourceList.View;

        // your Filter
        var yourCostumFilter= new Predicate<object>(item => ((Model)item).Name.Contains("Max"));

        //now we add our Filter
        Itemlist.Filter = yourCostumFilter;

        dataGrid1.ItemsSource = Itemlist;
    }

Caminho 2 (FilterEventHandler):

    public MainWindow()
    {
        InitializeComponent();

        // Collection which will take your Filter
        var _itemSourceList = new CollectionViewSource() { Source = ObColl };

       //now we add our Filter
       _itemSourceList.Filter += new FilterEventHandler(yourFilter);

        // ICollectionView the View/UI part 
        ICollectionView Itemlist = _itemSourceList.View;

        dataGrid1.ItemsSource = Itemlist;
    }

    private void yourFilter(object sender, FilterEventArgs e)
    {
        var obj = e.Item as Model;
        if (obj != null)
        {
            if (obj.Name.Contains("Max"))
                e.Accepted = true;
            else
                e.Accepted = false;
        }
    }

Extensão da Informação à Via 1

Se necessitar de condições múltiplas ou de um filtro complexo, pode adicionar um método ao seu Predicat

    // your Filter
    var yourComplexFilter= new Predicate<object>(ComplexFilter);

    private bool ComplexFilter(object obj)
    {
        //your logic
    }
 32
Author: WiiMaxx, 2013-03-22 13:53:23

Esta é uma implementação simples de usar a propriedade filtrante da ICollectionView. Suponha que o seu XAML contém isto:

<TextBox x:Name="SearchTextBox" />
<Button x:Name="SearchButton"
        Content="Search"
        Click="SearchButton_OnClick"
        Grid.Row="1" />
<DataGrid x:Name="MyDataGrid"
          Grid.Row="2">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Lorem ipsum column"
                            Binding="{Binding}" />
    </DataGrid.Columns>
</DataGrid>

Depois, no construtor, poderá obter a vista predefinida para os seus dados, onde poderá definir o predicado do filtro que será executado para cada item da sua colecção. A janela de recolha não saberá quando deverá actualizar a colecção, pelo que terá de chamar a actualização quando o Utilizador carregar no botão Procurar.

private ICollectionView defaultView;

public MainWindow()
{
    InitializeComponent();

    string[] items = new string[]
    {
        "Asdf",
        "qwer",
        "sdfg",
        "wert",
    };

    this.defaultView = CollectionViewSource.GetDefaultView(items);
    this.defaultView.Filter =
        w => ((string)w).Contains(SearchTextBox.Text);

    MyDataGrid.ItemsSource = this.defaultView;
}

private void SearchButton_OnClick(object sender, RoutedEventArgs e)
{
    this.defaultView.Refresh();
}

Neste url você pode encontrar mais descrição pormenorizada das colectâneas: http://wpftutorial.net/DataViews.html

 5
Author: Loránd Biró, 2013-03-22 12:31:11

@WiiMaxx, não posso comentar como representante insuficiente. eu seria um pouco mais cuidadoso sobre os moldes diretos lá. Eles podem ser lentos para uma coisa e para outra, se o mesmo filtro foi aplicado a uma grade contendo diferentes tipos de dados complexos, você teria uma Invalidcastexcepção.

// your Filter
    var yourCostumFilter= new Predicate<object>(item =>
    {
        item = item as Model;
        return item == null || item.Name.Contains("Max");
    });

Isto não lhe irá quebrar o datagrid e não irá filtrar os resultados se o elenco falhar. Menos impacto para seus usuários se você ficar com o código errado. Além disso, o filtro será mais rápido devido ao"as" operador não fazendo qualquer tipo de coerção explícita como a operação cast direto vai.

 3
Author: steve, 2014-12-04 14:36:57

Veja a base de dados --> no seu caso, não adicione itens à sua grelha, mas defina o itemssource

<Datagrid ItemsSource="{Binding MyCollectionOfModels}" />

Ou

dataGrid1.ItemsSource = this._myCollectionOfModels;

E se quiser algum tipo de filtragem, ordenação, agrupamento, veja a vista de recolha

 0
Author: blindmeis, 2013-03-22 11:34:49

Pode usar o filtro dataview para filtrar as linhas datagrid.

            DataView dv = datatable.DefaultView;

            StringBuilder sb = new StringBuilder();
            foreach (DataColumn column in dv.Table.Columns)
            {
                sb.AppendFormat("[{0}] Like '%{1}%' OR ", column.ColumnName, "FilterString");
            }
            sb.Remove(sb.Length - 3, 3);
            dv.RowFilter = sb.ToString();
            dgvReports.ItemsSource = dv;
            dgvReports.Items.Refresh();

Onde o" datable "é o" datasource "dado ao seu datagrid e usando o construtor de cadeias de caracteres, você constrói a pesquisa do filtro onde "Filter String" é o texto que deseja procurar no seu datagrid e configurá-lo para dataview e, finalmente, definir a dataview como itemsource para o seu datagrid e actualizá-lo.

 0
Author: Joee, 2016-08-11 07:20:22