webentwicklung-frage-antwort-db.com.de

Filtern Sie ein DataGrid in WPF

Ich lade eine Liste von Objekten in ein Datagrid mit:

dataGrid1.Items.Add(model);

Die model werden Daten aus einer Datenbank. Es hat eine Id(int), Name(string) und Text(string)

In meinem Datagrid zeige ich nur den Namen der model an. Wie kann ich das Datagrid jetzt filtern, wenn ich etwas in ein Textfeld eingebe?

Ich war auf dieser Seite: http://msdn.Microsoft.com/de-de/library/vstudio/ff407126(v=vs.100).aspx aber ich verstehe den Code von dort und mir nicht kann nicht erklären, wie ich das für mein problem umsetzen sollte.

10
Karl_Schuhmann

es gibt mehrere Möglichkeiten, Collection zu filtern

lassen Sie uns vorschlagen, dass dies Ihre Artikelklasse ist

public class Model
{
    public string Name
    {
        get;
        set;
    }
}

und deine Sammlung sieht aus wie 

       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" });

Weg 1 (Prädikat):

    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;
    }

Weg 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;
        }
    }

erweiterte Informationen zu Weg 1

wenn Sie mehrere Bedingungen oder einen komplexen Filter benötigen, können Sie Ihrem Predicat eine Methode hinzufügen

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

    private bool ComplexFilter(object obj)
    {
        //your logic
    }
32
WiiMaxx

Dies ist eine einfache Implementierung der Verwendung der Filter-Eigenschaft von ICollectionView. Angenommen, Ihre XAML enthält Folgendes:

<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>

Im Konstruktor können Sie dann die Standardansicht für Ihre Daten anzeigen, in der Sie das Filterprädikat festlegen können, das für jedes Element Ihrer Sammlung ausgeführt wird. Die CollectionView weiß nicht, wann sie die Sammlung aktualisieren soll. Daher müssen Sie Refresh aufrufen, wenn der Benutzer auf die Suchschaltfläche klickt.

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();
}

Unter dieser URL finden Sie eine detaillierte Beschreibung von CollectionViews: http://wpftutorial.net/DataViews.html

5
Loránd Biró

@WiiMaxx, kann nicht als nicht genug Repräsentant kommentieren. Bei den direkten Casts wäre ich etwas vorsichtiger. Sie können sowohl für das eine als auch für das andere langsam sein, wenn derselbe Filter auf ein Raster angewendet wurde, das andere komplexe Datentypen enthält, die über eine InvalidCastException verfügen.

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

Dies wird Ihr Datagrid nicht beschädigen und die Ergebnisse nicht filtern, wenn der Cast fehlschlägt. Weniger Auswirkungen auf Ihre Benutzer, wenn der Code falsch ist. Darüber hinaus ist der Filter schneller, da der Operator "as" keinen expliziten Typzwang ausführt, wie dies bei der direkten Cast-Operation der Fall ist.

3
steve

Sie können den DataView-Filter verwenden, um die DataGrid-Zeilen zu filtern.

            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();

Wo das "datatable" eine Datenquelle ist, die an Ihr Datagrid übergeben wird, und mithilfe von String Builder erstellen Sie die Filterabfrage, wobei "Filterzeichenfolge" der Text ist, den Sie in Ihrem Datagrid durchsuchen möchten. Setzen Sie ihn auf "DataView" und setzen Sie die Datenansicht als Itemsource auf Ihr Datagrid und erfrischen Sie es.

0
Joee

schauen Sie sich DataBinding an -> Fügen Sie in Ihrem Fall keine Elemente zu Ihrem Raster hinzu, sondern legen Sie die Elementquelle fest

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

oder 

dataGrid1.ItemsSource = this._myCollectionOfModels;

und wenn Sie eine Art Filterung, Sortierung und Gruppierung wünschen, schauen Sie nach CollectionView

0
blindmeis