过滤绑定到 DataTable WPF 的 Datagrid
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17261611/
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
Filtering Datagrid Binded to DataTable WPF
提问by Rajat Suneja
I am trying to create a filtering system for a DataGrid in WPF just as in the link -
我正在尝试为 WPF 中的 DataGrid 创建一个过滤系统,就像在链接中一样 -
http://www.codeproject.com/Articles/42227/Automatic-WPF-Toolkit-DataGrid-Filtering
http://www.codeproject.com/Articles/42227/Automatic-WPF-Toolkit-DataGrid-Filtering


I am using the same library that they are using but the thing is I need to bind my DataGrid to a datatable...
我使用的库与他们使用的库相同,但问题是我需要将 DataGrid 绑定到数据表...
And there is where the error is.. the filter library works perfectly as long as the ItemSource is a LIST but stops to work when the ItemSource is a DataTable...
并且有错误的地方.. 只要 ItemSource 是一个 LIST 过滤器库就可以完美地工作,但是当 ItemSource 是一个 DataTable 时它就会停止工作......
Any Alternatives or Suggestions??? Working Examples appreciated..
任何替代方案或建议???工作示例赞赏..
I am using AutoColumnGeneration=True since i don't know how many column do i need to populate
我正在使用 AutoColumnGeneration=True 因为我不知道我需要填充多少列
回答by Gayot Fow
Each DataRow in a table contains a flat Array of objects whose type is accessible only by extracting it from the DataColumns array. Since everything in the Array is boxed, a library that relies upon a strongly typed collection, like List of T will not be compatible. That should explain why it's not working.
表中的每个 DataRow 都包含一个平面对象数组,其类型只能通过从 DataColumns 数组中提取来访问。由于 Array 中的所有内容都是装箱的,因此依赖于强类型集合的库(如 T 的列表)将不兼容。这应该可以解释为什么它不起作用。
You wrote that it's urgent and I had to do the same type of thing once in a project with a very short fuse and I'll outline my approach. This answer is for URGENTcases only.
你写道它很紧急,我不得不在一个非常短的保险丝的项目中做同样类型的事情,我将概述我的方法。此答案仅适用于紧急情况。
Here's a ViewModel...
这是一个视图模型...
public class ViewModel : INotifyPropertyChanged
{
public CollectionView MyCollectionView { get; set; }
public ViewModel(DataTable dataTable)
{
MyCollectionView = CollectionViewSource.GetDefaultView(dataTable.Rows) as CollectionView;
if (MyCollectionView != null)
{
MyCollectionView.Filter = o => (o as DataRow).ItemArray[0].ToString().Contains("2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
The Constructor takes a DataTable and uses the Rows as the binding source to a CollectionView. Since the CollectionView has built-in filtering and sorting properties, it's a great tool to use as a binding source. Also as shown, the Constructor adds a filter for an example to help get you started.
构造函数采用 DataTable 并使用 Rows 作为 CollectionView 的绑定源。由于 CollectionView 具有内置的过滤和排序属性,因此它是用作绑定源的绝佳工具。同样如图所示,构造函数为示例添加了一个过滤器,以帮助您入门。
To present the data to the user, consider the following Xaml...
要将数据呈现给用户,请考虑以下 Xaml...
<DataGrid ItemsSource="{Binding MyCollectionView}"
AutoGenerateColumns="False"
CanUserSortColumns="True"
IsReadOnly="True"
>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding ., Converter=
{db:DbConverter}, ConverterParameter=PersonName}"/>
<DataGridTextColumn Header="Address" Binding="{Binding ., Converter=
{db:DbConverter}, ConverterParameter=PersonAddress}"/>
</DataGrid.Columns>
</DataGrid>
This is a DataGrid whose ItemsSource is bound to the CollectionView that was declared and assigned in the ViewModel. Each column of data is passed through a converter along with a parameter which tells the converter what it needs to do.
这是一个 DataGrid,其 ItemsSource 绑定到在 ViewModel 中声明和分配的 CollectionView。每列数据都通过一个转换器以及一个告诉转换器它需要做什么的参数。
To cap everything off, here's the converter...
为了结束一切,这是转换器......
public class DbConverter : MarkupExtension, IValueConverter
{
private static readonly Dictionary<object, int> ParameterToColumnMapping;
static DbConverter()
{
ParameterToColumnMapping = new Dictionary<object, int>
{
{"PersonName", 0}, {"PersonAddress", 1}
};
}
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
DataRow dr = value as DataRow;
if (dr != null)
{
if (ParameterToColumnMapping.ContainsKey(parameter))
{
return dr.ItemArray[ParameterToColumnMapping[parameter]];
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
That should get you back on track with filtering and presenting when you have a DataTable and an urgent situation. All in the coding takes about an hour. Note also that mine binds to the Rows, but you can also bind to the DefaultViewif needs be.
当您有 DataTable 和紧急情况时,这应该让您通过过滤和呈现重新回到正轨。整个编码过程大约需要一个小时。另请注意,我的绑定到Rows,但如果需要,您也可以绑定到DefaultView。

