Reputation: 35921
I have a set of controls for which a certain value is always valid, but others are valid or invalid depending on some logic. That logic is designed in such a way that it can never invalidate itself: upon calling logic.SetState( ... ) with an invalid parameter, it will return false and generate an error message but it's internals won't be affected. In other words, it's state is unchanged. And I want this reflected on the screen but cant figure out what's wrong with the code.
Here's an example of what I'd like to achieve with a ComboBox, but the same applies to a set of checkboxes or even textboxes, ie any controls taking user input. xaml:
<ComboBox ItemsSource="{Binding Path=States}"
SelectedItem="{Binding Path=State}"/>
code:
public string State
{
get { return state; }
set
{
if( value != "invalid" )
state = value;
else
ShowError(); //tell user this selection was not ok
RaisePropertyChanged( "State" ); //the usual INotifyPropertyChanged method
}
}
public string[] States
{
get { return new string[] { "none", "valid", "invalid" }; }
}
private string state;
The initial value for State is set to "none". When the user selects "valid", the state member is set to the new value and the property change is published.
When the user selects "invalid" though, the state member is not changed however the combobox shows "invalid". Hence there is a mismatch between what's on the screen ("invalid") and the effective value used in the application ("valid") and I'd rather avoid that.
I do not understand why the ComboBox still shows "invalid": I was under the impression that by calling RaisePropertyChanged( "State" ) the ComboBox would be triggerred to get the value of State and display that, hereby setting the ComboBox to "valid" again?
Would there be a way to do this? Note that the code is in a ViewModel-style class which doesn't know about ComboBox.
Is it better practice to not do it this way, but instead rely on the 'normal' validation methods? For example I could implement IDataErrorInfo and show a message telling the user that the value currently being displayed is not valid, showing a red box around it etc. At the same time I would also have to disable pretty much all other controls until this one control is valid again (since the other parts of the app will use another value then displayed on the screen, results might be quite unexpected).
Upvotes: 0
Views: 359
Reputation: 2944
The raising of the PropertyChanged event is ignored when the UI calls the setter. There is a known work around to this where if you have a converter on your binding it handles the PropertyChange correctly. The solution is to create a dummy converter that just returns the value passed in. See this article for how you can do this:
http://www.lhotka.net/weblog/DataBindingIssueInWPFWithSolution.aspx
To answer question 3 in your list, yes that is the approach I usually take. Never change the users value back to something for them but instead show an error and let them change it back.
Upvotes: 1