文本框焦点与DependencyProperty的双向数据绑定

时间:2014-10-21 20:59:21

标签: c# wpf xaml data-binding dependency-properties

在由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同时添加PropertyChangedLostFocus到绑定中,同时将DependencyProperty的默认值更改为true,其中没有一个改变了有关行为的任何内容。我还尝试IsKeyboardFocused代替IsFocused而没有任何更改,IsKeyboardFocusWithin,这使应用程序关闭而没有评论 - 可能是DevExpress异常 - 组装网格。)

1 个答案:

答案 0 :(得分:0)

您不是将GroupFocused属性绑定到TextBox.IsFocused属性的数据,而是将数据绑定到FocusHelper.IsFocused属性,以编程方式调用Focus TextBox

有明显的区别。在Focus 上调用TextBox方法会导致TextBox.IsFocused属性设置为true,但该属性与您的GroupFocusedFocusHelper.IsFocused属性,因此当false属性设置为TextBox.IsFocused时,两者都不会设置为false

此外,在尝试设置焦点时,您无法将数据绑定到TextBox.IsFocused属性,因为它是只读的。有关详细信息,请参阅MSDN上的UIElement.IsFocused Property页面。

然而,有一个简单的解决方案。它可能看起来不漂亮,但它肯定会工作......只需将GroupFocused属性设置为false,然后再将其设置为true。也许是这样的:

private void FocusTextBox()
{
    GroupFocused = false;
    GroupFocused = true;
}

...

FocusTextBox();