20

我使用以下方法在数据网格中加载对象列表:

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但我不明白那里的代码,我无法解释如何我应该为我的问题转置它。

4

6 回答 6

49

有多种过滤收藏的方法

让我们建议这是您的项目类

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
    }
于 2013-03-22T13:30:56.360 回答
9

这是使用 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

于 2013-03-22T12:31:11.693 回答
5

@WiiMaxx,不能评论为没有足够的代表。我会更加小心那里的直接演员表。一方面它们可能很慢,另一方面,如果将相同的过滤器应用于包含不同复杂类型数据的网格,您将遇到 InvalidCastException。

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

这不会破坏您的数据网格,并且如果转换失败也不会过滤结果。如果代码错误,对用户的影响会更小。最重要的是,由于“as”运算符没有像直接强制转换操作那样进行任何显式类型强制,过滤器会更快。

于 2014-12-04T14:36:57.127 回答
0

看看 DataBinding --> 在你的情况下不要将项目添加到你的网格中,而是设置 itemssource

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

或者

dataGrid1.ItemsSource = this._myCollectionOfModels;

如果您想要某种过滤、排序、分组,请查看CollectionView

于 2013-03-22T11:34:49.677 回答
0

您可以使用 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();

其中“数据表”是提供给数据网格的数据源,使用字符串构建器构建过滤器查询,其中“过滤器字符串”是要在数据网格中搜索的文本并将其设置为数据视图,最后将数据视图设置为数据网格的项目源并刷新它。

于 2016-08-11T07:20:22.883 回答
0

我找到了一个愚蠢的方法,知道这是一个老问题,但是......只需在 DataGrid 对象上的 items 属性上使用 Filter 函数。像这样:(对不起,我只学了VB)

Public Property SearchName As String
    Get
        Return _SearchName
    End Get
    Set
        _SearchName = Value
        DG_drw_overview.Items.Filter = New Predicate(Of Object)(Function(x) x.Name.Contains(Value))           
    End Set
End Property

每次在文本框中键入内容时,此属性都会更改。DG_drw_overview 是 DataGrid 实例。在 Predicate 中,对象代表您放入 DataGrid 中的对象。

然后将 SearchName 绑定到文本框

<TextBox x:Name="TB_search" 
         Text="{Binding SearchName, UpdateSourceTrigger=PropertyChanged}"/>

将文本框的datacontext设置为主类(通常在InitializeComponent()之后)

TB_search.DataContext = Me
于 2021-06-25T11:22:01.597 回答