【发布时间】:2013-04-08 14:21:33
【问题描述】:
我在 WPF 窗口上使用 KeyUp 和 KeyDown 事件。
我在此窗口的 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);
}
我注意到我拥有的元素越多,获得KeyUp 和KeyDown 事件的速度就越慢。
当我在主窗口中有大约 1000 个 UI 元素时,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事件,边框变为红色。
【问题讨论】:
-
如果我设置一个新项目,创建一个新表单并添加一个循环来创建 50,000 个文本框并挂钩主窗口 KeyDown 事件,我实际上根本没有注意到任何延迟。这些是嵌套控件吗?
-
没有嵌套控件。您想尝试在 CompositionTarget_Rendering 事件中放入一些代码,以便在 TextBox 中放入一些随机文本吗?我认为这将反映我所拥有的条件。想了想,50000 个文本框已经很多了。
-
想知道将文本框放在像 ListBox 这样的虚拟化容器中是否会有所帮助?
-
不幸的是不是,我认为这与我不知道的事情有关,例如事件中的优先级或其他什么。
-
在我的机器上,进程的cpu使用率很高,难怪一切都被延迟了。即不是关键事件被延迟,那台机器上的一切都会变慢
标签: wpf keyboard-events