Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 为什么KeyUp和KeyDown事件变得越来越慢?_Wpf_Keyboard Events - Fatal编程技术网

Wpf 为什么KeyUp和KeyDown事件变得越来越慢?

Wpf 为什么KeyUp和KeyDown事件变得越来越慢?,wpf,keyboard-events,Wpf,Keyboard Events,我正在WPF窗口上使用KeyUp和KeyDown事件 我在这个窗口的CompositionTarget_渲染事件中也有很多调用,用于创建UIElements并设置它们的动画。这是由以下发动机等级完成的: int _Fps; Stopwatch sw = new Stopwatch(); void CompositionTarget_Rendering_Stats(object sender, EventArgs e) { _Fps++; var ms = sw.ElapsedM

我正在WPF窗口上使用
KeyUp
KeyDown
事件

我在这个窗口的CompositionTarget_渲染事件中也有很多调用,用于创建UIElements并设置它们的动画。这是由以下发动机等级完成的:

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);
}
我注意到,我拥有的元素越多,获取
KeyUp
KeyDown
事件的速度就越慢

当我在主窗口中有大约1000个UIelements时,在我按下或释放一个键后大约半秒钟执行control\u KeyDown和control\u keydup的代码

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

  • 帧速率约为55 fps
  • 动画保持平滑
  • CompositionTarget\u Rendering
    事件中的计算持续时间不超过20毫秒
似乎只有键盘事件轮询遇到了严重的问题

我的问题是:

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

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

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();
    }
}
公共部分类主窗口:窗口
{
包皮根2;
公共主窗口()
{
初始化组件();
root2=新的WrapPanel();
根2.边缘=新厚度(10);
this.Content=root2;
}
已加载私有无效窗口(对象发送器、路由目标)
{
对于(变量i=0;i<2000;i++)
添加(newtextblock(){Background=brusks.Yellow});
this.KeyDown+=主窗口\u KeyDown;
this.KeyUp+=主窗口\u KeyUp;
CompositionTarget.Rendering+=CompositionTarget\u Rendering;
}
void main window_KeyUp(对象发送器,KeyEventArgs e)
{
this.Background=画笔.Red;
}
void main window_KeyDown(对象发送器,KeyEventArgs e)
{
this.Background=brushs.Green;
}
void CompositionTarget_呈现(对象发送方,事件参数e)
{
foreach(root2.childs中的var child)
((TextBlock)child.Text=DateTime.Now.millis秒.ToString();
}
}

根据您的机器性能,更改2000以增加文本框的数量。在一定数量下,CompositionTarget_呈现触发器比KeyUp或KeyDown多。当按下一个键以查看边框的颜色变化时,它是非常明显的:按下该键,然后多次触发构图渲染,然后触发keydown事件,边框变为红色。

为了回答我的第二个问题,我找到了另一种方法来执行全局键盘挂钩


它的
Keyup
Keydown
事件响应无延迟,事件在CPU和图形负载很重的情况下进行。

如果我设置一个新项目,创建一个新表单并添加一个循环来创建50000个文本框并钩住主windows Keydown事件,我实际上根本没有注意到任何延迟。这些控件是嵌套的吗?没有嵌套的控件。是否要尝试在CompositionTarget_呈现事件中添加一些代码,以便在文本框中添加一些随机文本?我认为这将反映我的情况。50000个文本框太多了,我想。不知道把文本框放在一个虚拟化容器中,比如列表框,是否会有帮助?不幸的是,没有,我认为这与我不知道的事情有关,比如事件优先级或其他什么。在我的机器上,这个过程会占用大量cpu,难怪所有事情都会延迟。i、 e.关键事件不会延迟,机器上的所有内容都会变慢