Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data Validation in Silverlight 4

I have control in SL4. I want data validation on button click. Big problem is normally SL4 give validation using binding property.

like example given shown in this example

http://weblogs.asp.net/dwahlin/archive/2010/08/15/validating-data-in-silverlight-4-applications-idataerrorinfo.aspx

<TextBox Text="{Binding Name,Mode=TwoWay,ValidatesOnDataErrors=true}" 
    Height="23" 
    Width="120"
    HorizontalAlignment="Left" 
    VerticalAlignment="Top"    />

BUT I WANT TO SHOW ERROR MESSAGE LIKE THIS ....

enter image description here

using my own code like on button click i check (textbox1.text == null ) then set this style of error to textbox1

like image 914
SOF User Avatar asked Mar 12 '11 13:03

SOF User


1 Answers

One way of deferring validation is to set the property UpdateSourceTrigger=Explicit in the bindings. If you do this, the bindings won't update the source objects, and hence won't cause validation errors, until you explicitly tell the bindings to do so. When your button is clicked, you force an update on the bindings, using a line such as the following for each control:

someTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();

You then have your property setters throwing exceptions for invalid data.

This approach can be a bit of a pain if there are quite a lot of controls to force binding updates on.

Also, forcing an update on the bindings has to be done in the code-behind of a control. If you're using a Command with the button as well then you might run in to an issue. Buttons can have both a Command and a Click event handler, and both will execute when the button is clicked on, but I don't know the order in which this happens or even if an order can be guaranteed. A quick experiment suggested that the event handler was executed before the command, but I don't know whether this is undefined behaviour. There is therefore the chance that the command will be fired before the bindings have been updated.


An approach to programmaticaly creating validation tooltips is to bind another property of the textbox and then deliberately cause an error with this binding.

'sapient' posted a complete solution, including code on the Silverlight forums (search for the post dated 07-08-2009 4:56 PM). In short, he/she creates a helper object with a property whose getter throws an exception, binds the Tag property of the textbox to this helper object and then forces an update on the binding.

'sapient's code was written before Silverlight 4 was released. We'll 'upgrade' his/her code to Silverlight 4. The class ControlValidationHelper becomes the following:

public class ControlValidationHelper : IDataErrorInfo
{
    public string Message { get; set; }

    public object ValidationError { get; set; }

    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    public string this[string columnName]
    {
        get { return Message; }
    }
}

It's easy enough to knock up a quick demo application to try this out. I created the following three controls:

    <TextBox x:Name="tbx" Text="{Binding Path=Text, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=TwoWay}" />
    <Button Click="ForceError_Click">Force error</Button>
    <Button Click="ClearError_Click">Clear error</Button>

The Text property and the event handlers for the two buttons live in the code-behind and are as follows:

    public string Text { get; set; }

    private void ForceError_Click(object sender, RoutedEventArgs e)
    {
        var helper = new ControlValidationHelper() { Message = "oh no!" };
        tbx.SetBinding(Control.TagProperty, new Binding("ValidationError")
        {
            Mode = BindingMode.TwoWay,
            NotifyOnValidationError = true,
            ValidatesOnDataErrors = true,
            UpdateSourceTrigger = UpdateSourceTrigger.Explicit,
            Source = helper
        });
        tbx.GetBindingExpression(Control.TagProperty).UpdateSource();
    }

    private void ClearError_Click(object sender, RoutedEventArgs e)
    {
        BindingExpression b = tbx.GetBindingExpression(Control.TagProperty);
        if (b != null)
        {
            ((ControlValidationHelper)b.DataItem).Message = null;
            b.UpdateSource();
        }
    }

The 'Force error' button should make a validation error appear on the textbox, and the 'Clear error' button should make it go away.

One potential downside of this approach occurs if you are using a ValidationSummary. The ValidationSummary will list all validation errors against ValidationError instead of against the name of each property.

like image 139
Luke Woodward Avatar answered Sep 22 '22 19:09

Luke Woodward