ObservableCollection属性类
我在MVVM
项目中重复这个属性太多次了。 创建generics类或工厂来替换这些代码行的正确方法是什么?
ObservableCollection _resultCollection; public ObservableCollection ResultCollection { get { if (_resultCollection == null) _resultCollection = new ObservableCollection(); return _resultCollection; } set { _resultCollection = value; } }
我知道这并不能完全回答你的问题,但是我个人更喜欢在Visual Studio中使用录制的宏来为我编写所有内容。
我更喜欢将它用于generics类,因为它将所有相关代码保存在一个地方,并且很容易理解发生了什么。 通常我将所有私有字段放在我的类的顶部,并将所有公共属性隐藏在我保持折叠的#region
标记中,因此我不需要滚动它们。
在VS中创建宏非常容易:只需转到“工具”>“宏”>“记录临时宏”,然后仅使用键盘执行所需的更改。 一旦宏正常工作,只需将其保存为永久宏。 如果你做得对,你可以用任何变量重新运行宏,它将以相同的方式构建它。
创建宏时要记住的一些有用的键盘快捷键是:
- 按Ctrl + C / Ctrl + V进行复制/粘贴
- 按Ctrl +向右 / Ctrl +向左移动单词
- Home / End移动到行的开头或结尾
- 在移动光标时移动以突出显示单词
您可能还需要对VB宏代码进行一些小修改,例如.Replace()
将小写字母转换为大写字母。
这是我用来构建MVVM的所有公共属性的示例宏。 它使用PRISM库,因此它使用语法RaisePropertyChanged(() => this.SomeProperty);
Sub PRISM_BuildPropertyChanged_CursorAtDefaultAfterCtrlRE() DTE.ActiveDocument.Selection.LineDown(False, 2) DTE.ActiveDocument.Selection.WordLeft(True) DTE.ActiveDocument.Selection.Copy() DTE.ActiveDocument.Selection.LineDown(False, 3) DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.CharLeft() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "RaisePropertyChanged(() => this." DTE.ActiveDocument.Selection.Paste() DTE.ActiveDocument.Selection.Text = ");" DTE.ActiveDocument.Selection.LineUp() DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText) DTE.ActiveDocument.Selection.CharRight(False, 4) DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.CharRight() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "if (value != " DTE.ActiveDocument.Selection.WordRight(True) DTE.ActiveDocument.Selection.Copy() DTE.ActiveDocument.Selection.CharLeft() DTE.ActiveDocument.Selection.Paste() DTE.ActiveDocument.Selection.DeleteLeft() DTE.ActiveDocument.Selection.Text = ")" DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "{" DTE.ActiveDocument.Selection.LineDown() DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "}" End Sub
有了它,我可以编写我的私人定义,例如
private ObservableCollection _someCollection;
按Ctrl + R , E以构建公共属性定义
private ObservableCollection _someCollection; public ObservableCollection SomeCollection { get { return _someCollection; } set { _someCollection = value; } }
然后运行我的宏来构建属性更改通知
public ObservableCollection SomeCollection { get { return _someCollection; } set { if (value != _someCollection) { _someCollection = value; RaisePropertyChanged(() => this.SomeCollection); } } }
(默认情况下, Ctrl + R , E将光标放在私有字段定义的末尾,这是运行此宏时光标所在的位置)
我还有另一个旧的宏添加代码来检查值是否为null,如果是这样,将其设置为对象的新实例,但是我从未使用太多,因为我更喜欢在构造函数中设置我的默认定义而不是在属性定义中。
如果你想要它,它看起来像这样(注意宏名称 – 你需要在运行这个宏之前突出显示公共属性名称):
Sub CreatePublicGet_NoNull_HightlightPropertyNameFirst() DTE.ActiveDocument.Selection.CharLeft(False, 2) DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, True) DTE.ActiveDocument.Selection.WordRight(True) DTE.ActiveDocument.Selection.Copy() DTE.ActiveDocument.Selection.LineDown(False, 2) DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText) DTE.ActiveDocument.Selection.CharRight(False, 4) DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.CharRight() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.CharLeft() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.LineUp(False, 2) DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Paste() DTE.ActiveDocument.Selection.Text = "();" DTE.ActiveDocument.Selection.LineDown() DTE.ActiveDocument.Selection.WordLeft(True) DTE.ActiveDocument.Selection.CharLeft() DTE.ActiveDocument.Selection.WordLeft(True) DTE.ActiveDocument.Selection.Copy() DTE.ActiveDocument.Selection.LineUp(False, 2) DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "if (" DTE.ActiveDocument.Selection.Paste() DTE.ActiveDocument.Selection.Text = " == null)" DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "{" DTE.ActiveDocument.Selection.LineDown() DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText) DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.NewLine() DTE.ActiveDocument.Selection.Text = "}" DTE.ActiveDocument.Selection.LineUp() DTE.ActiveDocument.Selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText) DTE.ActiveDocument.Selection.Paste() DTE.ActiveDocument.Selection.Text = " = new " DTE.ActiveDocument.Selection.Collapse() DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.LineDown(False, 4) DTE.ActiveDocument.Selection.EndOfLine() DTE.ActiveDocument.Selection.LineUp(True) DTE.ActiveDocument.Selection.Delete() End Sub
并且代码看起来像这样:
public ObservableCollection SomeCollection { get { if (_someCollection == null) { _someCollection = new ObservableCollection (); } return _someCollection; } }
没有某种forms的代码生成,AFAIK是不可能的。 查看T4模板,如此处所述 。
public abstract class XBase { ObservableCollection _resultCollection; public ObservableCollection ResultCollection { get { if (_resultCollection == null) _resultCollection = new ObservableCollection (); return _resultCollection; } set { _resultCollection = value; } } }
是的……能够绑定到一个字段会很棒,不会…… ;-)这让我想到了第一个解决方案 :
(1)创建一个允许绑定字段的转换器。
public class FieldBindingConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var par = parameter as string; var field = value.GetType().GetField(par); return field.GetValue(value); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
然后(2)直接从XAML绑定字段:
我有点不相信这是诚实的,因为它并没有真正清除…所以作为第二个解决方案 ,你可以直接从构造函数实例化属性:
public Foo() { ResultCollection = new ObservableCollection(); } [...] public ObservableCollection ResultCollection { get; private set; }
虽然这确实增加了几个字节的内存占用(它将惰性实例化的语义更改为直接实例化),但我不会太在意这一点。
- 无法加入备注,OLE或超链接对象
- 如何绑定外键? 如何在控制器类中使用外键创建Model对象?
- 如何阻止UpdatePanel导致整页回发?
- 使用.net代码更新cshtml文件时,为什么不需要编译?
- System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)拒绝访问
- 从模型validation中排除类型(示例DbGeography)以避免InsufficientExecutionStackException
- 如何在没有第三方短信门的情况下使用asp.net c#从网站发送短信
- 动态创建按钮单击事件未触发
- 使用State Server在不同的.NET版本之间共享会话状态