按键时修改WPF依赖项属性

时间:2014-10-31 18:09:58

标签: wpf user-controls

我有一个带有特定依赖属性UserControl的WPF DepProp

我希望在按ShiftAlt时修改此属性,并在释放密钥时返回上一个值。

我想要的是类似于触发器,但我不知道是否可以将条件设​​置为“按下Shift键”。

我知道可以为控件指定KeyBindings,据我所知,他们可以在按下某个键时执行命令,但是在释放该键时不会恢复上一个vlaue。 / p>

关于如何做到这一点的任何想法?

1 个答案:

答案 0 :(得分:1)

您可以创建一个附加行为,您可以将其附加到某些"范围"元素(例如,您的UserControl)将维护一个附加的只读属性,该属性从树中继承。然后,您只需在附加属性上添加Trigger

public sealed class AltShiftHotKeyBehavior : Behavior<FrameworkElement>
{
    private const ModifierKeys AltShift = ModifierKeys.Alt | ModifierKeys.Shift;

    private static readonly DependencyPropertyKey IsAltShiftPressedPropertyKey =
        DependencyProperty.RegisterAttachedReadOnly(
            "IsAltShiftPressed",
            typeof(bool),
            typeof(AltShiftHotKeyBehavior),
            new FrameworkPropertyMetadata(
                false,
                FrameworkPropertyMetadataOptions.Inherits));

    public static readonly DependencyProperty IsAltShiftPressedProperty =
        IsAltShiftPressedPropertyKey.DependencyProperty;

    public static bool GetIsAltShiftPressed(DependencyObject element)
    {
        return (bool)element.GetValue(IsAltShiftPressedProperty);
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        var element = this.AssociatedObject;

        element.AddHandler(
            FrameworkElement.LoadedEvent,
            (RoutedEventHandler)OnLoaded,
            handledEventsToo: true);

        element.AddHandler(
            FrameworkElement.UnloadedEvent,
            (RoutedEventHandler)OnUnloaded,
            handledEventsToo: true);

        element.AddHandler(
            UIElement.PreviewKeyDownEvent,
            (KeyEventHandler)OnKey,
            handledEventsToo: true);

        element.AddHandler(
            UIElement.PreviewKeyUpEvent,
            (KeyEventHandler)OnKey,
            handledEventsToo: true);

        element.AddHandler(
            UIElement.LostKeyboardFocusEvent,
            (KeyboardFocusChangedEventHandler)OnLostKeyboardFocus,
            handledEventsToo: true);

        var window = element as Window;
        if (window != null)
        {
            window.Activated += OnWindowActivated;
            window.Deactivated += OnWindowDeactivated;
        }

        CheckToggledState();
    }

    protected override void OnDetaching()
    {
        ClearToggledState();

        base.OnDetaching();

        var element = this.AssociatedObject;

        element.RemoveHandler(
            FrameworkElement.LoadedEvent,
            (RoutedEventHandler)OnLoaded);

        element.RemoveHandler(
            FrameworkElement.UnloadedEvent,
            (RoutedEventHandler)OnUnloaded);

        element.RemoveHandler(
            UIElement.PreviewKeyDownEvent,
            (KeyEventHandler)OnKey);

        element.RemoveHandler(
            UIElement.PreviewKeyUpEvent,
            (KeyEventHandler)OnKey);

        element.RemoveHandler(
            UIElement.LostKeyboardFocusEvent,
            (KeyboardFocusChangedEventHandler)OnLostKeyboardFocus);

        var window = element as Window;
        if (window != null)
        {
            window.Activated -= OnWindowActivated;
            window.Deactivated -= OnWindowDeactivated;
        }
    }

    private void CheckToggledState()
    {
        var element = this.AssociatedObject;
        if (element.IsLoaded &&
            element.IsKeyboardFocusWithin &&
            Keyboard.PrimaryDevice.Modifiers == AltShift)
        {
            element.SetValue(IsAltShiftPressedPropertyKey, true);
        }
        else
        {
            element.ClearValue(IsAltShiftPressedPropertyKey);                
        }
    }

    private void ClearToggledState()
    {
        this.AssociatedObject.ClearValue(IsAltShiftPressedPropertyKey);
    }

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        CheckToggledState();
    }

    private void OnUnloaded(object sender, RoutedEventArgs e)
    {
        ClearToggledState();
    }

    private void OnWindowActivated(object sender, EventArgs e)
    {
        CheckToggledState();
    }

    private void OnWindowDeactivated(object sender, EventArgs e)
    {
        ClearToggledState();
    }

    private void OnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        CheckToggledState();
    }

    private void OnKey(object sender, KeyEventArgs e)
    {
        CheckToggledState();
    }
}