【问题标题】:Filtering Datagrid Binded to DataTable WPF过滤 Datagrid 绑定到 DataTable WPF
【发布时间】:2013-06-20 03:23:44
【问题描述】:

我正在尝试在 WPF 中为 DataGrid 创建一个过滤系统,就像在链接中一样 -

http://www.codeproject.com/Articles/42227/Automatic-WPF-Toolkit-DataGrid-Filtering

我正在使用他们正在使用的同一个库,但问题是我需要将我的 DataGrid 绑定到数据表...

而且有错误的地方..只要 ItemSource 是 LIST,过滤器库就可以完美运行,但当 ItemSource 是 DataTable 时停止工作...

任何替代方案或建议???工作示例表示赞赏..

我使用 AutoColumnGeneration=True 因为我不知道需要填充多少列

【问题讨论】:

  • 您是否尝试将 ItemSource 绑定到从 DataTable 中获取的 CollectionViewSource?
  • 实际上是我的 AutoColumnGeneration = TRUE.. 因为我不知道我需要填充的确切列数.. 现在有什么建议
  • 我以前必须这样做。但是这项工作的导火索很短,所以我从行中创建了一个 CollectionViewSource 并使用了一个定制的值转换器。它工作得很好,但我相信有更好的方法。同样在第一种情况下,您不能将围绕强类型集合包装的代码与数据表一起使用,因为数据表使用盒装数组!
  • 我可以有一个相同的工作样本吗??
  • 如果没有其他人提供某些东西,我可以检查我的东西并找到它,但是您愿意接受快速解决方案吗?

标签: wpf wpf-controls wpfdatagrid wpf-4.0


【解决方案1】:

表中的每个 DataRow 都包含一个平面对象数组,其类型只能通过从 DataColumns 数组中提取来访问。由于 Array 中的所有内容都已装箱,因此依赖于强类型集合的库(如 List of T)将不兼容。这应该可以解释为什么它不起作用。

您写道这很紧急,我不得不在一个非常短的导火索的项目中做一次相同类型的事情,我将概述我的方法。此答案仅适用于 URGENT 案例。

这是一个 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));
        }
    }
}

构造函数接受一个 DataTable 并使用 Rows 作为 CollectionView 的绑定源。由于 CollectionView 具有内置的过滤和排序属性,因此它是用作绑定源的绝佳工具。同样如图所示,构造函数为示例添加了一个过滤器以帮助您入门。

要将数据呈现给用户,请考虑以下 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>

这是一个 DataGrid,其 ItemsSource 绑定到在 ViewModel 中声明和分配的 CollectionView。每列数据与一个参数一起通过转换器传递,该参数告诉转换器它需要做什么。

为了限制一切,这里是转换器...

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;
    }
}

当您有 DataTable 和紧急情况时,这应该可以让您重回正轨,进行过滤和呈现。全部编码大约需要一个小时。另请注意,我的绑定到 Rows,但如果需要,您也可以绑定到 DefaultView

【讨论】:

    猜你喜欢
    • 2013-07-28
    • 2018-02-07
    • 2023-04-06
    • 2011-08-17
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 2012-11-16
    相关资源
    最近更新 更多