问题 WPF:数据绑定TabControl在选择新选项卡时不提交更改


我有一个TabControl,其中每个Tab及其内容都被数据绑定到ObservableCollection:

<TabControl ItemsSource="{Binding Path=.}">
    <TabControl.ContentTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Path=propertyValue}" />
        </DataTemplate>
    </TabControl>
</TabControl>

如果我单击选项卡1,然后在文本框中键入内容并单击选项卡以使TextBox失去焦点,我键入文本框的新数据将提交给ObservableCollection项。

但是,如果我在TestBox中键入数据然后立即单击另一个选项卡,则永远不会提交数据。另外,当我回到数据时,它不再设置为我输入的内容。

任何人都知道在更改当前选项卡之前强制提交数据的方法吗?

更新和修复

我做了什么就连线了 SelectionChanged 事件:

private void tabData_SelectionChanged(object sender, SelectionChangedEventArgs e) {
    theTabControl.Focus();         
}

在TabControl上调用Focus()会使TextBox失去焦点并提交数据。我这样做是因为我有其他控件 - 比如DatePicker - 它表现出类似的行为。这是一个很好的选择。


3806
2018-04-18 11:56


起源

它应该在焦点丢失时提交。尝试将另一个TextBox添加到模板并将焦点切换到它。它有效吗? - asktomsk
@asktomsk你是对的,它会在焦点丢失时提交。但是,当我选择新选项卡时,焦点不会丢失(或者事件未触发)。 - bugfixr
非常感谢。搜索5小时后它救了我 - TabControl.Focus() 救了我的屁股。好编辑:) - Mafii


答案:


这个问题在这里有详细描述: WPF绑定:使用LostKeyboardFocus而不是LostFocus作为UpdateSourceTrigger  非常有趣的是,微软的人多年来都知道这个问题,但仍然没有修复它。 这也是一个很大的讨论: 保存前的WPF Databind

这个黑客有效:

    <TabControl SelectionChanged="OnSelectionChanged">

和代码隐藏:

    private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (Keyboard.FocusedElement is TextBox)
            Keyboard.FocusedElement.RaiseEvent(new RoutedEventArgs(LostFocusEvent));
    }

12
2018-04-18 12:31





如果选择新选项卡,将从可视树中卸载旧选项卡。我认为这就是为什么不提交更改的原因。你可以尝试 停止这种行为 或者作为您可以设置的解决方法 UpdateSourceTrigger 至 PropertyChanged

<TextBox Text="{Binding Path=propertyValue, UpdateSourceTrigger="PropertyChanged"}" />

2
2018-04-18 12:20



这可能有用,但问题是我在更改ObservableCollection时保存数据。我猜这意味着每次击键都会导致数据被保存? - bugfixr
它确实会在每次按键时保存。或者,您可以将其更改为 UpdateSourceTrigger=Explicit 当你想要它时自己发布更新,但我想 PropertyChanged 是最好的选择 - Jason Ridge


如果您有其他控件或从文本框转换为制表符控件的方式,这可能是最佳答案。如果文本框以任何方式丢失键盘焦点,它将升级为失去焦点。

<TextBox PreviewLostKeyboardFocus="commentTextBox_PreviewLostKeyboardFocus"  Name="commentTextBox" Text="{Binding Comment, UpdateSourceTrigger=LostFocus}"/>

并在代码隐藏中的事件处理程序中: -

    private void commentTextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        (sender as TextBox).RaiseEvent(new RoutedEventArgs(LostFocusEvent));
    }

这具有在预览阶段将“丢失的键盘焦点”升级为完全成熟的“失去焦点”事件的效果。


0
2017-10-05 14:59





也许你可以试试这个

<TabControl ItemsSource="{Binding Path=.}">
<TabControl.ContentTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Path=propertyValue,UpdateSourceTrigger=LostFocus}" />
    </DataTemplate>
</TabControl>


-1
2018-04-18 12:22



这是TextBoxes的默认值。 - LPL
谢谢 - 虽然问题是当我选择一个新标签时没有触发LostFocus。 - bugfixr