【问题标题】:How to filter DataGrid bound to DataContext如何过滤绑定到 DataContext 的 DataGrid
【发布时间】:2015-11-02 17:30:17
【问题描述】:

我应该为 DataGrid 添加过滤功能,该DataGrid 创建和绑定如下。

<DataGrid ItemsSource="{Binding Path=Things, Mode=TwoWay}" ...>
  ...
  <DataGrid.Columns>
    <DataGridTextColumn Header="Id" Binding="{Binding Id}" />
    ...
  </DataGrid.Columns>
</DataGrid>

根据MSDN article 我应该添加一个集合视图源并绑定到它。但是,在示例中,他们谈到了命名空间 local,我希望从数据上下文中获取我的东西。

<Window.Resources>
  <local:Tasks x:Key="tasks" />
    <CollectionViewSource x:Key="cvsTasks" 
                          Source="{StaticResource tasks}" 
                          Filter="CollectionViewSource_Filter" />
</Window.Resources>

有可能吗?当我尝试过时,我得到了一堆空单元格。单击它们用于打开一个对话框,其中单击的行的值是可编辑的(并预先填充了表中的数据),但现在我到处都是空框。我的版本是这样的。

<Window.Resources>
  <CollectionViewSource x:Key="ThingsFiltered"
                        Source="{Binding Path=Things}"
                        Filter="ThingsFiltered_OnFilter" />
</Window.Resources>

数据网格中的绑定现在是这样完成的。

<DataGrid ItemsSource="{Binding Source=ThingsFiltered}" ...>
  ...
  <DataGrid.Columns>
    <DataGridTextColumn Header="Id" Binding="{Binding Id}" />
    ...
  </DataGrid.Columns>
</DataGrid>

我的猜测是我没有正确绑定集合视图源。事实上,应该处理过滤器的方法根本没有被调用。在数据网格及其列中尝试了不同的语法之后,我承认我不知道如何使它工作。有什么建议吗?

【问题讨论】:

  • 你在哪里定义了“事物”?
  • @MaximeTremblay-Savard 在我的视图模型中。 Things 字段是其中的一部分,可在数据上下文中使用(直接绑定时)。它的类型是 ObservableCollection
  • 如果没有过滤器,您是否能够使用您的 Things 填充数据网格?
  • 另外,您能否发布您的 ThingsFiltered_OnFilter 实现
  • @MaximeTremblay-Savard 是的,在我添加集合视图源(直接绑定到在构造函数中设置为数据上下文的视图模型)之前,它可以完美运行。我在过滤器的处理程序中 throw new NotImplementedException() 但它没有到达那里。这就是为什么我要问是否可以过滤来自视图模型的东西,或者它们显示的过滤是否只能在本地资源或其他东西上完成。

标签: c# wpf xaml data-binding filter


【解决方案1】:

您可能遇到的问题是声明和您对 myThings 的使用。您需要确保在顶部定义local,然后在&lt;Window.Resources&gt; 中实例化您的列表。在&lt;CollectionViewSource&gt;Source 中使用它时,请确保在名称前写上StaticResource,而不是Binding

经过大量测试,这就是我的做法。我主要使用了 MSDN 文档背后的想法。

我的 MainWindow.xaml。您需要为当前解决方案定义本地。

<Window x:Class="WpfApplication18.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication18"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:Things x:Key="myThings"/>
    <CollectionViewSource x:Key="ThingsFiltered"
                    Source="{StaticResource myThings}"
                    Filter="ThingsFiltered_OnFilter" />
</Window.Resources>
<StackPanel>
    <DataGrid x:Name="dataGrid1" 
      ItemsSource="{Binding Source={StaticResource ThingsFiltered}}"
      CanUserAddRows="False">
    </DataGrid>
</StackPanel>

所以在这里,&lt;local:Things x:Key="myThings"/&gt; 的棘手部分是您在此处定义列表,然后绑定到此列表。

我的其他类很简单:

public class Thing
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Things: ObservableCollection<Thing>
{
    public Things()
    {
        this.Add(new Thing() { Id = 1, Name = "Maxime" });
        this.Add(new Thing() { Id = 2, Name = "Konrad" });
    }
}

这样做,它最终会命中过滤器代码并执行预期的操作:

private void ThingsFiltered_OnFilter(object sender, FilterEventArgs e)
{
    Thing thing = e.Item as Thing;

    if (thing.Name == "Maxime")
    {
        e.Accepted = true;
    }
    else
    {
        e.Accepted = false;
    }
}

【讨论】:

  • 啊啊啊啊,我刚看到。忘记本地。就是我在源定义中跳过了 {Static Resource xxx} 。它一直就在我眼前。不过,我觉得你已经做了很多工作,所以我会接受它作为答案(它确实有帮助,不是吗?)如果你也想要 +1 ,我希望您在回复的第一段中说明根本原因。您可能还想重新格式化代码示例中的大括号(它们有一点偏移),我觉得为了完整起见我们应该保留它。
  • 更正了大括号并添加了问题的最常见根本原因。
猜你喜欢
  • 2015-01-21
  • 2012-11-22
  • 2013-11-16
  • 2010-11-01
  • 1970-01-01
  • 2013-06-20
  • 2012-02-12
  • 2012-12-25
  • 2021-08-29
相关资源
最近更新 更多