2014-10-31 57 views
0

我有一個WPF UserControl具有某種依賴項屬性DepProp按鍵時修改WPF依賴項屬性

我希望在按下ShiftAlt時修改此屬性,並在釋放按鍵時返回上一個值。

我想要的與觸發器類似,但我不知道是否可以將條件設​​置爲「按下Shift鍵」。

我知道可以爲控件指定KeyBindings,據我所知他們可以在按下按鍵時執行命令,但在釋放按鍵時不會恢復以前的vlaue。

任何想法如何做到這一點?

+0

您想在哪個範圍內捕獲這些密鑰?在整個父窗口內,當鍵盤焦點在'UserControl'內,還是什麼? – 2014-10-31 18:54:18

+0

第二種情況應該足夠了。 – elnigno 2014-10-31 19:00:17

回答

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(); 
    } 
} 
+0

謝謝,我會盡快嘗試。 – elnigno 2014-10-31 22:55:45