web-dev-qa-db-ja.com

WPFでDataGridをフィルター処理する

これでデータグリッドにオブジェクトのリストをロードします:

_dataGrid1.Items.Add(model);
_

modelはデータベースのデータになります。 Id(int)Name(string)およびText(string)があります。

私のデータグリッドでは、modelの名前のみを表示しています。テキストボックスに何かを入力したときに、データグリッドをフィルタリングするにはどうすればよいですか?

私はこのページにいた: http://msdn.Microsoft.com/en-us/library/vstudio/ff407126(v = vs.100).aspx からのコードが理解できないそこに私はそれを私の問題のためにどのように転置するべきか説明できません。

12
Karl_Schuhmann

コレクションをフィルタリングする方法は複数あります

これがあなたのアイテムクラスであることを示唆しましょう

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

そしてあなたのコレクションは次のようになります

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

方法1(述語):

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

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

情報を方法1に拡張

複数の条件や複雑なフィルターが必要な場合は、Predicatにメソッドを追加できます

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

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

これは、ICollectionViewのFilterプロパティを使用する簡単な実装です。 XAMLにこれが含まれているとします。

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

次に、コンストラクターでデータのデフォルトビューを取得し、コレクションのすべてのアイテムに対して実行されるフィルター述語を設定できます。 CollectionViewはいつコレクションを更新する必要があるかを認識しないため、ユーザーが検索ボタンをクリックしたときにRefreshを呼び出す必要があります。

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

このURLで、CollectionViewsのより詳細な説明を見つけることができます。 http://wpftutorial.net/DataViews.html

5
Loránd Biró

@WiiMaxx、担当者が不足しているためコメントできません。そこでの直接キャストについてはもう少し注意が必要です。同じフィルターが別の複合型データを保持するグリッドに適用された場合、InvalidCastExceptionが発生する可能性があります。

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

これはデータグリッドを壊すことはなく、キャストが失敗した場合に結果をフィルタリングしません。コードを間違えても、ユーザーへの影響は少なくなります。さらに、「as」演算子が直接キャスト操作のように明示的な型強制を行わないため、フィルターが高速になります。

3
steve

データグリッド行をフィルタリングするために、dataviewフィルターを使用できます。

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

「datatable」はデータグリッドに与えられたデータソースであり、文字列ビルダーを使用してフィルタークエリを作成します。「フィルター文字列」はデータグリッドで検索するテキストであり、それをdataviewに設定し、最後にデータビューをitemsourceとしてデータグリッドに設定します。更新してください。

0
Joee

dataBindingを見てください->あなたのケースではアイテムをグリッドに追加せず、itemssourceを設定してください

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

または

dataGrid1.ItemsSource = this._myCollectionOfModels;

何らかのフィルタリング、並べ替え、グループ化が必要な場合は、 CollectionView を見てください。

0
blindmeis