2
votes

Here is the problem:

  1. I have a simple form (textboxes, etc).
    • The bindings are all within a BindingGroup.
    • Each binding has UpdateSourceTrigger=Explicit set.
    • Some bindings have validation rules attached that do not allow blank/null values (required field).
  2. I bind a brand new, empty object to the form.
  3. Without entering any data, the user clicks the save button triggering BindingGroup.UpdateSources().
  4. UpdateSources succeeds, no validation errors are triggered.

I believe this occurs because WPF only triggers the validation rules of each binding if the user has actively changed the value of that field in the UI, and since I originally bound an empty object to the form, nothing has changed. This is not the behavior I want - I want all validation rules to be evaluated when UpdateSources is called.

Does anyone know a (hopefully clean) way to get the behavior I want?


Here is a (shortened, simplified) example of the C# and XAML code:

ToolTypeModelPanel.xaml.cs

private void addModelButton_Click(object sender, RoutedEventArgs e)
{
    ToolModel model = new ToolModel();

    // bind the model details view to the new model
    this.createModelBinding = new Binding();
    this.createModelBinding.Source = model;
    this.modelFormGrid.SetBinding(Grid.DataContextProperty, this.createModelBinding);
}

private void saveModelButton_Click(object sender, RoutedEventArgs e)
{
    Binding modelDataContext = this.modelFormGrid.GetBindingExpression(Grid.DataContextProperty).ParentBinding;

    if (modelDataContext == this.modelDetailsBinding && this.modelListBox.SelectedItem != null)
    {
        // update existing tool model
        if (this.modelFormBindingGroup.UpdateSources())
        {
            // ...
        }
    }
    else if (modelDataContext == this.createModelBinding)
    {
        // create new tool model
        ToolModel modelToCreate = (ToolModel)this.createModelBinding.Source;

        if (this.modelFormBindingGroup.UpdateSources())
        {
            Context.ToolModel.AddObject(modelToCreate);
            Context.SaveChanges();

            // ...
        }
    }
}

ToolTypeModelPanel.xaml

<GroupBox
    Grid.Row="3"
    Grid.Column="2"
    Margin="5"
    Header="{x:Static prop:Resources.HeaderModelDetails}">
    <Grid x:Name="modelFormGrid" DataContext="{Binding ElementName=modelListBox, Path=SelectedItem}">

        <Grid.BindingGroup>
            <BindingGroup x:Name="modelFormBindingGroup" />
        </Grid.BindingGroup>

        <Label Grid.Row="0" Grid.Column="0" Content="{x:Static prop:Resources.LabelModelName}" />
        <TextBox x:Name="modelNameTextBox"
            Grid.Row="0"
            Grid.Column="1">
            <TextBox.Text>
                <Binding Path="ModelName" UpdateSourceTrigger="Explicit">
                    <Binding.ValidationRules>
                        <vr:RequiredValidationRule />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

        <Label Grid.Row="3" Grid.Column="0" Content="{x:Static prop:Resources.LabelModelParameter}" />
        <TextBox x:Name="modelParameterTextBox"
            Grid.Row="3"
            Grid.Column="1"
            Text="{Binding Path=ModelParameter, UpdateSourceTrigger=Explicit}" />

        <Label Grid.Row="4" Grid.Column="0" Content="{x:Static prop:Resources.LabelFactoryAssemblyName}" />
        <TextBox x:Name="modelFactoryAssemblyTextBox"
            Grid.Row="4"
            Grid.Column="1">
            <TextBox.Text>
                <Binding Path="FactoryAssemblyName" UpdateSourceTrigger="Explicit">
                    <Binding.ValidationRules>
                        <vr:NamespaceValidationRule />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

        <Button x:Name="saveModelButton"
            Width="100"
            Margin="36,0,0,0"
            IsEnabled="False"
            Content="{x:Static prop:Resources.ButtonSaveText}"
            Click="saveModelButton_Click" />
    </Grid>
</GroupBox>
2
can you post a sample example for your problem.blindmeis

2 Answers

2
votes

My current workaround is: After binding a new item to the form, set fields of the form that need validation to a non-null but empty value for example:

this.modelNameTextBox.Text = string.Empty;

This causes the WPF validation scheme to validate the binding of this textbox when the sources are updated. If anyone has a cleaner solution please let me know.

0
votes

why did you set the UpdateSourceTrigger to explicit for you controls? change it to lostfocus or propertychanged.