我有一个 TabControl,它是绑定到列表的数据。(列表中的两个数据项)TabControl 有一个 DataTemplate,其中包含两个 TextBox 控件,这些控件绑定到我的数据类上的两个字符串属性。
如果我在第一个选项卡上的 Textbox1 上键入一些文本,然后单击 Tab2,则不会对数据源进行更新,并且更改将丢失。
这是因为 LostFocus 实际上并没有为 TextBox1 触发(它在 TextBox2 上,因为移动到选项卡 2 会自动聚焦 TextBox1),我相信这是因为每个选项卡共享模板中的相同文本框,并且只是更改选项卡开关上的 DataContext。
这里有两个事件可能会有所帮助:PreviewLostKeyboardFocus 和 DataContextChanged 两者在 TextBox 上仍然具有可用的键入文本。
还有一个古老的问题是工具栏保存按钮没有获得焦点。
在我看来,也许 Binding 类应该听 PreviousLostKeyboardFocus 而不是在上述两种情况下似乎都会触发的 LostFocus。
各位大佬是怎么解决这些问题的?
Aos,有哪些方法可以利用 PreviewLostKeyboardFocus 事件来更新源?(我正在考虑类似于顶级容器监视此事件,检查 OriginalSource 上是否存在带有 LostFocus UpdateSourceTrigger 的绑定并欺骗/强制绑定以更新源 - 但我是 Wpf 的新手,并且可能还有其他我没有考虑过的因素)
这是一个示例应用程序...
<Window x:Class="BindingFocusTabIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="398" Width="731" >
<Grid>
<TabControl Height="267" HorizontalAlignment="Left" Margin="31,36,0,0" Name="tabControl1" VerticalAlignment="Top" Width="472" ItemsSource="{Binding}">
<TabControl.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBox Margin="3" Name="TextBox1" Text="{Binding Text1}" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus" PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" DataContextChanged="TextBox_DataContextChanged"/>
<TextBox Margin="3" Name="TextBox2" Text="{Binding Text2}" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus" PreviewLostKeyboardFocus="TextBox_PreviewLostKeyboardFocus" DataContextChanged="TextBox_DataContextChanged"/>
</StackPanel>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
<GroupBox Header="List item 1" Height="115" HorizontalAlignment="Left" Margin="509,50,0,0" Name="groupBox1" VerticalAlignment="Top" Width="188">
<Grid >
<TextBox Height="23" HorizontalAlignment="Left" Margin="28,21,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="{Binding Path=[0].Text1}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="28,50,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" Text="{Binding Path=[0].Text2}"/>
</Grid>
</GroupBox>
<GroupBox Header="List item 2" Height="115" HorizontalAlignment="Left" Margin="509,184,0,0" Name="groupBox2" VerticalAlignment="Top" Width="188">
<Grid>
<TextBox Height="23" HorizontalAlignment="Left" Margin="28,21,0,0" Name="textBox3" VerticalAlignment="Top" Width="120" Text="{Binding Path=[1].Text1}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="28,50,0,0" Name="textBox4" VerticalAlignment="Top" Width="120" Text="{Binding Path=[1].Text2}"/>
</Grid>
</GroupBox>
<ToolBar Height="26" HorizontalAlignment="Left" Margin="54,3,0,0" Name="toolBar1" VerticalAlignment="Top" Width="200">
<Button>Save</Button>
</ToolBar>
</Grid>
及其代码隐藏
using System;
使用 System.Collections.Generic;使用 System.Diagnostics;使用 System.Windows;使用 System.Windows.Controls;使用 System.Windows.Input;
命名空间 BindingFocusTabIssue { public partial class MainWindow : Window { public MainWindow() { InitializeComponent();
DataContext = new List<DataClass>
{
new DataClass { Name="One"},
new DataClass { Name="Two"},
};
}
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
var textBox = (TextBox) e.Source;
Debug.WriteLine(textBox.Name + "_GotFocus and Text='" + textBox.Text + "'");
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
var textBox = (TextBox) e.Source;
Debug.WriteLine(textBox.Name + "_LostFocus and Text='" + textBox.Text + "'");
}
private void TextBox_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
var textBox = (TextBox) e.Source;
Debug.WriteLine(textBox.Name + "_PreviewLostKeyboardFocus and Text='" + textBox.Text + "'");
}
private void TextBox_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var textBox = (TextBox) sender;
Debug.WriteLine(textBox.Name + "_DataContextChanged and Text='" + textBox.Text + "'");
}
}
public class DataClass
{
public string Name { get; set; }
public string Text1 { get; set; }
public string Text2 { get; set; }
public override string ToString()
{
return Name;
}
}
}