提高财产的更好方法改变了MVVMLight

时间:2017-04-19 02:38:57

标签: c# wpf mvvm

使用MVVM Light创建了一个项目。 ViewModels通常有很多看起来像这样的属性

class TestModel
{
    public string DisplayValue { get; set; }
}

class TestViewModel : ViewModelBase
{
    public string DisplayValue
    {
         private TestModel model = new TestModel();

         get
         {
              return model.DisplayValue;
         }
         set
         {
              if (model.DisplayValue != value)
              {
                   model.DisplayValue = value;
                   RaisePropertyChanged();
              }
         }
    }
}

有时,该属性不在模型中,而是由本地私有字段支持。这种方法工作正常,但有大量的样板代码。如何减少代码重复?

有没有比我提出的解决方案更好的解决方案,或者我错过了MVVM Light内置的东西?

4 个答案:

答案 0 :(得分:9)

我的版本样板MVVM Light属性如下所示:

private string _Prop = "";

public string Prop
{
  get { return _Prop; }
  set { Set(ref _Prop, value); }
}
通过使用基础Set类提供的ObservableObject函数(也可以使用ViewModelBase),

几乎是最薄的一个。

答案 1 :(得分:0)

在我的应用程序中,模型是纯数据存储,主要用于读写SQL Server。该模型包含ViewModel中保存到服务器的所有属性的支持字段。因此,仅在模型中包含字段并且仅通过ViewModel

访问它们是有意义的
class TestModel
{
    public string displayValue;
    public override bool Equals(object obj)
    {
        if (obj.GetType() != typeof(TestModel))
                return false;

        var testObj = obj as TestModel;
        return testObj?.GetHashCode() == testValue?.GetHashCode();
    }

    public override int GetHashCode()
    {
        return displayValue.GetHashCode();
    }
}

当将其他字段添加到类中时,GetHashCode将是唯一需要更新的内容。由于它是一个字段,因此可以通过引用将其传递给一个公共函数并在所有属性中使用它。

class TestViewModel:ViewModelBase
{
    private TestModel model = new TestModel();
    public string DisplayValue
    {
        get { return model.displayValue; }
        set { SetIfChanged(ref model.displayValue, value, RunCalculations); }
    }


    public bool SetIfChanged<T>(ref T field, T value, Action MoreWork, [CallerMemberName] string propertyName = null)
    {
        if (!Equals(field, value))
        {
            field = value;
            MoreWork.Invoke();
            RaisePropertyChanged(propertyName);
            return true;
        }

        return false;
    }

    private void RunCalculations()
    {
       // Do some work before RaisePropertyChanged()
    }
}

这接受所有类型,根据需要重写EqualTo以使其正常工作。它还可以根据需要运行其他计算。

如果可以像使用MVVM Light Set方法一样从ViewModel中删除它,那将是很好的,但我还没有能够解决这个问题。

答案 2 :(得分:0)

MVVM指示灯提供了设置方法,如下例所示,直接使用它。

class TestViewModel : ViewModelBase
{
   private TestModel model = new TestModel();

   public string DisplayValue
  {
     get{return model.DisplayValue;}
     set{ Set(()=>DisplayValue, ref model.DisplayValue, value); }
  }   
}

答案 3 :(得分:0)

C#7版本的dotNET发布:

private string _Prop = string.empty;

public string Prop
{
  get => return _Prop;
  set => Set(ref _Prop, value);
}