C# ObservableCollection属性类

C# ObservableCollection属性类,c#,asp.net,generics,mvvm,C#,Asp.net,Generics,Mvvm,我在我的MVVM项目中重复此属性的次数太多,无法计数。创建泛型类或工厂以替换这些代码行的正确方法是什么 ObservableCollection<Result> _resultCollection; public ObservableCollection<Result> ResultCollection { get { if (_resultCollection == null)

我在我的
MVVM
项目中重复此属性的次数太多,无法计数。创建泛型类或工厂以替换这些代码行的正确方法是什么

    ObservableCollection<Result> _resultCollection;
    public ObservableCollection<Result> ResultCollection
    {
        get
        {
            if (_resultCollection == null)
                _resultCollection = new ObservableCollection<Result>();
            return _resultCollection;
        }
        set
        {
            _resultCollection = value;
        }
    }
observedcollection\u resultCollection;
公共可见收集结果收集
{
得到
{
if(_resultCollection==null)
_resultCollection=新的ObservableCollection();
返回_resultCollection;
}
设置
{
_结果收集=值;
}
}

如果没有某种形式的代码生成,这是不可能的。查看T4模板,如回答所示
.

公共抽象类XBase
{
可观察采集(u resultCollection);;
公共可见收集结果收集
{
得到
{
if(_resultCollection==null)
_resultCollection=新的ObservableCollection();
返回_resultCollection;
}
设置
{
_结果收集=值;
}
}
}

我知道这并不能完全回答您的问题,但就我个人而言,我更喜欢在Visual Studio中使用录制的宏为我编写所有这些内容

与泛型类相比,我更喜欢使用它,因为它将所有相关代码保存在一个地方,并且很容易理解正在发生的事情。通常,我会将所有私有字段放在类的顶部,并将所有公共属性隐藏在我一直折叠的
#region
标记中,这样我就不需要滚动它们了

在VS中创建宏相当容易:只需进入工具>宏>录制临时宏,然后仅使用键盘执行所需的更改。一旦宏正常工作,只需将其保存为永久宏即可。如果操作正确,可以使用任何变量重新运行宏,它将以相同的方式构建宏

创建宏时要记住的一些有用的键盘快捷键包括:

  • Ctrl+C/Ctrl+V以复制/粘贴
  • Ctrl+Right/Ctrl+Left在单词上移动
  • 起始/结束移动到行的开始或结束
  • 移动光标时高亮显示单词的Shift键
您可能还需要对VB宏代码进行一些小的修改,例如
.Replace()
将小写字母转换为大写字母

下面是一个用于构建MVVM所有公共属性的宏示例。它使用PRISM库,因此它使用语法
RaisePropertyChanged(()=>this.SomeProperty)

有了它,我可以写我的私人定义,比如

private ObservableCollection<SomeObject> _someCollection;
并产生如下代码:

public ObservableCollection<SomeObject> SomeCollection
{
    get 
    {
        if (_someCollection == null)
        {
            _someCollection = new ObservableCollection<SomeObject>();
        }
        return _someCollection; 
    }
}
public observeCollection SomeCollection
{
得到
{
if(_someCollection==null)
{
_someCollection=新的ObservableCollection();
}
返回(someCollection);;
}
}

是的。。。能够绑定到一个领域将是伟大的,不是吗…;-)这就引出了第一个解决方案:

(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绑定字段:

    <ItemsControl ItemsSource="{Binding ., Converter={StaticResource Field}, ConverterParameter=Coll2}" Grid.Row="1">

老实说,我有点不喜欢这个,因为它并没有真正把事情弄清楚。。。因此,作为第二个解决方案,您可以直接从构造函数实例化属性:

public Foo() 
{
    ResultCollection = new ObservableCollection<Result>();
}

[...]

public ObservableCollection<Result> ResultCollection { get; private set; }
publicfoo()
{
ResultCollection=新的ObservableCollection();
}
[...]
public observeCollection ResultCollection{get;private set;}

虽然这确实会增加您的内存占用数字节(它将惰性实例化的语义更改为直接实例化),但我不会太在意这一点。

是否可以将其放在一个非常令人印象深刻的基类中。@Justin谢谢!我已经够懒的了,我会加倍努力,想办法在将来变得懒惰;)
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<SomeObject> SomeCollection
{
    get 
    {
        if (_someCollection == null)
        {
            _someCollection = new ObservableCollection<SomeObject>();
        }
        return _someCollection; 
    }
}
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();
    }
}
    <ItemsControl ItemsSource="{Binding ., Converter={StaticResource Field}, ConverterParameter=Coll2}" Grid.Row="1">
public Foo() 
{
    ResultCollection = new ObservableCollection<Result>();
}

[...]

public ObservableCollection<Result> ResultCollection { get; private set; }