首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有多个调用PropertyChanged的PropertyChanged属性

具有多个调用PropertyChanged的PropertyChanged属性
EN

Stack Overflow用户
提问于 2015-12-03 17:13:01
回答 5查看 2.3K关注 0票数 1

最近我一直在学习C#和WPF。我试图在我正在进行的项目中使用MVVM,只是为了使代码组织起来,并了解它是如何工作的。

在MVVM中,视图绑定上的控件绑定到ViewModel上的属性,该属性实现了INotifyPropertyChanged。通常情况下,当某个属性被更新时,我希望得到一组其他属性的更新结果。

例如,我有一个ListBox,上面有一个TextBox。您可以输入TextBox,它会过滤ListBox中的内容。但在某些情况下,我还需要能够从代码中清除TextBox。代码最后看起来是这样的:

代码语言:javascript
复制
private Collection<string> _listOfStuff;
public Collection<string> FilteredList
{
    get
    {
        if (String.IsNullOrWhiteSpace(SearchText))
        {
            return _listOfStuff;
        }
        else
        {
            return new Collection<string>(_listOfStuff.Where(x => x.Contains(SearchText)));
        }
    }
    set
    {
        if (value != _listOfStuff)
        {
            _listOfStuff = value;
            OnPropertyChanged("FilteredList");
        }
    }
}

private string _searchText;
public string SearchText
{
    get { return _searchText; }
    set
    {
        if (value != _searchText)
        {
            _searchText = value;
            OnPropertyChanged("SearchText"); // Tells the view to change the value of the TextBox
            OnPropertyChanged("FilteredList"); // Tells the view to update the filtered list
        }
    }
}

随着这个项目的规模越来越大,这个项目开始感到草率。我有一个设置者,有6个调用到OnPropertyChanged,这是很难保持跟踪的东西。有更好的方法吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-12-03 19:50:29

大约一年前,我在一个项目中试用了Assisticant。它会指出哪些属性需要发出通知,哪些属性是相关的。在Pluralsight上有一个很好的课程,网站上的例子也很好。如果没有其他的东西,您可以查看源代码,看看他是如何做到的。

同时也有一些来自MVVM层次结构中的更改通知的好建议。

他们提到:

使用属性->,例如DependsUpon(名称(大小))

乔希·史密斯的PropertyObserver

如果每次只需要引发相同的通知,则可以将raise属性更改调用放入方法中。

票数 1
EN

Stack Overflow用户

发布于 2015-12-03 18:29:13

首先,您不应该在命令中执行可能昂贵的操作,然后您将能够从您的OnPropertyChanged("FilteredList");中删除该SearchText

因此,您应该将该代码从getter移动到它自己的命令中,并从XAML绑定它(要么作为按钮上的命令,要么使用混合交互触发器在文本字段值更改时调用它)。

代码语言:javascript
复制
public ICommand SearchCommand { get; protected set; }
// Constructor
public MyViewModel()
{
    // DelegateCommand.FromAsyncHandler is from Prism Framework, but you can use
    // whatever your MVVM framework offers for async commands
    SearchCommand = DelegateCommand.FromAsyncHandler(DoSearch);
}

public async Task DoSearch() 
{
    var result = await _listOfStuff.Where(x => x.Contains(SearchText)).ToListAsync();
    FilteredList = new Collection<string>(result);
}

private Collection<string> _listOfStuff;
private Collection<string> _filteredList;
public Collection<string> FilteredList
{
    get
    {
        return _filteredList;
    }
    set
    {
        if (value != _filteredList)
        {
            _filteredList = value;
            OnPropertyChanged("FilteredList");
        }
    }
}

private string _searchText;
public string SearchText
{
    get 
    { 
        return _searchText;
    }
    set
    {
        if (value != _searchText)
        {
            _searchText = value;
            OnPropertyChanged("SearchText");
        }
    }
}

On :当您重命名您的属性时,您也可以使用OnPropertyChanged(nameof(FilteredList));拥有一个重构友好版本,所有的OnPropertyChanged调用都将更新到。虽然需要VisualStudio6.0,但它与旧的C#框架(回到2.0)兼容,但需要VisualStudio2015或更高版本

票数 1
EN

Stack Overflow用户

发布于 2017-11-07 15:29:53

对于任何寻找这类问题的好解决方案的人,请查看ReactiveUI

它是一个基于反应性扩展(Rx)的框架,它的思想是在没有大量RaisePropertyChanged(..)的情况下,显式地对属性之间的这种类型的依赖关系建模。

特别是查看ObservableAsPropertyHelper (有时称为OAPH)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34072156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档