考虑具有许多输入字段的WPF对话,这些输入字段绑定到视图模型中的属性。 E.g。
...
<TextBox Text="{Binding FirstName}">
...
public string FirstName {
get { return mFirstName; }
set {
if (mFirstName == value) return;
mFirstName = value;
OnPropertyChanged("FirstName");
}
}
由于有这样的几十个字段,我想尽量减少要编写的样板C#代码。我有什么选择?
答案 0 :(得分:0)
我可以让您的代码更容易转换为代码段。
if (mFirstName != value) {
mFirstName = value;
OnPropertyChanged("FirstName");
}
如果只是写它的时间很痛苦,并且你经常使用WPF,那么片段也可能有用。我知道在Sublime Text,VS Code和Visual Studio中,Snippets非常有用。否则,我认为它只是你能得到的骨头,除非有我没看到的东西
答案 1 :(得分:0)
首先,我猜您已经使用了Microsoft.Prism,您可以在幕后删除字符串并从CallerMemberNameAttribute中获利,这样您的代码就会如下所示:
public string FirstName {
get { return mFirstName; }
set {
if (mFirstName == value) return;
mFirstName = value;
OnPropertyChanged();
}
}
这也等同于c#6.0 nameof(FirstName)
运算符。
其次,你可以深入研究AOP并将样板抽象为属性。其中一个处理此问题的AOP框架是PostSharp并使用它,您的代码可能如下所示:
[NotifyPropertyChanged]
public class Customer
{
public string FirstName { get; set; }
虽然它不是免费的,AOP has it's drawbacks(感谢Evk)。
答案 2 :(得分:0)
我使用Fody在编译时注入属性更改的代码。你的类获得[ImplementPropertyChanged]属性,然后你的{get;组; }属性成为已编译代码中的通知属性。
答案 3 :(得分:0)
如果您可以选择使用基类,请考虑从以下内容继承视图模型对象:
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
// ReSharper disable once ExplicitCallerInfoArgument
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void OnPropertiesChanged(params string[] propertyNames)
{
foreach (string propertyName in propertyNames)
{
// ReSharper disable once ExplicitCallerInfoArgument
OnPropertyChanged(propertyName);
}
}
}
示例用法,显示样板大大减少:
public sealed class ViewModel : BindableBase
{
private string name;
public string Name
{
get { return name; }
private set { SetProperty(ref name, value); }
}
}
(如果您不能使用基类(例如,您已经拥有一个或正在使用框架元素的属性),您仍然可以选择在相关类中直接添加类似的支持。)