C# 在 WPF 中过滤 DataGrid
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15568325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Filter a DataGrid in WPF
提问by Karl_Schuhmann
I load a lists of objects in a datagrid with this:
我用这个加载数据网格中的对象列表:
dataGrid1.Items.Add(model);
The model
become data from a database. It has a Id(int)
, Name(string)
and Text(string)
将model
成为数据库中的数据。它有一个Id(int)
,Name(string)
和Text(string)
In my datagrid I show only the Name of the model
. How can I filter the datagrid now, when I enter something in a textbox?
在我的数据网格中,我只显示model
. 当我在文本框中输入内容时,现在如何过滤数据网格?
I was at this page: http://msdn.microsoft.com/en-us/library/vstudio/ff407126(v=vs.100).aspxbut I don't understand the code from there and I can not explain how I should transpose that for my problem.
我在这个页面上:http: //msdn.microsoft.com/en-us/library/vstudio/ff407126(v=vs.100).aspx但我不明白那里的代码,我无法解释如何我应该为我的问题转换它。
采纳答案by WiiMaxx
there are multiple way's to filter Collection
有多种过滤集合的方法
let's suggesting this is your Item Class
让我们建议这是您的项目类
public class Model
{
public string Name
{
get;
set;
}
}
and your collection looks like
你的收藏看起来像
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" });
Way 1 (Predicate):
方式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;
}
Way 2 (FilterEventHandler):
方式二(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;
}
}
extended Information to Way 1
将信息扩展到方式 1
if need multiple conditions or some complex Filter you can add a method to your Predicat
如果需要多个条件或一些复杂的过滤器,您可以向您的 Predicat 添加一个方法
// your Filter
var yourComplexFilter= new Predicate<object>(ComplexFilter);
private bool ComplexFilter(object obj)
{
//your logic
}
回答by blindmeis
take at look at DataBinding --> in your case dont add items to your grid, but set the itemssource
看看 DataBinding --> 在您的情况下,不要将项目添加到您的网格,而是设置项目源
<Datagrid ItemsSource="{Binding MyCollectionOfModels}" />
or
或者
dataGrid1.ItemsSource = this._myCollectionOfModels;
and if you want some kind of filtering,sorting, grouping look at CollectionView
如果您想要某种过滤、排序、分组,请查看CollectionView
回答by Loránd Biró
This is a simple implementation of using the Filter property of ICollectionView. Suppose your XAML contains this:
这是使用 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>
Then in the constructor you can get the default view for your data where you can set the filter predicate which will be executed for every item of your collection. The CollectionView won't know when it should update the collection, so you have to call Refresh when the user clicks the search button.
然后在构造函数中,您可以获得数据的默认视图,您可以在其中设置过滤谓词,该谓词将为您的集合的每个项目执行。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();
}
At this url you can find a more detailed description of CollectionViews: http://wpftutorial.net/DataViews.html
在这个 url 你可以找到更详细的 CollectionViews 描述:http: //wpftutorial.net/DataViews.html
回答by steve
@WiiMaxx, can't comment as not enough rep. I would be a bit more careful about the direct casts there. They can be slow for one thing and for another, if the same filter was applied to a grid holding different complex type data you would have an InvalidCastException.
@WiiMaxx,不能评论因为没有足够的代表。我会对那里的直接演员更加小心。一方面,它们可能会很慢,另一方面,如果将相同的过滤器应用于保存不同复杂类型数据的网格,则会出现 InvalidCastException。
// your Filter
var yourCostumFilter= new Predicate<object>(item =>
{
item = item as Model;
return item == null || item.Name.Contains("Max");
});
This will not break you datagrid and will not filter the results if the cast fails. Less impact to your users if you get the code wrong. On top of that the filter will be faster due to the "as" operator not doing any explicit type coercion as the direct cast operation will.
如果转换失败,这不会破坏您的数据网格并且不会过滤结果。如果您弄错了代码,对您的用户的影响就会减少。最重要的是,由于“as”运算符不会像直接转换操作那样执行任何显式类型强制,因此过滤器将更快。
回答by Joee
You can use dataview filter in order to filter the datagrid rows.
您可以使用数据视图过滤器来过滤数据网格行。
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();
Where the "datatable" is datasource given to your datagrid and using string builder you build the filter query where "Filter String" is the text you want to search in your datagrid and set it to dataview and finally set the dataview as itemsource to your datagrid and refresh it.
其中“数据表”是提供给数据网格的数据源,并使用字符串构建器构建过滤器查询,其中“过滤字符串”是要在数据网格中搜索的文本并将其设置为数据视图,最后将数据视图设置为数据网格的项目源并刷新它。