看完这篇文章 ,一个在我下面的代码PersonViewModel
类:
public Jurisdiction CountryResidence
{
get
{
return Model.CountryResidence;
}
set
{
if (Model.CountryResidence == value)
return;
else
{
Model.CountryResidence = value;
base.OnPropertyChanged("CountryResidence");
}
}
}
public Jurisdiction CountryBirth
{
get
{
return Model.CountryBirth;
}
set
{
if (Model.CountryBirth == value)
return;
else
{
Model.CountryBirth = value;
base.OnPropertyChanged("CountryBirth");
}
}
}
我也有CountryDomiciled
, CountryPassport
和LegalJurisdiction
,都具有相同的格式。 同样,我有很多的String
特性,所有这些都分享他们的格式。
这导致大量的单调枯燥的代码! 不过,我不知道如何使这个更简洁。
有没有更好的方法来生成这些性质使他们强类型?
Answer 1:
UPDATE:NotifyPropertyWeaver已被弃用,并继续为生命PropertyChanged.Fody 。 这是解决这个问题的绝对超爽的方式。 这是一个编译时唯一的解决办法。
这里的东西,将节省您的代码和麻烦: NotifyPropertyWeaver
使用上面,你可以在没有任何实现你的属性INotifyPropertyChanged
相关代码和生成步骤将处理接线,为您服务。
这是一个简单的项目包括(也可以通过提供的NuGet),将自动注入OnPropertyChanged
的回调实现任何类的属性INotifyPropertyChanged
。 它是在编译时(因此没有运行时命中)和你的代码可以只具有自动实现的属性(除非你的情况,你使用一个单独的支持对象在哪里)。
它甚至还包括了价值平等的检查,所以它涵盖了完整的逻辑。 我还没有手动实现性能测试,但值得一试。
编辑:我现在已经测试了它,它工作得很好:“只是工作”手动实现的属性会
Answer 2:
我使用的代码段为Visual Studio,这与后备存储和事件提高了我产生财产。 只需创建名称为xml文件propchanged
(或其他名称,如果你愿意的话)和以下内容:
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<CodeSnippet Format="1.0.0">
<Header>
<Title>propchanged</Title>
<Shortcut>propchanged</Shortcut>
<Description>Code snippet for property (with call to OnPropertyChanged) and backing field</Description>
<Author>lazyberezovsky</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>type</ID>
<ToolTip>Property type</ToolTip>
<Default>string</Default>
</Literal>
<Literal>
<ID>property</ID>
<ToolTip>Property name</ToolTip>
<Default>MyProperty</Default>
</Literal>
<Literal>
<ID>field</ID>
<ToolTip>The variable backing this property</ToolTip>
<Default>myVar</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[private $type$ $field$;
public $type$ $property$
{
get { return $field$;}
set
{
if ($field$ == value)
return;
$field$ = value;
OnPropertyChanged("$property$");
}
}
$end$]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>
并把它放到文件夹C:\Users\YourName\Documents\Visual Studio 2010\Code Snippets\Visual C#\My Code Snippets\
。
接下来,我继承了一些基本的视图模型,它实现了我的ViewModels INotifyPropertyChanged
inteface和提供保护的方法OnPropertyChanged
产生`的PropertyChanged”事件。
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
}
}
现在当你输入propchanged
在Visual Studio中,它会问你的属性类型和名称,并为你生成代码。
public class PersonViewModel : ViewModel
{
// type here 'propchanged' (or other shortcut assigned for snippet)
}
更新:
另一种选择是由像AOP框架生成代码PostSharp 。 在这种情况下,代码生成和编译过程中添加(因此你的类将保持干净)。 这里是例如实现INotifyProperty改变经由PostSharp属性的:
[Notify]
public class PersonViewModel
{
public Jurisdiction CountryResidence { get; set; }
public Jurisdiction CountryBirth { get; set; }
}
Answer 3:
不是真的你正在寻找的东西,但作为一个预留您可以通过扭转你的逻辑测试节省每财产两行:
public Jurisdiction CountryResidence
{
get
{
return Model.CountryResidence;
}
set
{
if (Model.CountryResidence != value)
{
Model.CountryResidence = value;
base.OnPropertyChanged("CountryResidence");
}
}
}
Answer 4:
我不知道任何内置的方式,但你可以录制宏,将生成的代码为您服务。 我觉得这样做是刚开始录制宏,然后再创建任何你想要使用键盘只(你可以找到得心应手的键盘快捷键列表,最简单的方法在这里 )
例如,我有一个生成的属性的公版,所以我必须键入是private string _someValue;
和打我的宏,它会产生与属性更改通知沿着公共财产。
这就是说,要记住,这是在MVVM完全有效的整个模型暴露给视图为了简单和方便起见。 因此,而不是分别暴露出每一型号的特性,您只需为您的模型对象的一个属性。
public Model SomeModel
{
get
{
return Model;
}
set
{
if (Model == value)
return;
else
{
Model= value;
base.OnPropertyChanged("SomeModel");
}
}
}
并绑定到这样的模型的属性:
<TextBox Text="{Binding SomeModel.SomeProperty}" />
Answer 5:
请尝试XAML PowerToys的快速生成的ViewModels;
Answer 6:
为了得到一个“强类型的”参考属性名称(这是为了使重构),您可以使用表达式。 将下面的方法,也许在你的ViewModels基类:
protected void RaisePropertyChanged<T>(Expression<Func<T>> property)
{
var handler = PropertyChanged;
if (handler == null) return;
var propertyName = NotifyPropertyChangedHelper.GetPropertyNameFromExpression(property);
handler(sender, new PropertyChangedEventArgs(propertyName));
}
在你的ViewModels,然后您就能够做到以下几点:
public Jurisdiction CountryResidence
{
get { return Model.CountryResidence; }
set
{
if (Model.CountryResidence == value)
return;
Model.CountryResidence = value;
OnPropertyChanged(() => CountryResidence);
}
}
现在,由于基准是针对实际的属性重构属性名被自动拾取。
这解决了硬编码的属性名称的痛点,虽然它仍然需要4-5行的样板代码。 像面向方面的办法notifypropertyweaver和PostSharp真正消除在所有的ViewModels手工编码。
Answer 7:
你有没有尝试过使用Visual Studio代码片段,如prop
或propfull
? 只需键入它,然后按Tab键两次。 问题是propfull
片段不会引发PropertyChanged事件。
但实际上应该有这样的任务第三方片段。 这里是我的发现: 财产片段与INPC
Answer 8:
我写了一个小T4模板用于这一目的。
http://software.the-architect.info/2014/08/12/a-quick-way-to-generate-view-model-properties-in-wpf
文章来源: Quickly generating ViewModel properties in wpf?