Reputation: 325
I'm working on an MVVM app and have a view that is used to modify a number of network parameters (IP, SubnetMask, etc).
The view contains a number of text boxes bound to properties in a NetworkConfigViewModel
:
<TextBox>
<TextBox.Text>
<Binding Path="IP" UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
... etc
The view also contains a button called Save Configuration
. The button is bound to a RelayCommand in the ViewModel that takes care of saving the configuration to the remote device on request.
I would like to modify the textbox bindings to use UpdateSourceTrigger="Explicit"
so that the ViewModel only gets updated when the user explicitly clicks 'Save Configuration', rather than updating as values are modified.
I understand that I'll need to call BindingExpression.UpdateSource()
for each text box. How can I do this in an MVVM-friendly way? Adding a new RelayCommand to the ViewModel that is aware of the UI elements doesn't seem correct.
Upvotes: 3
Views: 5808
Reputation: 91
So referring back to your example:
If the ViewModel has private backing fields for its properties instead of exposing the properties of the Model like so-
private string _myProperty;
public string MyProperty
{
get { return _myProperty; }
set
{
if (_myProperty != value)
{
_myProperty = value;
OnPropertyChanged("MyProperty");
}
}
}
What will the controls in the View bind to? If you bind to a property that only exposes a private backing field, how would any data ever get into the view? For instance, a TextBox couldn't bind to the ViewModel property, MyProperty, anymore because it isn't exposing Model.MyProperty. It's simply exposing _myProperty. If you do bind to Model.MyProperty like so in the View:
<TextBox Text="{Binding Model.MyProperty, UpdateSourceTrigger=Explicit}" />
<Button Command="{Binding SaveCommand}" />
...you will get data into the TextBox. Now, how do we update the model with the updated value from the TextBox when the Save button is pressed?
private void SaveExecute()
{
// How do we update the Model.MyProperty value?
}
Upvotes: 1
Reputation: 96920
Don't implement this functionality in the bindings to your view model. Implement it in your view model. The properties of the view model should always reflect what's in the view - it's called a view model because it's a model of the view, after all.
I'm guessing that you're asking this question because you've implemented the view model with properties like this:
public string MyProperty
{
get { return _Model.MyProperty; }
set
{
_Model.MyProperty=value;
OnPropertyChanged("MyProperty");
}
}
Don't do this. Store the property values in private backing fields, and update the model properties in the "Save Configuration" method.
Upvotes: 1
Reputation: 15823
Exactly, letting ViewModel know about View too much isn't good. I'd better update a copy of settings, and let binding do all works for me. Once user clicks 'Save Configuration' button I would propagate changes further to repository, model or whatever...
Upvotes: 1