2013-04-08 82 views
7

我在WPF窗口上使用KeyUpKeyDown事件。为什么KeyUp和KeyDown事件变慢?

我还在此窗口的CompositionTarget_Rendering事件中创建了许多调用,它们创建了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); 
} 

我注意到元素的多我越慢得KeyUpKeyDown事件。

当我在主窗口中有大约1000个UI元素时,control_KeyDown和control_KeyUp的代码在我敲击或释放键约半秒钟后执行。

这并不会让我感到意外,如果窗口内的动画也是滞后的,但事实并非如此。

  • 帧率是在约55 fps的
  • 动画保持光滑
  • CompositionTarget_Rendering事件的计算持续时间不超过20毫秒。

似乎只有键盘事件轮询正受到恶劣条件的影响。

我的问题是:

  • 什么是落后于WPF键盘操作的魔力:它为什么重条件,而不是渲染处理下得到laggy?
  • 如何处理更好的键盘输入并避免这种情况?

编辑:

我写安迪评论启发的样本。您可以将其粘贴到新的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以增加文本框的数量。在某种程度上,比KeyUp或KeyDown有更多的CompositionTarget_Rendering触发器。当按下键看到边框的颜色变化时,它是非常明显的:按键关闭,然后Composition_Rendering被触发几次,然后触发keydown事件并且边框变为红色。

+0

如果我设置一个新项目,创建一个新窗体并添加一个循环来创建50,000个文本框并挂钩主窗口的KeyDown事件,实际上我根本没有注意到任何延迟。这些嵌套控件? – Andy 2013-04-08 15:11:20

+1

没有控件嵌套。您是否想尝试在CompositionTarget_Rendering事件中放置一些代码,以将一些随机文本放入TextBox中?我认为这将反映我的情况。想到50000个文本框是很多的。 – Larry 2013-04-08 15:14:33

+0

不知道如果把文本框在一个虚拟容器像一个列表框将帮助? – Paparazzi 2013-04-08 17:50:16

回答

相关问题