文本框焦点与DependencyProperty的双向数据绑定
本文关键字:数据绑定 DependencyProperty 焦点 文本 | 更新日期: 2023-09-27 18:27:19
在根据MVVM原理构建的WPF应用程序中,我需要从代码中显式地将焦点设置为TextBox(对键盘事件做出反应),还需要知道焦点是否丢失。从这里的另一个问题中,我已经收集到,似乎实现这一点的方法是在DependencyProperty上进行数据绑定。为此,我选择了以下代码:
public static class FocusHelper
{
public static bool GetIsFocused(DependencyObject obj)
{
return (bool)obj.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject obj, bool value)
{
obj.SetValue(IsFocusedProperty, value);
}
public static readonly DependencyProperty IsFocusedProperty =
DependencyProperty.RegisterAttached(
"IsFocused", typeof(bool), typeof(FocusHelper),
new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));
private static void OnIsFocusedPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var uie = (UIElement)d;
if ((bool)e.NewValue)
{
uie.Focus();
}
}
}
TextBox绑定如下所示:
<TextBox Text="{Binding Path=RowData.Row.Group}" helper:FocusHelper.IsFocused="{Binding RowData.Row.GroupFocused, Mode=TwoWay}"
这是在(DevExpress)网格中;Row
是整行绑定到的实际ViewModel。
绑定ViewModel中的相应代码:
private bool groupFocused;
public bool GroupFocused
{
get { return this.groupFocused; }
set
{
this.groupFocused = value;
this.NotifyOfPropertyChange(() => this.GroupFocused);
}
}
当处理键盘事件时,GroupFocused
设置为true,这肯定会调用DependencyProperty回调并将焦点设置为TextBox。然而,当控件失去焦点时,该更改不会反映回ViewModel(DependencyProperty的回调也不会被调用)。
这种行为有什么明显的原因吗?代码有什么问题吗?
(我尝试将UpdateSourceTrigger
和PropertyChanged
以及LostFocus
一起添加到绑定中,还将DependencyProperty的默认值更改为true
,但这些都没有改变行为。我还尝试了IsKeyboardFocused
而不是IsFocused
,但没有任何更改,以及IsKeyboardFocusWithin
,这使应用程序在组装网格时关闭,没有任何注释-可能是DevExpress异常。)
您不是将GroupFocused
属性数据绑定到TextBox.IsFocused
属性,而是将其数据绑定到以编程方式调用TextBox
上的Focus
的FocusHelper.IsFocused
属性。
有一个明显的区别。在TextBox
上调用Focus
方法将导致TextBox.IsFocused
属性设置为true
,但该属性与GroupFocused
或FocusHelper.IsFocused
属性之间没有连接,因此当TextBox.IsFocused
属性设置为false
时,两者都不会设置为CCD21。
此外,由于TextBox.IsFocused
属性是只读的,因此无法在尝试设置焦点时将其数据绑定到CCD_24。有关详细信息,请参阅MSDN上的UIElement.IsFocused
属性页。
然而,有一个简单的解决方案。它可能看起来不漂亮,但肯定会起作用。。。每次将GroupFocused
属性设置为true之前,只需将其设置为false
即可。也许是这样的:
private void FocusTextBox()
{
GroupFocused = false;
GroupFocused = true;
}
FocusTextBox();