使用 RaisePropertyChanged 方法的最安全方式






4.72/5 (9投票s)
使用 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());
}
}
}
我希望这个小技巧对您有所帮助。