问题
I am trying to create a filtering system for a DataGrid in WPF just as in the link -
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...
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...
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
回答1:
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.
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 URGENT cases 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.
To present the data to the user, consider the following 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.
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 DefaultView if needs be.
来源:https://stackoverflow.com/questions/17261611/filtering-datagrid-binded-to-datatable-wpf