UWP中点击CommandBar的AppBarButton时,最后获焦TextBox数据未更新
解决UWP中x:Bind TwoWay绑定在焦点未失焦时Save按钮不更新值的问题
嘿,这个问题我之前也踩过坑!核心原因其实很好理解——当你点击CommandBar里的Save AppBarButton时,页面上的last name文本框根本没失去焦点,而默认情况下TextBox的TwoWay绑定是在LostFocus(失去焦点)时才会把输入值同步到数据源里。
为啥普通Button就没问题?因为点击普通Button时,系统会自动让当前焦点控件(也就是那个TextBox)失去焦点,触发绑定更新;但AppBarButton属于应用栏控件,点击它不会触发页面内控件的焦点转移,所以last name的输入值还停留在TextBox里,没同步到你的绑定对象上。
给你几个实用的解决方案,按需选择:
方案1:修改TextBox的绑定更新时机(最推荐)
直接把TextBox的UpdateSourceTrigger改成PropertyChanged,这样每输入一个字符就会同步更新绑定的源属性,彻底避开焦点问题。对于姓名这种短字段来说,完全不用担心性能问题。
XAML代码修改示例:
<TextBox Text="{x:Bind ViewModel.FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBox Text="{x:Bind ViewModel.LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
方案2:手动触发绑定更新
如果不想每次输入都更新绑定,就在Save按钮的点击事件里,手动让未失焦的TextBox同步数据:
private void SaveAppBarButton_Click(object sender, RoutedEventArgs e) { // 手动更新last name文本框的绑定源 lastnameTextBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource(); // 也可以加上first name的保险,不过其实它已经失焦更新过了 firstnameTextBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource(); // 执行你的保存逻辑 SaveUserData(); }
要是页面上TextBox多,还可以写个通用方法遍历所有TextBox更新:
private void UpdateAllTextBoxBindings(UIElement parent) { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) { var child = VisualTreeHelper.GetChild(parent, i); if (child is TextBox textBox) { textBox.GetBindingExpression(TextBox.TextProperty)?.UpdateSource(); } else if (child is UIElement uiElement) { UpdateAllTextBoxBindings(uiElement); } } } // 调用方式 private void SaveAppBarButton_Click(object sender, RoutedEventArgs e) { UpdateAllTextBoxBindings(this.Content as UIElement); SaveUserData(); }
方案3:强制转移焦点
点击Save按钮时,把焦点转移到页面的其他元素(比如根容器),触发TextBox的LostFocus事件:
private void SaveAppBarButton_Click(object sender, RoutedEventArgs e) { // 把焦点设置到页面的根面板,触发所有TextBox的LostFocus if (this.Content is Panel rootPanel) { rootPanel.Focus(FocusState.Programmatic); } // 执行保存逻辑 SaveUserData(); }
这几个方案都能解决你的问题,个人最推荐方案1,简单直接一劳永逸~
内容的提问来源于stack exchange,提问作者slayernoah
相关产品推荐
相关产品推荐

