2008-11-28 34 views
7

Tôi cần nhận các sự kiện nhấn phím trong khi chỉnh sửa ô trong điều khiển DataGridView.Cách nhận các sự kiện keypressed, keydown từ các ô dữ liệu DataGridView

Từ những gì tôi tìm thấy trên mạng, DataGridView được thiết kế để chuyển tất cả các sự kiện quan trọng từ DataGridView sang điều khiển chỉnh sửa ô và bạn không thể dễ dàng nhận các sự kiện này.

Tôi đã tìm thấy điều này piece of code để bẫy các sự kiện đó cho điều khiển DataGrid, nhưng điều đó không hoạt động đối với DataGridView.

Trả lời

2

Cuối cùng đã tìm ra. Có hai phần của trò chơi này - nhận các phím từ điều khiển chỉnh sửa ô và nhận khóa từ chính DataGridView. Đây là mã của tôi. Để sử dụng, bạn chỉ cần đăng ký sự kiện tùy chỉnh: keyPressHook.

class KeyPressAwareDataGridView : DataGridView 
{ 

    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     this.subscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     this.unsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    protected override bool ProcessDataGridViewKey(KeyEventArgs e) 
    { 
     bool procesedInternally = false; 

     if (this.keyPressHook != null) 
     { 
      this.keyPressHook(this, e); 
      procesedInternally = e.SuppressKeyPress; 
     } 

     if (procesedInternally) 
     { 
      return true; 
     } 
     else 
     { 
      return base.ProcessDataGridViewKey(e); 
     } 
    } 


    private void subscribeEvents(Control control) 
    { 
     control.KeyDown += new KeyEventHandler(this.control_KeyDown); 
     control.ControlAdded += new ControlEventHandler(this.control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(this.control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      this.subscribeEvents(innerControl); 
     } 
    } 

    private void unsubscribeEvents(Control control) 
    { 
     control.KeyDown -= new KeyEventHandler(this.control_KeyDown); 
     control.ControlAdded -= new ControlEventHandler(this.control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(this.control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      this.unsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     this.subscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     this.unsubscribeEvents(e.Control); 
    } 

    private void control_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (this.keyPressHook != null) 
     { 
      this.keyPressHook(this, e); 
     } 
    } 

    public event KeyEventHandler keyPressHook; 

} 
+0

bạn có thể cung cấp thêm thông tin về cách làm như vậy không? – eladyanai

0

bạn phải ghi đè các DataGridViewCell/DataGridViewTextBoxCell/otherTypes và xử lý các sự kiện quan trọng * trong lớp dẫn xuất.

1

Có lẽ không tốt bằng câu trả lời của Mladen Prajdic ở trên, nhưng có thể dễ dàng hơn một chút, tùy thuộc vào hoàn cảnh của bạn. Bạn có thể ghi đè lên phương thức ProcessCmdKey của biểu mẫu hoặc chính điều khiển, xử lý tổ hợp phím ở đó và kiểm tra ô hiện tại.

2

Hãy thử điều này:

class KeyPressAwareDataGridView : DataGridView 
{ 
    protected override void OnControlAdded(ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
     base.OnControlAdded(e); 
    } 

    protected override void OnControlRemoved(ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
     base.OnControlRemoved(e); 
    } 

    private void SubscribeEvents(Control control) 
    { 
     control.KeyPress += new KeyPressEventHandler(control_KeyPress); 
     control.ControlAdded += new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved += new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      SubscribeEvents(innerControl); 
     } 
    } 

    private void UnsubscribeEvents(Control control) 
    { 
     control.KeyPress -= new KeyPressEventHandler(control_KeyPress); 
     control.ControlAdded -= new ControlEventHandler(control_ControlAdded); 
     control.ControlRemoved -= new ControlEventHandler(control_ControlRemoved); 

     foreach (Control innerControl in control.Controls) 
     { 
      UnsubscribeEvents(innerControl); 
     } 
    } 

    private void control_ControlAdded(object sender, ControlEventArgs e) 
    { 
     SubscribeEvents(e.Control); 
    } 

    private void control_ControlRemoved(object sender, ControlEventArgs e) 
    { 
     UnsubscribeEvents(e.Control); 
    } 

    private void control_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     // Apply your logic here whether this is the key pressed event you need. 
     // (e.g. "if(SelectedCells != null)") 
     MessageBox.Show(e.KeyChar.ToString()); 
    } 
} 
0

Tôi tìm thấy một giải pháp phần bằng cách lắng nghe EditingControlShowing và thêm người nghe chìa khóa để kiểm soát từng chỉnh sửa mới.

Điều này cho phép tôi truy cập vào hầu hết các khóa, nhưng tôi vẫn không nhận được các phím mũi tên.

Tôi sẽ thử những gì Eren Aygunes đề xuất.

2

Hoặc, đối với những người sử dụng KHÔNG muốn tạo DataGridView của riêng mình cho những dịp như vậy; có phương thức này (trong C++): Nó sử dụng sự kiện EditingControlShowing của DataGridView.

private: System::Boolean fIsNonNumeric; 
private: static System::Windows::Forms::KeyEventHandler^ EventKeyDown = nullptr; 
private: static System::Windows::Forms::KeyPressEventHandler^ EventKeyPress = nullptr; 
private: System::Void dataGridView_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) 
{ 
    fIsNonNumeric= false; 

    // Determine whether the keystroke is a number from the top of the keyboard. 
    if (e->KeyCode < Keys::D0 || e->KeyCode > Keys::D9) 
    { 
    // Determine whether the keystroke is a number from the keypad. 
    if (e->KeyCode < Keys::NumPad0 || e->KeyCode > Keys::NumPad9) 
    { 
     // Determine whether the keystroke is a backspace. 
     if (e->KeyCode != Keys::Back) 
     { 
     // A non-numerical keystroke was pressed. 
     // Set the flag to true and evaluate in KeyPress event. 
     fIsNonNumeric = true; 
     } 
    } 
    } 
} 

private: System::Void dataGridView_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) 
{ 
    // Should we stop the character from being entered...? 
    if (fIsNonNumeric == true) 
    e->Handled = true; 
} 

private: System::Void dataGridView_Machines_EditingControlShowing(System::Object^ sender, System::Windows::Forms::DataGridViewEditingControlShowingEventArgs^ e) 
{ 
    if (nullptr == EventKeyDown) 
    EventKeyDown = (gcnew System::Windows::Forms::KeyEventHandler(this, &ProjectForm::dataGridView_KeyDown)); 

    if (nullptr == EventKeyPress) 
    EventKeyPress = (gcnew System::Windows::Forms::KeyPressEventHandler(this, &ProjectForm::dataGridView_KeyPress)); 

    e->Control->KeyDown -= EventKeyDown; 
    e->Control->KeyPress -= EventKeyPress; 

    e->Control->KeyDown += EventKeyDown; 
    e->Control->KeyPress += EventKeyPress; 
} 
Các vấn đề liên quan