You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将ObservableCollection绑定到两个按IsWhite筛选的DataGrid?

这问题我之前做WPF项目时也遇到过,最靠谱的方案是用CollectionViewSource来做过滤,既能自动响应原集合的增删,还能处理单个项属性变化的情况,下面给你详细说两种常用方式:

方法一:使用CollectionViewSource(推荐,支持自动更新)

这是WPF中处理集合过滤的标准方式,能完美适配ObservableCollection的动态变化,包括集合增删项、单个项属性修改的场景。

步骤1:确保类A实现INotifyPropertyChanged(关键)

如果你的isWhiteEnum属性会在运行时被修改,类A必须实现INotifyPropertyChanged接口,否则修改属性后过滤视图不会自动更新:

public enum IsWhite
{
    True,
    False
}

public class A : INotifyPropertyChanged
{
    private IsWhite _isWhiteEnum = IsWhite.False;
    public IsWhite isWhiteEnum
    {
        get => _isWhiteEnum;
        set
        {
            if (_isWhiteEnum != value)
            {
                _isWhiteEnum = value;
                OnPropertyChanged(nameof(isWhiteEnum));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤2:在ViewModel中创建过滤视图

在你的ViewModel(推荐MVVM模式,也可以用窗口后台代码)里,创建两个ICollectionView,分别过滤出对应枚举值的项:

public class YourViewModel : INotifyPropertyChanged
{
    public ObservableCollection<A> ACollection { get; set; } = new ObservableCollection<A>();

    // 绑定到第一个DataGrid:过滤isWhiteEnum为False的项
    public ICollectionView FalseItemsView { get; }
    // 绑定到第二个DataGrid:过滤isWhiteEnum为True的项
    public ICollectionView TrueItemsView { get; }

    public YourViewModel()
    {
        // 为False项创建视图并启用实时过滤
        var falseCvs = new CollectionViewSource { Source = ACollection };
        falseCvs.LiveFilteringProperties.Add(nameof(A.isWhiteEnum));
        falseCvs.IsLiveFilteringRequested = true;
        falseCvs.View.Filter = item => ((A)item).isWhiteEnum == IsWhite.False;
        FalseItemsView = falseCvs.View;

        // 为True项创建视图并启用实时过滤
        var trueCvs = new CollectionViewSource { Source = ACollection };
        trueCvs.LiveFilteringProperties.Add(nameof(A.isWhiteEnum));
        trueCvs.IsLiveFilteringRequested = true;
        trueCvs.View.Filter = item => ((A)item).isWhiteEnum == IsWhite.True;
        TrueItemsView = trueCvs.View;
    }

    // ViewModel的INotifyPropertyChanged实现(如果需要通知其他属性变化)
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤3:XAML中绑定DataGrid

直接把两个DataGrid的ItemsSource绑定到对应的视图即可:

<!-- 绑定isWhiteEnum为False的项 -->
<DataGrid ItemsSource="{Binding FalseItemsView}" />
<!-- 绑定isWhiteEnum为True的项 -->
<DataGrid ItemsSource="{Binding TrueItemsView}" />
方法二:使用Linq查询(简单但不支持自动更新)

如果你的集合不会动态增删,且isWhiteEnum属性不会修改,也可以用Linq的Where方法直接过滤,但这种方式的缺点是原集合变化时,视图不会自动更新,需要手动触发刷新:

ViewModel中的代码:

public class YourViewModel : INotifyPropertyChanged
{
    public ObservableCollection<A> ACollection { get; set; } = new ObservableCollection<A>();

    // 注意:这里是IEnumerable<A>,不是ObservableCollection
    public IEnumerable<A> FalseItems => ACollection.Where(a => a.isWhiteEnum == IsWhite.False);
    public IEnumerable<A> TrueItems => ACollection.Where(a => a.isWhiteEnum == IsWhite.True);

    // 原集合变化后,手动调用此方法通知UI更新
    public void RefreshFilteredItems()
    {
        OnPropertyChanged(nameof(FalseItems));
        OnPropertyChanged(nameof(TrueItems));
    }

    // INotifyPropertyChanged实现
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML绑定:

<DataGrid ItemsSource="{Binding FalseItems}" />
<DataGrid ItemsSource="{Binding TrueItems}" />

注意:每次ACollection增删项或者isWhiteEnum修改后,都要调用RefreshFilteredItems()来通知UI更新,否则DataGrid不会显示最新的过滤结果。

关键提醒
  • 如果需要动态响应集合增删和属性变化,一定要用方法一的CollectionViewSource+LiveFiltering,这是WPF的最佳实践。
  • 类A必须实现INotifyPropertyChanged,否则单个项的isWhiteEnum修改后,过滤视图不会自动更新。

内容的提问来源于stack exchange,提问作者sushi7777

火山引擎 最新活动