WinUI3中KeyboardAccelerators功能不符合预期的问题求助
问题原因分析
核心问题是通过KeyboardAccelerator触发SaveHoursCommand时,TextBox因焦点未丢失,导致绑定目标未同步源的重置值:
- 点击保存按钮时,按钮会获取焦点,TextBox失去焦点,此时TwoWay绑定会自动同步源(
OpeningHours.PrimaApertura)的最新重置值到TextBox的Text属性。 - 按下Enter键触发KeyboardAccelerator时,TextBox始终持有焦点,WinUI/WPF的TwoWay绑定在控件有焦点时会优先保留当前输入值,不会自动同步源的重置值,因此TextBox内容未清空。
另外,第二个未配置KeyboardAccelerator的TextBox按下Enter无反应,是因为默认情况下TextBox的Enter键未绑定任何命令,需手动处理。
解决办法
方法1:Reset后强制更新TextBox绑定
在Reset执行完成后,手动触发TextBox的绑定更新,确保源值同步到控件。若采用MVVM模式,可通过View后台代码实现:
// View后台代码,获取TextBox实例后更新绑定 var bindingExpr = primaapertura.GetBindingExpression(TextBox.TextProperty); bindingExpr?.UpdateTarget();
如果不想直接操作控件,可在ViewModel中添加ResetCompleted事件,View订阅后执行绑定更新逻辑。
方法2:强制TextBox失去焦点
在SaveHours命令执行完成后,将焦点转移到其他控件(如保存按钮),触发绑定同步:
[RelayCommand] void SaveHours() { // 原有保存逻辑... Reset(); // 转移焦点到保存按钮 FocusManager.TryFocusAsync(salva, FocusState.Programmatic); }
方法3:改用TextBox的KeyDown事件替代KeyboardAccelerator
直接处理TextBox的KeyDown事件,按下Enter时触发命令并标记事件已处理,避免默认行为干扰:
XAML修改:
<TextBox x:Name="primaapertura" ex:TextBoxExtensions.Mask="99:99 99:99" Margin="0" Text="{x:Bind GiorniOperativi.OpeningHours.PrimaApertura, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" KeyDown="Primaapertura_KeyDown"> </TextBox>
后台代码:
private void Primaapertura_KeyDown(object sender, KeyRoutedEventArgs e) { if (e.Key == Windows.System.VirtualKey.Enter) { GiorniOperativi.SaveHoursCommand.Execute(null); e.Handled = true; // 强制更新绑定 var tb = sender as TextBox; tb?.GetBindingExpression(TextBox.TextProperty)?.UpdateTarget(); } }
方法4:优化ViewModel的Refresh逻辑
确保OraAperturaData的PrimaApertura属性被明确重置为空字符串,避免依赖对象默认值:
public void Refresh() { _ora = new OraApertura(); // 明确重置目标属性 _ora.PrimaApertura = string.Empty; OnPropertyChanged(nameof(PrimaApertura)); }
第二个TextBox的处理逻辑
对于未配置KeyboardAccelerator的第二个TextBox,可直接复用上述方法3的KeyDown事件处理方式,或添加对应的KeyboardAccelerator配置,确保按下Enter时触发命令并同步绑定。
内容的提问来源于stack exchange,提问作者Kraken
相关产品推荐
相关产品推荐

