我正在尝试重构MVVM架构中的一些代码。
模型具有可直接更改的公共值。
UI监听这些值的变化。
下面是事件信令码:
public string LoadFilename { get { return _loadFilename; } set { _loadFilename = value; OnPropertyChanged(); } }
public string SaveFilename { get { return _saveFilename; } set { _saveFilename = value; OnPropertyChanged(); } }
public string OneSafFilename { get { return _oneSafFilename; } set { _oneSafFilename = value; OnPropertyChanged(); } }
public bool IsSaveEnabled { get { return _isSaveEnabled; } set { _isSaveEnabled = value; OnPropertyChanged(); } }
public bool IsLoadEnabled { get { return _isLoadEnabled; } set { _isLoadEnabled = value; OnPropertyChanged(); } }
public bool IsLoadCheckpointEnabled { get { return _isLoadCheckpointEnabled; } set { _isLoadCheckpointEnabled = value; OnPropertyChanged(); } }
public bool IsCheckpointEnabled { get { return _isCheckpointEnabled; } set { _isCheckpointEnabled = value; OnPropertyChanged(); } }
public bool IsScenariosEnabled { get { return _isScenariosEnabled; } set { _isScenariosEnabled = value; OnPropertyChanged(); } }
OnPropertyChanged
函数:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
对于MVVM中应该很自然的东西来说,这似乎是很多样板文件。
我想让它更简洁,但我不知道从哪里开始。
如果视图监听上述属性,getter和setter应该是什么样子?
实现INPC始终是WPF/XAML的丑陋部分。有了一个好的基类,它可以减少到{ get { return _loadFilename; } set { Set(ref _loadFilename, value); } }
,但这是最紧凑的。Resharper对此提供了支持(重构)。
顺便说一句,你的代码也缺少优化保护if(value != _loadFilename)
。所以BindableBase
基类绝对是一个好主意。
您可能想看看Fody的PropertyChanged之类的东西,它在构建时重写IL以注入更改通知代码。
private type m_name;
public type name
{
get { return m_name; }
set
{
m_name = value;
if (PropertyChanged != null)
{ PropertyChanged(this, new PropertyChangedEventArgs("name")); }
}
}
我将上面的代码用于需要侦听器的属性更改。Type是属性的类型,name是属性的名称(在代码中看到的任何地方修改Type和name)
关于MVVM的一个很好的教程,解释了更多关于属性更改和代码片段,看看Jerry Nixon在youtube上:https://www.youtube.com/watch?v=cB7KdYPQw1k它有点过时了,但仍然很有帮助!