我在数据网格中加载一个对象列表:
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但是我不明白那里的代码,我无法解释如何为我的问题转换它。
答案 0 :(得分:32)
有多种方法来过滤收藏
让我们建议这是你的物品类
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" });
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;
}
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;
}
}
如果需要多个条件或某些复杂的过滤器,您可以向Predicat添加方法
// your Filter
var yourComplexFilter= new Predicate<object>(ComplexFilter);
private bool ComplexFilter(object obj)
{
//your logic
}
答案 1 :(得分:5)
这是使用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();
}
在此网址中,您可以找到有关CollectionViews的更详细说明: http://wpftutorial.net/DataViews.html
答案 2 :(得分:3)
// your Filter
var yourCostumFilter= new Predicate<object>(item =>
{
item = item as Model;
return item == null || item.Name.Contains("Max");
});
这不会破坏您的数据网格,并且如果转换失败则不会过滤结果。如果代码错误,对用户的影响较小。最重要的是,由于“as”操作符没有像直接强制转换操作那样进行任何显式类型强制,过滤器会更快。
答案 3 :(得分:0)
看一下DataBinding - &gt;在你的情况下,不要将项添加到你的网格,但设置itemssource
<Datagrid ItemsSource="{Binding MyCollectionOfModels}" />
或
dataGrid1.ItemsSource = this._myCollectionOfModels;
如果您想要某种过滤,排序,分组,请查看CollectionView
答案 4 :(得分:0)
您可以使用数据视图过滤器来过滤数据网格行。
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();
&#34;数据表&#34;是给数据网格的数据源,并使用字符串构建器构建过滤器查询,其中&#34; Filter String&#34;是您要在数据网格中搜索的文本,并将其设置为dataview,最后将dataview设置为itemsource到datagrid并刷新它。
答案 5 :(得分: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}"/>
设置textbox的datacontext为主类(一般在InitializeComponent()之后)
TB_search.DataContext = Me