2013-04-08 23 views
7

Tôi đang sử dụng các sự kiện KeyUpKeyDown trên Cửa sổ WPF.Tại sao các sự kiện KeyUp và KeyDown trở nên chậm hơn?

Tôi cũng có nhiều cuộc gọi trong sự kiện CompositionTarget_Rendering của cửa sổ này tạo UIElements và tạo hoạt ảnh cho chúng. Này được thực hiện bởi lớp cơ bên dưới:

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); 
} 

tôi đã nhận thấy rằng càng có nhiều các yếu tố tôi có, càng chậm được KeyUpKeyDown sự kiện.

Khi tôi có khoảng 1000 Giao diện người dùng trong Cửa sổ chính, mã của cả control_KeyDown và control_KeyUp được thực thi khoảng nửa giây sau khi tôi nhấn hoặc nhả phím.

Điều này sẽ không làm tôi ngạc nhiên nếu hoạt ảnh bên trong cửa sổ cũng bị lag, nhưng không phải như vậy.

  • Các khung hình là vào khoảng 55 fps
  • Các hình ảnh động trơn tru vẫn
  • Các tính toán trong trường hợp CompositionTarget_Rendering không kéo dài hơn 20 mili giây.

Dường như chỉ có sự kiện bỏ phiếu bàn phím đang gặp phải tình trạng nặng.

Câu hỏi của tôi là:

  • sự kỳ diệu đằng sau xử lý bàn phím trong WPF là gì: tại sao là nó nhận lag trong điều kiện nặng trong khi không phải là quá trình vẽ?
  • Làm cách nào để xử lý đầu vào bàn phím tốt hơn và tránh điều này?

EDIT:

Tôi đã viết một mẫu lấy cảm hứng từ Andy nhận xét. Bạn có thể sao chép dán nó vào Windows chính của một ứng dụng WPF mới. Nó thay đổi màu sắc của cửa sổ khi một phím là xuống hoặc lên, và nó điền vào càng nhiều hộp văn bản càng tốt trong sự kiện 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(); 
    } 
} 

Tùy thuộc vào hiệu suất máy của bạn, thay đổi 2000 để tăng số lượng hộp văn bản. Tại một số tiền nhất định, có nhiều trình kích hoạt CompositionTarget_Rendering hơn KeyUp hoặc KeyDown. Nó là khá hiển nhiên khi một phím được nhấn để xem sự thay đổi màu sắc của biên giới: phím là xuống, sau đó các Composition_Rendering được kích hoạt một thời gian, sau đó sự kiện keydown được kích hoạt và biên giới chuyển sang màu đỏ.

+0

Nếu tôi thiết lập dự án mới, hãy tạo biểu mẫu mới và thêm vòng lặp để tạo 50.000 hộp văn bản và móc cửa sổ chính Sự kiện KeyDown, tôi thực sự không nhận thấy bất kỳ sự chậm trễ nào. Những điều khiển lồng nhau này? – Andy

+1

Không có điều khiển nào được lồng vào nhau.Bạn có muốn vui lòng thử đặt một số mã bên trong sự kiện CompositionTarget_Rendering để đặt một số văn bản ngẫu nhiên bên trong TextBox không? Tôi nghĩ nó sẽ phản ánh những điều kiện tôi có. 50000 hộp văn bản là rất nhiều, suy nghĩ. – Larry

+0

Tự hỏi liệu việc đặt Hộp văn bản vào vùng chứa ảo hóa như ListBox có giúp ích gì không? – Paparazzi

Trả lời

0

Để trả lời câu hỏi thứ hai của tôi, tôi đã tìm thấy một cách thay thế để làm một cái móc toàn cầu bàn phím: Using global keyboard hook (WH_KEYBOARD_LL) in WPF/C#

KeyupKeydown của sự kiện phản ứng mà không lag, sự kiện dưới CPU nặng và tải đồ họa.

Các vấn đề liên quan