7

我在 WPF 窗口上使用KeyUpandKeyDown事件。

我在这个窗口的 CompositionTarget_Rendering 事件中也有很多调用,它们创建 UIElement 并为其设置动画。这是由下面的引擎类完成的:

int _Fps;
Stopwatch sw = new Stopwatch();

void CompositionTarget_Rendering_Stats(object sender, EventArgs e)
{
    _Fps++;
    var ms = sw.ElapsedMilliseconds;
    sw.Restart();
    engine.Update(ms / 1000f);
    timeFrames.Add(ms);
}

我注意到我拥有的元素越多,获取KeyUpKeyDown事件就越慢。

当我在主窗口中有大约 1000 个 UIelements 时,control_KeyDown 和 control_KeyUp 的代码在我按下或释放一个键后大约半秒执行

如果 Window 内的动画也很滞后,这不会让我感到惊讶,但事实并非如此。

  • 帧率约为 55 fps
  • 动画保持流畅
  • 事件中的计算CompositionTarget_Rendering持续时间不超过 20 毫秒。

似乎只有键盘事件轮询受到严重条件的影响。

我的问题是:

  • WPF 中键盘处理背后的魔力是什么:为什么它在繁重的条件下变得迟钝,而不是渲染过程?
  • 如何处理更好的键盘输入并避免这种情况?

编辑:

我写了一个受安迪评论启发的样本。您可以将其复制粘贴到新 WPF 应用程序的主窗口中。它会在按键按下或按下时更改窗口的颜色,并在 CompositionTarget_Rendering 事件中填充尽可能多的文本框。

public partial class MainWindow : Window
{
    WrapPanel root2;

    public MainWindow()
    {
        InitializeComponent();
        root2 = new WrapPanel();
        root2.Margin = new Thickness(10);
        this.Content = root2;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        for (var i = 0; i < 2000; i++)
            root2.Children.Add(new TextBlock() { Background = Brushes.Yellow });

        this.KeyDown += MainWindow_KeyDown;
        this.KeyUp += MainWindow_KeyUp;
        CompositionTarget.Rendering += CompositionTarget_Rendering;
    }

    void MainWindow_KeyUp(object sender, KeyEventArgs e)
    {
        this.Background = Brushes.Red;
    }

    void MainWindow_KeyDown(object sender, KeyEventArgs e)
    {
        this.Background = Brushes.Green;
    }

    void CompositionTarget_Rendering(object sender, EventArgs e)
    {
        foreach (var child in root2.Children)
            ((TextBlock)child).Text = DateTime.Now.Millisecond.ToString();
    }
}

根据您的机器性能,更改 2000 以增加文本框的数量。在一定数量下,CompositionTarget_Rendering 触发器比 KeyUp 或 KeyDown 多。按键时看到边框颜色变化是相当明显的:按键按下,然后多次触发Composition_Rendering,然后触发keydown事件,边框变为红色。

4

1 回答 1

0

为了回答我的第二个问题,我找到了一种替代方法来执行全局键盘挂钩在 WPF / C# 中使用全局键盘挂钩 (WH_KEYBOARD_LL)

KeyupKeydown事件响应没有延迟,在繁重的 CPU 和图形负载下发生事件。

于 2013-04-11T18:00:13.583 回答