我有一个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 - 它表现出类似的行为。这是一个很好的选择。
这个问题在这里有详细描述: 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));
}
如果选择新选项卡,将从可视树中卸载旧选项卡。我认为这就是为什么不提交更改的原因。你可以尝试 停止这种行为 或者作为您可以设置的解决方法 UpdateSourceTrigger 至 PropertyChanged
:
<TextBox Text="{Binding Path=propertyValue, UpdateSourceTrigger="PropertyChanged"}" />
如果您有其他控件或从文本框转换为制表符控件的方式,这可能是最佳答案。如果文本框以任何方式丢失键盘焦点,它将升级为失去焦点。
<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));
}
这具有在预览阶段将“丢失的键盘焦点”升级为完全成熟的“失去焦点”事件的效果。
也许你可以试试这个
<TabControl ItemsSource="{Binding Path=.}">
<TabControl.ContentTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=propertyValue,UpdateSourceTrigger=LostFocus}" />
</DataTemplate>
</TabControl>