views:

34

answers:

1

I have a form with some validations set in entity metadata class. and then binding entity instance to UI by VM. Something as below:

Xaml like:

   <Grid x:Name="LayoutRoot">
            <StackPanel VerticalAlignment="Top">
                <input:ValidationSummary />
            </StackPanel>
      <TextBox Text="{Binding Name, Mode=TwoWay}" />
      <ComboBox x:Name="xTest" ItemsSource="{Binding MyList}"
               SelectedItem="{Binding MyItem,Mode=TwoWay,
               DisplayMemberPath="MyName"
               ValidatesOnDataErrors=True,
               ValidatesOnNotifyDataErrors=True,
               ValidatesOnExceptions=True,
               NotifyOnValidationError=True,UpdateSourceTrigger=Explicit}"  />
      </Grid>

Code-behind like:

public MyForm()
{
  InitializeComponent();
  this.xTest.BindingValidationError +=new EventHandler<ValidationErrorEventArgs>((s,e)=>{

  BindingExpression be = this.xTest.GetBindingExpression(ComboBox.SelectedItemProperty);
  be.UpdateSource();

  if (e.Action == ValidationErrorEventAction.Added)
    ((ComboBox)s).Foreground = new SolidColorBrush(Colors.Red);
  });
}

Metadata like:

[Required]
 public string Name { get; set; }

 [RequiredAttribute]
 public int MyItemID { get; set; }

But when running the app, I got nothing display in valudationSummary. For CombBox, even there is error, looks like BindingValidationError event is never fired. How to resolve it?

+1  A: 

Why are you using an Explicit UpdateSourceTrigger?

Silverlight validation happens inside the binding framework, when the binding is updating the source object. The way you have this, there won't be a binding validation error because you never tell the binding to update the source object. Well, actually you do, but it happens inside the validation error event handler. You've written chicken-and-egg code.

  • Remove your UpdateSourceTrigger on your binding or set it to Default.
  • Remove the explicit call to BindingExpression.UpdateSource.
  • Remove setting the ComboBox foreground to red - you are using NotifyOnValidationError=True, which eliminates any need to manually color the control.
  • Remove the DisplayMemberPath from the binding

So your XAML:

<Grid x:Name="LayoutRoot"> 
    <StackPanel VerticalAlignment="Top"> 
         <input:ValidationSummary /> 
         <ComboBox x:Name="xTest" ItemsSource="{Binding MyList}" 
               SelectedItem="{Binding MyItem,
               Mode=TwoWay, 
               ValidatesOnDataErrors=True, 
               ValidatesOnNotifyDataErrors=True, 
               ValidatesOnExceptions=True, 
               NotifyOnValidationError=True}"  /> 
      </StackPanel> 
</Grid> 

And your code:

public MyForm()   
{   
  InitializeComponent();   
  // you don't need anything here to have the validations work
}  
Adam Sills
Thank you. Done your's suggestion: 1. DisplayMemberPath should be kept becuase MyName is one property of entity MyItem. 2.Add all validation option in xaml. 3. Remove code behind for event BindingValidationError. Then run the app again. the Result is: I can get the validation error in Entity.ValidationErrors in VM(I use message box to display it for testing), but can't get it in ValidationSummary.
KentZhou
Well you have DisplayMemberPath inside your binding in your example. And there is no DisplayMemberPath option in the binding markup extension.
Adam Sills
To get your validation summary to work, move it into the same parent container as your ComboBox (edited my answer).
Adam Sills
your are right. Thanks.
KentZhou