DataGrid 不过滤?

DataGrid not filtering?

我有以下 UI 定义并且构建良好。

当我运行它也没有绑定错误。

DEBUG 选项卡似乎包含 Collection 中定义的四个项目,但其他 TabViews 是空的。

我已经尝试查看是否在我的过滤器中命中了任何断点,但它们似乎没有命中?

最小示例:

MainWindow.xaml

<Window x:Class="Dummy.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Dummy" >

    <Window.Resources>
        <local:TestList x:Key="TestList"/>
        <CollectionViewSource x:Key="NoScope" Source="{Binding TestList}" Filter="NoScopeFilter" />
        <CollectionViewSource x:Key="Scope" Source="{Binding TestList}" />
        <CollectionViewSource x:Key="ScopeCodeBehind" Source="{Binding TestList}" Filter="ScopeFilter" />
    </Window.Resources>

    <Grid>
        <TabControl>
            <TabItem Header="DEBUG">
                <DataGrid Name="DEBUG" AutoGenerateColumns="True" ItemsSource="{Binding Source={StaticResource TestList}}" />
            </TabItem>
            <TabItem Header="NoScope">
                <DataGrid Name="NoScope" AutoGenerateColumns="True" ItemsSource="{Binding Source={StaticResource NoScope}}" />
            </TabItem>
            <TabItem Header="Scope">
                <DataGrid Name="Scope" AutoGenerateColumns="True" ItemsSource="{Binding Source={StaticResource Scope}}" />
            </TabItem>
            <TabItem Header="Scope (CB)">
                <DataGrid Name="ScopeCB" AutoGenerateColumns="True" ItemsSource="{Binding Source={StaticResource ScopeCodeBehind}}" />
            </TabItem>
        </TabControl>
    </Grid>
</Window>

MainWindow.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;

namespace Dummy
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void NoScopeFilter(object sender, FilterEventArgs e)
        {
            if (e.Item is Test test)
            {
                e.Accepted = true;
            }
        }

        private void ScopeFilter(object sender, FilterEventArgs e)
        {
            if (e.Item is Test test)
            {
                e.Accepted = test.Scope.Equals("Scope", StringComparison.OrdinalIgnoreCase);
            }
        }

    }


    public abstract class Test
    {
        private string desciption;
        private string scope;

        public string Name { get; set; }
        public string Desciption { get => desciption; set => desciption = value; }
        public string ExpectedValue { get; set; }
        public string ActualValue { get; set; }
        public string Scope { get => scope; set => scope = value; }
        public abstract bool Result { get; }
        protected Test(string name, string expected, string actual, string scope = null)
        {
            this.Name = name;
            this.ActualValue = actual;
            this.ExpectedValue = expected;
            this.Scope = scope;
        }
    }

    public class IsEqual : Test
    {
        public IsEqual(string name, string expected, string actual, string scope = "") : base(name, expected, actual, scope)
        {
        }

        public override bool Result { get { return this.ActualValue == this.ExpectedValue; } }
    }

    public class IsNotEqual : IsEqual
    {
        public IsNotEqual(string name, string expected, string actual, string scope = "") : base(name, expected, actual, scope)
        {
        }

        public override bool Result { get { return !base.Result; } }
    }

    public class TestList : ObservableCollection<Test>
    {
        public TestList()
        {
            string actual = "test";
            string expected = "TesT";
            this.Add(new IsEqual("Should be equal", expected.ToLower(), actual));
            this.Add(new IsNotEqual("Should not be equal", expected, actual));
            this.Add(new IsEqual("Should be equal (with scope)", expected.ToLower(), actual, "scope"));
            this.Add(new IsNotEqual("Should not be equal (with another scope)", expected, actual, "another scope"));
        }

    }
}

您对 CollectionViewSource.Source 属性的数据绑定是错误的。他们当前绑定到他们的 DataContext,它不引用 TestList 资源(CollectionViewSource 甚至没有 DataContext 因为它没有扩展 FrameworkElement).您必须使用 StaticResource 标记扩展引用资源:

<Window.Resources>
  <local:TestList x:Key="TestList"/>
  <CollectionViewSource x:Key="NoScope" Source="{StaticResource TestList}" Filter="NoScopeFilter" />
  <CollectionViewSource x:Key="Scope" Source="{StaticResource TestList}" />
  <CollectionViewSource x:Key="ScopeCodeBehind" Source="{StaticResource TestList}" Filter="ScopeFilter" />
</Window.Resources>