views:

989

answers:

3

Please consider the following example. Note that in the real-word, the binding source will likely be a data object. I'm using a TextBlock for simplicity.

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel Margin="20">

        <Label>Enter a Name:</Label>
        <TextBox x:Name="txt_Name" Text="{Binding ElementName=display_name, Path=Text, UpdateSourceTrigger=LostFocus}" />

        <Label>The name you entered:</Label>
        <TextBlock x:Name="display_name" />

        <Button x:Name="btn_Save" Click="SaveClick">_Save</Button>

    </StackPanel>
</Window>

Class Window1

    Private Sub SaveClick(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        MessageBox.Show("Saving your name as: " & display_name.Text)
    End Sub

End Class

In the example above, if I enter the name "Joe" into the TextBox and click "Save", the TextBlock is updated upon LostFocus and the data is "saved" properly. All is good.

However, if I then enter "Bob" in the TextBox and use my access key (Alt-S) to Save, the TextBlock is not updated because the LostFocus event on the TextBox is not fired. As a result, my binding source is not updated and the wrong value (i.e., "Joe") is saved.

In most WPF TextBox data entry fields, you'll want to do your validation upon LostFocus (not PropertyChanged); however, if the LostFocus event does not fire (and thus the binding is not updated) when an Access Key is used, how do we validate the entry?? In WinForms we have the Validating and Validated events, but they are absent in WPF.

Thanks.

+2  A: 

You can do this manually just before the save using:

txt_Name.GetBindingExpression(TextBox.TextProperty).UpdateTarget();

A bit ugly, but it works.

Sam Meldrum
+1  A: 

You can also change focus in your click handler before reading the value, for example forcing the focus to the button or to another text box

This is another "ugly, but it works" solution, it may be appropriate if you have a lot of controls or don't want to mess with their binding expressions.

Nir
+1  A: 

Well, if you're more interested in your real world scenario than your contrived example here, you can set the binding on the text box to update on data change rather than lost focus, and the data will be saved in both scenarios without any ugly hacks. The only problem (which is mentioned in the WPF documentation for Bindings) is that this may impact the performance of your application. If you're running on any sort of even relatively new machine, you won't notice the difference ( I haven't ).

Alex Marshall