使用依赖项属性将TextBox对象引用分配给静态事件处理程序回调

时间:2017-11-22 04:55:11

标签: c# wpf xaml dependency-properties

我可能把自己画成了一个角落。我有一个自定义触摸键盘用户控件,它使用静态事件将键按下时传递给文本框。我尝试为所有文本框创建一个依赖项属性,以便在它们处于焦点时订阅我的触摸键盘事件处理程序,并在它们失去焦点时取消订阅。

我目前的问题是PropertyChangedCallbackIsTouchKeyboardTargetChanged永远不会触发。我已经读到这是因为它是在XAML中设置的,因此永远不会改变。"

到目前为止,我发现的其他答案都不适用于我的模式。我甚至不确定这是解决这个问题的正确方法,但如果这样做的话对我来说会很方便。我按照示例设置了我的MahApps TextBoxHelper

如果有人可以帮我解决PropertyChangedCallback问题,或者当任何人更好地了解如何在任何和所有文本框引发焦点事件时完成订阅/取消订阅静态事件,我将非常感激。

CS

public class TouchTextBoxHelper : DependencyObject
{
    public static readonly DependencyProperty IsTouchKeyboardTargetProperty = DependencyProperty.Register("IsTouchKeyboardTarget", typeof(bool), typeof(TouchTextBoxHelper), new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged));


    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetIsTouchKeyboardTargetEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsTouchKeyboardTargetProperty);
    }

    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsTouchKeyboardTargetProperty, value);
    }

    private static void IsTouchKeyboardTargetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var tb = d as TextBox;
        if (null == tb)
        {
            throw new InvalidOperationException("The property 'IsTouchKeyboardTarget' may only be set on TextBox elements.");
        }

        if (e.OldValue != e.NewValue)
        {
            //tb.SetValue(SpellCheck.IsEnabledProperty, (bool)e.NewValue);
            if ((bool)e.NewValue)
            {
                tb.GotFocus += TextBoxBaseGotFocus;
                tb.LostFocus += TextBoxBaseLostFocus;
            }
            else
            {
                tb.GotFocus -= TextBoxBaseGotFocus;
                tb.LostFocus -= TextBoxBaseLostFocus;
            }
        }
    }

    private static void TextBoxBaseGotFocus(object sender, RoutedEventArgs e)
    {
        TouchTextBoxEvents.tb = sender as TextBox;
        StaticEvents.OnShowTouchKeyboard(sender, e);
        StaticEvents.TouchKeyboardKeyTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
        StaticEvents.TouchKeyboardSpaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
        StaticEvents.TouchKeyboardBackspaceTouch += TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
    }

    private static void TextBoxBaseLostFocus(object sender, RoutedEventArgs e)
    {
        StaticEvents.OnHideTouchKeyboard(sender, e);
        StaticEvents.TouchKeyboardKeyTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardKeyTouch;
        StaticEvents.TouchKeyboardSpaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardSpaceTouch;
        StaticEvents.TouchKeyboardBackspaceTouch -= TouchTextBoxEvents.StaticEvents_TouchKeyboardBackspaceTouch;
    }
}

public class TouchTextBoxEvents
{
    public static TextBox tb = null;
    public static void StaticEvents_TouchKeyboardKeyTouch(object sender, EventArgs e)
    {
        int i = tb.CaretIndex;
        string t = (sender as Button).Content.ToString();
        tb.Text = tb.Text.Insert(tb.CaretIndex, t);
        tb.CaretIndex = i + 1;
    }

    public static void StaticEvents_TouchKeyboardBackspaceTouch(object sender, EventArgs e)
    {
        int i = tb.CaretIndex;
        if (tb.CaretIndex == 0) return;
        tb.Text = tb.Text.Remove(tb.CaretIndex - 1, 1);
        tb.CaretIndex = i - 1;
    }

    public static void StaticEvents_TouchKeyboardSpaceTouch(object sender, EventArgs e)
    {
        int i = tb.CaretIndex;
        tb.Text = tb.Text.Insert(tb.CaretIndex, " ");
        tb.CaretIndex = i + 1;
    }
}

编辑:

事实证明我所要做的就是更新我的二传手:

    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static void SetIsTouchKeyboardTargetEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsTouchKeyboardTargetProperty, value);
        TextBox tb = obj as TextBox;
        if (tb == null) return;
        if (value)
        {

            tb.GotFocus += TextBoxBaseGotFocus;
            tb.LostFocus += TextBoxBaseLostFocus;
        }
        else
        {
            tb.GotFocus -= TextBoxBaseGotFocus;
            tb.LostFocus -= TextBoxBaseLostFocus;
        }
    }

EDIT2:

PropertyChangedCallback逻辑置于setter中是一件坏事。幸运的是,Clemens提供了一些很好的建议,使用RegisterAttached代替Register。这消除了从DependencyObject派生的需要,并清除了PropertyChangedCallback未触发的问题。

1 个答案:

答案 0 :(得分:1)

必须通过致电DependencyProperty.RegisterAttached而不是Register来注册附加财产。也不需要从DependencyObject派生声明类:

public class TouchTextBoxHelper
{
    public static readonly DependencyProperty IsTouchKeyboardTargetProperty =
        DependencyProperty.RegisterAttached(
            "IsTouchKeyboardTarget",
            typeof(bool),
            typeof(TouchTextBoxHelper),
            new FrameworkPropertyMetadata(false, IsTouchKeyboardTargetChanged));

    ...
}