IntroductionThe common practise in Silverlight, when using MVVM, is to validate user data via the bound property setter in the view model. Although this works well for most circumstances, it doesn't work when the user doesn't make a change to data and instead clicks on a button. For example, imagine a form that prompts the user for his/her name, which must not be blank, and then click a Next button. If the user just clicks the Next button without typing anything in the Name field, the validation via the bound property setter is never executed. One way to address this is to repeat the validation in the view model when the user clicks Next. The issue with this is how to display the error message to the user in a way that is consistent (e.g. shown in a ValidationSummary and red tool tip, with any other error).
SolutionThe solution I'm proposing is based on a solution by Josh Twist (see his article here http://www.thejoyofcode.com/Silverlight_Validation_and_MVVM_Part_II.aspx). The premise of his solution is to allow the view model to instruct the view to refresh it's bindings. This tells the view to set any bound properties, and this allows your validation code to run, even if the user has not entered data. I've taken Josh's code and simplified it, by decoupling it from the validation framework and removing the need to add attached properties to each element participating in the validation scope.
Using the codeThe solution is based around an attached behaviour, which I've called RefreshBindingScope.public class RefreshBindingScope
{
private static readonly Dictionary<type, > BoundProperties =
new Dictionary<type, >
{
{ typeof(TextBox), TextBox.TextProperty },
{ typeof(ItemsControl), ItemsControl.ItemsSourceProperty },
{ typeof(ComboBox), ItemsControl.ItemsSourceProperty },
{ typeof(DataGrid), DataGrid.ItemsSourceProperty},
{ typeof(AutoCompleteBox), AutoCompleteBox.TextProperty},
{ typeof(DatePicker), DatePicker.SelectedDateProperty},
{ typeof(ListBox), ItemsControl.ItemsSourceProperty },
{ typeof(PasswordBox), PasswordBox.PasswordProperty },
}; public FrameworkElement ScopeElement { get; private set; }Read more: Codeproject
QR:
SolutionThe solution I'm proposing is based on a solution by Josh Twist (see his article here http://www.thejoyofcode.com/Silverlight_Validation_and_MVVM_Part_II.aspx). The premise of his solution is to allow the view model to instruct the view to refresh it's bindings. This tells the view to set any bound properties, and this allows your validation code to run, even if the user has not entered data. I've taken Josh's code and simplified it, by decoupling it from the validation framework and removing the need to add attached properties to each element participating in the validation scope.
Using the codeThe solution is based around an attached behaviour, which I've called RefreshBindingScope.public class RefreshBindingScope
{
private static readonly Dictionary<type, > BoundProperties =
new Dictionary<type, >
{
{ typeof(TextBox), TextBox.TextProperty },
{ typeof(ItemsControl), ItemsControl.ItemsSourceProperty },
{ typeof(ComboBox), ItemsControl.ItemsSourceProperty },
{ typeof(DataGrid), DataGrid.ItemsSourceProperty},
{ typeof(AutoCompleteBox), AutoCompleteBox.TextProperty},
{ typeof(DatePicker), DatePicker.SelectedDateProperty},
{ typeof(ListBox), ItemsControl.ItemsSourceProperty },
{ typeof(PasswordBox), PasswordBox.PasswordProperty },
}; public FrameworkElement ScopeElement { get; private set; }Read more: Codeproject
QR:
0 comments:
Post a Comment