Improved way to boost properties changed MVVMLight

Created a project using MVVM Light. There are a lot of properties for ViewModels that look like this:

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();
              }
         }
    }
}

      

Sometimes the property is not in the model and is instead supported by a local private field. This approach works great, but there is a ton of boilerplate code. How to reduce code duplication?

Are there any better solutions than the ones I suggested, or something built into MVVM Light that I missed?

+3


source to share


3 answers


My version of the MVVM Light template property looks like this:

private string _Prop = "";

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

      



which can pretty much be the most subtle one can be done with the function Set

provided by the base class ObservableObject

(you can also use ViewModelBase

).

+6


source


In my application, the model is a pure data store and is used primarily for reading and writing to SQL Server. The model contains backing fields for all properties in the ViewModel that are persisted to the server. Therefore it makes sense to only have fields in the model and access them through the 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 will be the only thing that needs to be updated when additional classes are added to the class. Since this is a field, you can pass it by reference to a common function and use it in all properties.



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()
    }
}

      

This accepts all types, overrides EqualTo as required for equality to work properly. It can also perform additional calculations as needed.

It would be nice if this could be removed from the ViewModel like the MVVM Light Set method, but I couldn't figure it out.

0


source


MVVM indicator provides set methods as shown below where you used it directly.

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

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

      

0


source







All Articles