我在 WPF 窗口上使用KeyUp
andKeyDown
事件。
我在这个窗口的 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 个 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事件,边框变为红色。