65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 RaisePropertyChanged 方法的最安全方式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.72/5 (9投票s)

2013 年 11 月 14 日

CPOL

2分钟阅读

viewsIcon

60279

downloadIcon

610

使用 RaisePropertyChanged 方法的最安全方式。

引言

在我的上一篇关于 最简单的 MVVM 的文章中,我给出了实现 MVVM 的最简单概述。现在,我想通过选择各个领域来扩展我之前的文章。这一次,我选择了 RaisePropertyChanged。所有从事 XAML 相关应用开发的开发者都非常了解这个 RaisePropertyChanged 的用途。我相信,我们大多数人都知道在哪里使用它。但是,每个人都知道正确的或者说通用的使用方法吗? 即使你不知道,也没关系。在本文的结尾,你一定会带走一个关于使用 RaisePropertyChanged 的实用技巧。

背景

正如我们所知,MVVM 提供了一种松耦合的方法。在很多地方,这种架构非常有用,但代价是需要你保持警惕。因为当我们谈论 MVVM 时,我们通常会说 ViewModel 对 View 没有了解,而属性是 View 和 ViewModel 绑定以在 UI 上显示数据的方式。这里有一个陷阱!

ViewModels 实现了 INotifyPropertyChanged 接口,以便 ViewModel 中的属性更改可以传递到 View。让我们以一个示例属性为例,以便更好地理解

public string SelectedName
{
    get { return _selectedName; }
    set
    {
        if (_selectedName != value)
        {
            _selectedName = value;
            RaisePropertyChanged("SelectedName");
        }
    }
}

需要注意的是,RaisePropertyChanged 方法中硬编码了属性名称 "SelectedName"。现在,由于需求变更,一位开发者将一个属性的名称从 SelectedName 更改为 FirstName,同时,他忘记更改 RaisePropertyChanged 方法的参数。现在会发生什么?

这个疏忽不会导致任何编译或运行时错误,但我们的功能将无法正常工作。除非功能出现重大故障,否则很难检测到这类问题。那么,如何摆脱这类问题呢?

技巧来了

与其硬编码属性名称,我们是否可以使用反射 API 动态获取属性名称呢?当然可以。

Reflection.MethodBase.GetCurrentMethod().Name 

为了更好地实现它,让我们创建一个扩展方法来读取此属性名称,如下所示:

 public static string GetPropertyName(this System.Reflection.MethodBase methodBase)
{
    return methodBase.Name.Substring(4);
}

这里需要使用 Substring 方法来去除调用位置是 'get_' 或 'set_' 开头的部分。

因此,通过使用这个扩展方法,人们将能够引发属性更改事件,而无需担心将来属性名称可能会更改。

完成上述更改后,我们的属性将如下所示:

public string SelectedName 
{
    get { return _selectedName; }
    set
    {
        if (_selectedName != value)
        {
            _selectedName = value;
            //RaisePropertyChanged("SelectedName");
            RaisePropertyChanged(
              System.Reflection.MethodBase.GetCurrentMethod().GetPropertyName());
        }
    }
} 

我希望这个小技巧对您有所帮助。

相关主题

© . All rights reserved.