7

コントロール内のセル編集中にキー押下イベントを受信する必要がありますDataGridView

私がネット上で見つけたものから、DataGridViewはすべての主要なイベントをセル編集コントロールに渡すように設計されてDataGridViewおり、これらのイベントを簡単に取得することはできません。

これらのイベントを制御のためにトラップするこのコードを見つけましDataGridたが、では機能しませんDataGridView

4

6 に答える 6

2

これを試して:

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());
    }
}
于 2008-11-29T21:49:27.947 に答える
2

やっとわかった。このパズルには、セル編集コントロールからキーを取得する部分と、DataGridView 自体からキーを取得する部分の 2 つがあります。これが私のコードです。これを使用するには、カスタム イベント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;

}
于 2008-12-02T14:27:29.943 に答える
2

または、そのような機会のために独自の DataGridView を作成したくない使用者のために。このメソッドがあります (C++ の場合): DataGridView の EditingControlShowing イベントを使用します。

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;
}
于 2008-12-27T22:18:29.413 に答える
1

上記のMladen Prajdicの回答ほど良くはないかもしれませんが、状況によっては少し簡単かもしれません。フォームまたはコントロール自体の ProcessCmdKey メソッドをオーバーライドし、そこでキーストロークを処理し、現在のセルをチェックすることができます。

于 2008-11-28T13:39:07.267 に答える
0

DataGridViewCell / DataGridViewTextBoxCell / otherTypesをオーバーライドし、派生クラスのkey*イベントを処理する必要があります。

于 2008-11-28T12:41:20.487 に答える
0

EditingControlShowing をリッスンし、新しい編集コントロールごとにキー リスナーを追加することで、部分的な解決策を見つけました。

これにより、ほとんどのキーにアクセスできるようになりますが、まだ矢印キーを取得できません。

Eren Aygunes が提案したことを試してみます。

于 2008-12-02T08:03:46.317 に答える