Blend KeyTrigger fires several times

I am using the Blend SDK KeyTrigger in a WPF project and have a problem that the event is fired several times every time I click on the assigned key, here is DeleteCommand.

<ei:KeyTrigger FiredOn="KeyDown" ActiveOnFocus="True" SourceName="repositoryPackages" Key="Delete">
  <i:InvokeCommandAction Command="{Binding SelectedItem.DeleteCommand, repositoryPackages}" />
</ei:KeyTrigger>

This trigger is in the ListView trigger collection, which itself is in the grid inside the user control.

The user control is then embedded in the WPF TabControl tab in the main application window.

Each time I switch and return to the tab using the ListView, the trigger invokes the command again ad infinitum.

I looked at the source of KeyTrigger (at Microsoft.Expressions.Interactions) and noticed the following lines:

protected override void OnEvent(EventArgs eventArgs)
{
  if (this.ActiveOnFocus)
  {
    this.targetElement = base.Source;
  }
  else
  {
    this.targetElement = GetRoot(base.Source);
  }
  if (this.FiredOn == KeyTriggerFiredOn.KeyDown)
  {
    this.targetElement.KeyDown += new KeyEventHandler(this.OnKeyPress);
  }
  else
  {
    this.targetElement.KeyUp += new KeyEventHandler(this.OnKeyPress);
  }
}

OnEvent , OnLoaded. TabControl OnLoaded , . , KeyDown/KeyUp.

Blend SDK KeyTrigger.

- , , KeyTrigger?

+3
2

FiredOn="KeyUp" ? KeyDown , , ?

+2

KeyTrigger KeyDown/Up Loaded.

    public class KeyTrigger : EventTriggerBase<UIElement>
{
    // Fields
    public static readonly DependencyProperty ActiveOnFocusProperty = DependencyProperty.Register("ActiveOnFocus", typeof(bool), typeof(KeyTrigger));
    public static readonly DependencyProperty FiredOnProperty = DependencyProperty.Register("FiredOn", typeof(KeyTriggerFiredOn), typeof(KeyTrigger));
    public static readonly DependencyProperty KeyProperty = DependencyProperty.Register("Key", typeof(Key), typeof(KeyTrigger));
    public static readonly DependencyProperty ModifiersProperty = DependencyProperty.Register("Modifiers", typeof(ModifierKeys), typeof(KeyTrigger));
    private UIElement targetElement;

    // Methods
    private static ModifierKeys GetActualModifiers(Key key, ModifierKeys modifiers)
    {
        if ((key == Key.LeftCtrl) || (key == Key.RightCtrl))
        {
            modifiers |= ModifierKeys.Control;
            return modifiers;
        }
        if (((key == Key.LeftAlt) || (key == Key.RightAlt)) || (key == Key.System))
        {
            modifiers |= ModifierKeys.Alt;
            return modifiers;
        }
        if ((key == Key.LeftShift) || (key == Key.RightShift))
        {
            modifiers |= ModifierKeys.Shift;
        }
        return modifiers;
    }

    protected override string GetEventName()
    {
        return "Loaded";
    }

    private static UIElement GetRoot(DependencyObject current)
    {
        UIElement element = null;
        while (current != null)
        {
            element = current as UIElement;
            current = VisualTreeHelper.GetParent(current);
        }
        return element;
    }

    protected override void OnDetaching()
    {
        if (this.targetElement != null)
        {
            if (this.FiredOn == KeyTriggerFiredOn.KeyDown)
            {
                this.targetElement.KeyDown -= new KeyEventHandler(this.OnKeyPress);
            }
            else
            {
                this.targetElement.KeyUp -= new KeyEventHandler(this.OnKeyPress);
            }
        }
        base.OnDetaching();
    }

    protected override void OnEvent(EventArgs eventArgs)
    {
        if (this.ActiveOnFocus)
        {
            this.targetElement = base.Source;
        }
        else
        {
            this.targetElement = GetRoot(base.Source);
        }
        if (this.FiredOn == KeyTriggerFiredOn.KeyDown)
        {
            this.targetElement.KeyDown += new KeyEventHandler(this.OnKeyPress);
        }
        else
        {
            this.targetElement.KeyUp += new KeyEventHandler(this.OnKeyPress);
        }
    }

    private void OnKeyPress(object sender, KeyEventArgs e)
    {
        if ((e.Key == this.Key) && (Keyboard.Modifiers == GetActualModifiers(e.Key, this.Modifiers)))
        {
            base.InvokeActions(e);
        }
    }

    // Properties
    public bool ActiveOnFocus
    {
        get
        {
            return (bool)base.GetValue(ActiveOnFocusProperty);
        }
        set
        {
            base.SetValue(ActiveOnFocusProperty, value);
        }
    }

    public KeyTriggerFiredOn FiredOn
    {
        get
        {
            return (KeyTriggerFiredOn)base.GetValue(FiredOnProperty);
        }
        set
        {
            base.SetValue(FiredOnProperty, value);
        }
    }

    public Key Key
    {
        get
        {
            return (Key)base.GetValue(KeyProperty);
        }
        set
        {
            base.SetValue(KeyProperty, value);
        }
    }

    public ModifierKeys Modifiers
    {
        get
        {
            return (ModifierKeys)base.GetValue(ModifiersProperty);
        }
        set
        {
            base.SetValue(ModifiersProperty, value);
        }
    }
}

, , , , Loaded. /.

, , , .

, KeyTrigger , Tab, / , .

CallMethodAction KeyDown.

+2

All Articles