c# - WPF:在没有清除/添加的情况下替换数据绑定(bind)集合内容

标签 c# wpf data-binding

当使用 WPF 数据绑定(bind)时,我显然不能按照 MyCollection = new CollectionType<Whatever>( WhateverQuery() ); 的方式进行操作因为绑定(bind)引用了旧集合。到目前为止,我的解决方法是 MyCollection.Clear();接下来是 foreach 做 MyCollection.Add(item); - 这对性能和美观来说都非常糟糕。

ICollectionView ,虽然很整洁,但也没有解决问题,因为它是 SourceCollection属性是只读的;真可惜,因为那将是一个不错且简单的解决方案。

其他人是如何处理这个问题的?应该提到的是,我正在做 MVVM,因此无法翻阅各个控件绑定(bind)。我想我可以围绕 ObservableCollection 做一个包装运动 ReplaceSourceCollection()方法,但在采用该方法之前,我想知道是否还有其他一些最佳实践。

编辑:

对于 WinForms,我会将控件绑定(bind)到 BindingSource ,允许我简单地更新它的 DataSource属性(property)并调用ResetBindings()方法 - 很快,底层集合有效地改变了。我会期望 WPF 数据绑定(bind)支持开箱即用的类似场景吗?

示例(伪)代码:WPF 控件(ListBox、DataGrid,无论您喜欢什么)都绑定(bind)到 Users属性(property)。我意识到集合应该是只读的,以避免 ReloadUsersBad() 所展示的问题。 ,但是这个例子的错误代码显然无法编译 :)

public class UserEditorViewModel
{
    public ObservableCollection<UserViewModel> Users { get; set; }

    public IEnumerable<UserViewModel> LoadUsersFromWhateverSource() { /* ... */ }

    public void ReloadUsersBad()
    {
        // bad: the collection is updated, but the WPF control is bound to the old reference.
        Users = new ObservableCollection<User>( LoadUsersFromWhateverSource() );
    }

    public void ReloadUsersWorksButIsInefficient()
    {
        // works: collection object is kept, and items are replaced; inefficient, though.
        Users.Clear();
        foreach(var user in LoadUsersFromWhateverSource())
            Users.Add(user);
    }

    // ...whatever other stuff.
}

最佳答案

如果对象 MyCollection 是实现 INotifyPropertyChanged 的对象,您可以简单地替换集合。

一个例子:

public class MyClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private ObservableCollection<Whatever> _myCollection;

    private void NotifyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public ObservableCollection<Whatever> MyCollection
    {
        get
        {
            return _myCollection;
        }
        set
        {
            if (!ReferenceEquals(_myCollection, value))
            {
                _myCollection = value;
                NotifyChanged("MyCollection");
            }
        }
    }
}

有了这个,当您分配一个集合时,WPF 会检测到这一点并且所有内容都会更新。

这就是我解决这个问题的方法。

关于c# - WPF:在没有清除/添加的情况下替换数据绑定(bind)集合内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4302945/

相关文章:

C# - 如何获取 "Everybody"用户?

C# WebSocketServer wss ://connection fail

c# - WPF DataTemplate 绑定(bind)取决于属性的类型

wpf - 在 XAML 中指定命名颜色的透明度级别

c# - 验证错误阻止调用属性 setter

wpf - 为什么带有转换器的多重绑定(bind)在工具提示中不起作用?

c# - 使用 asp.net core 进行集成测试(没有 View 的 Controller 测试)

c# - 使用 AvalonEdit 显示无效的 XML 语法

c# - WPF - 如何从按钮处理程序确定列表框中当前项目的索引

android - Google SignInButton 的 onClick 无法使用数据绑定(bind)