仅为视觉效果而不为FrameworkElement子类触发WPF键盘事件

时间:2017-05-10 14:42:07

标签: wpf events keyboard frameworkelement drawingvisual

我创建了一个FrameworkElement的子类,它有一个Visuals集合:

public class GameElement : FrameworkElement
{
    private VisualCollection Visuals { get; }

    public GameElement()
    {
        this.KeyDown += this.OnKeyDown;
        this.MouseDown += this.OnMouseDown;
    }

    private void OnKeyDown(object sender, KeyEventArgs keyEventArgs)
    {
        ... // Does not get fired.
    }

    private void OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        ... // Does get fired.
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        // Draw a transparent background to catch mouse events (otherwise hit testing won't hit anything).
        drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
    }

    protected override int VisualChildrenCount
    {
        get
        {
            return this.Visuals.Count;
        }
    }

    protected override Visual GetVisualChild(int index)
    {
        if (index < 0 || index >= this.Visuals.Count)
        {
            throw new ArgumentOutOfRangeException();
        }

        return this.Visuals[index];
    }
}

我使用以下代码在XAML中显示此元素:

<UserControl
    x:Class="..."
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Background="Black">

    <Grid Margin="10">
        <local:GameElement x:Name="GameElement" ClipToBounds="True" />
    </Grid>
</UserControl>

我已经尝试了我能想到的一切,但我无法解决KeyDown事件。我在网上找到的最常用的评论与焦点有关。我尝试过Focusable =&#34; True&#34;的每一个组合。并调用this.Focus(),但没有任何作用。

任何人都知道如何做到这一点? 谢谢!

2 个答案:

答案 0 :(得分:1)

为了能够处理按下元素的键应该集中注意力。 如果你能做到这一点,也试着从控制而不是FramworkElement派生它。

public class GameElement : Control
{
    private VisualCollection Visuals { get; }

    public GameElement()
    {
        this.KeyDown += this.OnKeyDown;
        this.MouseDown += this.OnMouseDown;
    }

    private void OnKeyDown(object sender, KeyEventArgs keyEventArgs)
    {
        // Does get fired.
    }

    private void OnMouseDown(object sender, MouseButtonEventArgs e)
    {
        Focus();
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        // Draw a transparent background to catch mouse events (otherwise hit testing won't hit anything).
        drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
    }

    protected override int VisualChildrenCount
    {
        get
        {
            return this.Visuals.Count;
        }
    }

    protected override Visual GetVisualChild(int index)
    {
        if (index < 0 || index >= this.Visuals.Count)
        {
            throw new ArgumentOutOfRangeException();
        }

        return this.Visuals[index];
    }
}

答案 1 :(得分:0)

我终于通过注册一个也处理处理事件的类处理程序来实现它。

EventManager.RegisterClassHandler(typeof(Window), Keyboard.KeyDownEvent, new KeyEventHandler(OnKeyDown), true);