0
votes

I have a view which binds to a ViewModel

DataContext="{Binding MyViewModel, Source={StaticResource Locator}}">

the textboxes, ... are binding to the propertys IN the ViewModel:

<TextBox Text="{Binding MyValue, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayValue}"/>

Property in ViewModel:

public MyViewModel()
{
    DisplayValue = "0€";
    MyValue = "0";
}

private string _myvalue;
public string MyValue
{
    get
    {
        return _myvalue;
    }
    set
    {
        _myvalue = value;
        ChangeValue();
        RaisePropertyChanged(() => MyValue);
    }
}

private string _displayvalue;
public string DisplayValue
{
    get
    {
        return _displayvalue;
    }
    set
    {
        _displayvalue = value;
        RaisePropertyChanged(() => DisplayValue);
    }
}

private void ChangeValue()
{
//do something here and change the values of the property, e.g.:
DisplayValue = MyValue + "€";
}

This is just a snipped. I normally have ~50 properties IN THE VIEWMODEL and all the methods are also in the ViewModel (means RelayCommands AND methods, which will be called in the setter of ~50% of the properties). As you can see, I'm not using any Model(s). Is this a normal way of using MVVM or should I create a new class and put all the properties/methods in the new class (Model)?... But how am I supposed to bind the elements in the view with the Properties in the Model, when the views DataContext is binded to the ViewModel?

Edit: To make it clear. I have a TextBox and the TextBox is binded to a property in the ViewModel. Is this the correct way of using MVVM? Should I use a Model-Class only when I have a List (e.g. ComboBox) or also when I have several TextBox (which would be in my eyes kinda stupid and unnecessary)?

2
Ok this might be a dumb comment, but have you tested this code ? From what I can read, when you set MyValue, you raise the PropertyChanged event, then call the ChangeValue() method, which will set the MyValue property, which will raise PropertyChanged event, which will call ChangeValue() method, which will set the MyValue property ... and so on. Unless the MyValue += "€" does not uses the Setter, but I seriously doubt that. Seems to be like a good old infinite loop / memory leack. But again, I didn't tested it myself so I could be wrong ;) - Miiite
yes, you are right... stupid example, gonna change (edit) it - Rudi

2 Answers

1
votes

I hope I understand what you are trying to do. My solution comprises of the DependencyProperty that I use in the MVVM pattern, not the INotifyPropertyChanged.

Lets say, you have a model, that contains a property:

public class SymbolStatsModel
{
    public string Symbol
    {
        get
        {
            return this._symbol;
        }
        set
        {
            this._symbol = value;
        }
    }
}

Then the corresponding ViewModel is going to be like this. Declare a property and a dependency property:

public string Symbol
{
    get
    {
        return (string)GetValue(SymbolProperty);
    }
    set
    {
        SetValue(SymbolProperty, value);
    }
}

public static readonly DependencyProperty SymbolProperty =
    DependencyProperty.Register
    (
        "Symbol",
        typeof(string),
        typeof(SymbolStatsViewModel),
        new FrameworkPropertyMetadata
        (
            string.Empty
        )
    );

And also create a property of the Model class(SymStatsModel) in the ViewModel:

public SymbolStatsModel SymbolStatsModel
{
    get
    {
        return new SymbolStatsModel(Symbol);
    }
    set
    { 
        this.Symbol = value.Symbol;
    }
}

In that way, the values that you assign to the ViewModel Symbol Property are going to be assigned to the Model Property. Also, you can directly access the Model's properties from the View by accessing the property of the Model present in the ViewModel.

This may be a little hard to grasp, but this sure is the way to make the view communicate with the Model. On another thought, you can specify the property of the Model just like I have mentioned in my solution, while using the INotifyPropertyChanged. A little immature I guess, but you gave give it a thought.

0
votes

"Divide and Conquer" should help you in maintainability

  • Try and find boundaries in your UI, logical groups, repeating parts.
  • Factor them out
  • You can always reset the DataContext, or use a more complex Binding Path like MyVm.SubVm.Property