2

In my application, I have the following TabControl:

<TabControl ItemsSource="{Binding MyItemsSource}"
            ContentTemplate="{StaticResource ResourceKey=MyContentTemplate}"
            IsSynchronizedWithCurrentItem="True" />

Here is the ContentTemplate used:

<DataTemplate x:Key="MyContentTemplate">
    <Canvas>
        <TextBox Text="{Binding Path=MyFirstText, Mode=TwoWay}" />
        <TextBox Text="{Binding Path=MySecondText, Mode=TwoWay}" />
    </Canvas>
</DataTemplate>

And the ItemsSource:

public ObservableCollection<MyData> MyItemsSource { get; set; }

public class MyData
{
    public string MyFirstText { get; set; }
    public string MySecondText { get; set; }
}

Please consider this scenario:

  • Select the first tab
  • Enter some text in the first TextBox
  • Select the second tab
  • Select the first tab: The text entered in the TextBox of the first tab disappeared (because the binding was not applied)

Another scenario:

  • Select the first tab
  • Enter some text in the first TextBox
  • Select the second TextBox (or whatever to change the focus except changing tab)
  • Select the second tab
  • Select the first tab: The text entered is still displayed (because the binding was applied)

Is that a normal behavior? Or am I doing something wrong? Thank you.

Morgan M.
  • 846
  • 2
  • 9
  • 27

3 Answers3

2

It happens because TextBox's update trigger is set to LostFocus by default. Change it to PropertyChanged, and it should work:

<TextBox Text="{Binding Path=MyFirstText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

UpdateSourceTrigger: http://msdn.microsoft.com/en-us/library/system.windows.data.updatesourcetrigger.aspx

CKII
  • 1,439
  • 14
  • 26
1

It may be related to a focused element and OnLostFocus event being not fired when switching between tabs. Try altering your bindings with UpdateSourceTriger attribute like this:

<DataTemplate x:Key="MyContentTemplate">
    <Canvas>
        <TextBox Text="{Binding Path=MyFirstText, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Text="{Binding Path=MySecondText, UpdateSourceTrigger=PropertyChanged}" />
    </Canvas>
</DataTemplate>

Also, you do not need to specify twoway mode as in wpf it is the default one.

VidasV
  • 4,335
  • 1
  • 28
  • 50
0

The issue is that LostFocus isn't fired when changing tabs, you can change the UpdateSourceTrigger to PropertyChanged as previously mentioned, but I preferred extending TabControl and firing LostFocus manually. This way I don't have to add UpdateSourceTrigger=PropertyChanged to every TextBox in my Tab. I also avoid updating the viewmodel with every key press.

This is a derivative of the solution mentioned here. WPF: Data bound TabControl doesn't commit changes when new tab is selected

public class SmartTabControl : TabControl
{
    protected override void OnSelectionChanged(SelectionChangedEventArgs e)
    {
        if (Keyboard.FocusedElement is TextBox)
            Keyboard.FocusedElement.RaiseEvent(new RoutedEventArgs(LostFocusEvent));

        base.OnSelectionChanged(e);
    }
}
Community
  • 1
  • 1
Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48