C# 在MVVM中定义从模型到视图的属性更改的理想方法是什么?
我正在尝试重构MVVM体系结构中的一些代码。C# 在MVVM中定义从模型到视图的属性更改的理想方法是什么?,c#,wpf,mvvm,inotifypropertychanged,field-accessors,C#,Wpf,Mvvm,Inotifypropertychanged,Field Accessors,我正在尝试重构MVVM体系结构中的一些代码。 模型具有可直接更改的公共值 UI侦听这些值中的更改 以下是事件信号代码: public string LoadFilename { get { return _loadFilename; } set { _loadFilename = value; OnPropertyChanged(); } } public string SaveFilename { get { return _saveFilename; } set { _s
模型具有可直接更改的公共值 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{u loadFilename;}set{set(ref{u loadFilename,value);}}
,但这是最简洁的。Resharper支持(重构到)这一点
顺便说一句,您的代码也缺少优化保护
if(value!=\u loadFilename)
。所以一个BindableBase
基类绝对是个好主意 实现INPC始终是WPF/XAML的丑陋部分。有了一个好的基类,它可以简化为{get{return{u loadFilename;}set{set(ref{u loadFilename,value);}}
,但这是最简洁的。Resharper支持(重构到)这一点
顺便说一句,您的代码也缺少优化保护
if(value!=\u loadFilename)
。所以一个BindableBase
基类绝对是个好主意 您可能希望查看类似的内容,它在生成时重写IL以注入更改通知代码。您可能希望查看类似的内容,它在生成时重写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:
这有点过时,但仍然非常有用
对于需要侦听器的属性更改,我使用上述代码。type是属性的类型,name是属性的名称(在代码中的任意位置更改“type”和“name”)
有关MVVM的精彩教程,详细介绍了属性更改和代码片段,请查看Jerry Nixon youtube:
这有点过时,但仍然非常有用 我完全同意@HenkHolterman的观点,您可以将INPC实现移到基类中。这里有一个我之前使用过的小例子,别忘了减少derp(
PropertyChanged?.Invoke(…)
)的语言功能其次,有很多方法可以改善这种情况,从样板的T4模板生成,使用类型描述符,在IDynamicMetaObjectProviders中包装POCO,等等。我完全同意@HenkHolterman的观点,您可以将INPC实现移到基类中。这里有一个我之前使用过的小例子,不要忘记减少derp的语言特性(PropertyChanged?.Invoke(…)
)其次,有很多方法可以改善这种情况,从样板的T4模板生成,使用类型描述符,在IDynamicMetaObjectProviders中包装POCO,等等。使用“name”在引号中是对原始代码的一大倒退。而且这个也更长。OnPropertyChange()方法属于推荐的模式。在引号中使用“name”比原始代码倒退了一大步。而且这个也更长。OnPropertyChange()方法属于推荐的模式。