none
dataGridViewで特定の列のKeyDownイベントを記述する方法 RRS feed

  • 質問

  • VS2003では次のようにイベントハンドラを設定していたのですが、

       private void Form1_Load(object sender, EventArgs e)
            {
                this.dataGridTextBoxColumn1.TextBox.KeyDown
                           += new KeyEventHandler(this.Name_KeyDown);
            }

    VS2005ではどのように記述するとよいのでしょうか?

    お教え願います。

     

    2008年6月6日 21:59

回答

  • 提示もらったソースのように処理を行う場合はKeyDownイベントではなくCellEndEditで処理を書いたほうがうまくいきます。

    CellEndEditは編集完了時に呼び出されるので確実です。

     

    Code Snippet

            private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
            {
                string tmpStr;

                IntPtr himc = ImmGetContext(dataGridView1.Handle);
                if(himc == IntPtr.Zero) return;
                if (e.ColumnIndex == 0)
                {
                    try
                    {
                        int dwSize = ImmGetCompositionString(himc, GCS_RESURTREADSTR, null, 0);
                        StringBuilder lpBuf = new StringBuilder(dwSize);

                        ImmGetCompositionString(himc, GCS_RESURTREADSTR, lpBuf, dwSize);
                        lpBuf.Length = dwSize;
                        tmpStr = lpBuf.ToString();
                        Furigana += tmpStr;
                        dataGridView1[e.ColumnIndex + 1, e.RowIndex].Value = Furigana;
                        Furigana = "";
                    }
                    finally
                    {
                        ImmReleaseContext(dataGridView1.Handle, himc);
                    }
                }
            }
        }

     

     

    振り仮名を取得する方法が勉強になりました。
    2008年6月7日 10:48

すべての返信

  • ヘッダ列ではなく特定列のTextセルのKeyDownイベントを受け取りたいという認識でよろしいですか?

     

    私が以前行ったのはDataGridViewのEditingControlShowingイベントで編集用のコントロールにKeyDownイベントハンドラを登録する方法です(リンク参照)。

    http://msdn.microsoft.com/ja-jp/library/system.windows.forms.datagridview.editingcontrolshowing.aspx

     

    具体的には次のようにプログラムしました。編集しているセルはDataGridViewTextBoxCellと仮定しています。

    Code Snippet

     

            private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                DataGridViewTextBoxEditingControl ctr = dataGridView1.EditingControl as DataGridViewTextBoxEditingControl;
                ctr.KeyDown -= new KeyEventHandler(ctr_KeyDown);
                ctr.KeyDown += new KeyEventHandler(ctr_KeyDown);
            }

     

     

    イベント引数でどの列が編集状態になっているのか確認できるので少し修正すれば特定列のセルのKeyDownイベントを処理できるようになると思います。

     

    もしかしてもっと上手い方法があるかもしれませんが。ご参考までに。

    2008年6月7日 7:13
  • handcraftさん、ありがとうございます。

     handcraft さんからの引用

    ヘッダ列ではなく特定列のTextセルのKeyDownイベントを受け取りたいという認識でよろしいですか?

    はい、そのとおりです。

     handcraft さんからの引用

    イベント引数でどの列が編集状態になっているのか確認できるので少し修正すれば特定列のセルのKeyDownイベントを処理できるようになると思います。

    0列のKeyDownイベントを処理したいのですが、いつまでも初心者の域を脱することができない私には具体的に確かめる方策がなくお手上げの状態です。

    ----------------------------------------------------------------------------------------------------------------------------

    今私がしたいことは、VS2003の「DataGridで入力した氏名のセルの右隣に”フリガナ”を自動入力する」プログラムをVS2005で書き換えることです。

    VS2003ではうまく動作していたのですが、お尋ねした

       this.dataGridTextBoxColumn1.TextBox.KeyDown
                            += new KeyEventHandler(this.Name_KeyPress);

    の部分をVS2005ではどうかくのかがわからず困っているわけです。vs2003では

       this.dataGridTextBoxColumn1.TextBox.KeyDown
               this.dataGridTextBoxColumn3.TextBox.KeyPress
               this.dataGridTextBoxColumn4.TextBox.KeyDown

    などと個別に個々の列のイベントハンドラを定義できたのですが、VS2005ではこのような定義はできないようですね。

     

    それで下のコードように、dataGridView1_KeyDownで代替させてみたのですが、予期しない動作になってしまいました。

       ------------------------------------------------------------------------

               | 大山   |     |     |     |

       ------------------------------------------------------------------------

               ”大山”と入力してEnterキーを続けて2回押すと、下のようにふりがなが表示されます。

       ------------------------------------------------------------------------

               | 大山   |     |     |     |

       ------------------------------------------------------------------------

               |      |オオヤマ   |     |     |

       ------------------------------------------------------------------------

              次に”中森”と入力して上と同様にキーを押しますと

       ------------------------------------------------------------------------

               | 大山   |     |     |     |

       ------------------------------------------------------------------------

               | 中森   |オオヤマ   |ナカモリ   |     |

       ------------------------------------------------------------------------

    というふうに、これ以降は常にふりがなは1行目に表示されてしまいます。

    フリガナを表示するときのセルの指定に問題がありそうです。

    これについてアドバイスをいただけますとうれしいのですが。

    よろしくおねがいします。

    Code Snippet

    using System;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    namespace DG_Furigana
    {
        public partial class Form1 : Form
        {
            public string Furigana = "";
            const int GCS_RESURTREADSTR = 0x0200;

            [DllImport("imm32.dll")]
            static extern IntPtr ImmGetContext(IntPtr hWnd);
            [DllImport("imm32.dll")]
            static extern int ImmGetCompositionString(
                IntPtr hiMC, int dwIndex, StringBuilder lpBuf, int dwBufLen);
            [DllImport("imm32.dll")]
            static extern bool ImmReleaseContext(IntPtr hWnd, IntPtr hiMC);

            //KeyPressで入力された数値
            //public string TempChr = "";
            //public int Cnt = 0;
            //public bool UPdata = false;

            public Form1()
            {
                InitializeComponent();
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                //this.dataGridTextBoxColumn1.TextBox.KeyDown
                           // += new KeyEventHandler(this.SeitoName_KeyPress);
            }


            private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
            {
                string tmpStr;
                int iCol = dataGridView1.CurrentCell.ColumnIndex;
                int iRow = dataGridView1.CurrentCell.RowIndex;
                IntPtr himc = ImmGetContext(dataGridView1.Handle);
                if (iCol == 0)
                {
                    if (himc == IntPtr.Zero
                        || e.KeyCode == Keys.Back || e.KeyCode == Keys.Left || e.KeyCode == Keys.Shift)
                    {
                        return;
                    }
                    try
                    {
                        int dwSize = ImmGetCompositionString(himc, GCS_RESURTREADSTR, null, 0);
                        StringBuilder lpBuf = new StringBuilder(dwSize);

                        ImmGetCompositionString(himc, GCS_RESURTREADSTR, lpBuf, dwSize);
                        lpBuf.Length = dwSize;
                        tmpStr = lpBuf.ToString();
                        Furigana += tmpStr;
                        dataGridView1[iRow, iCol + 1].Value = Furigana;
                        Furigana = "";
                    }
                    finally
                    {
                        ImmReleaseContext(dataGridView1.Handle, himc);
                    }
                }
            }

     

     

     


                          

     

     

     

    2008年6月7日 9:54
  • 0列目に漢字,1列目の同行に振り仮名が表示されればよいのですね。提示してもらったソースを1行修正しました。

    KeyDownイベントは編集中のセルに登録した場合は動くようです。

     

     

    Code Snippet

            private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
            {
                DataGridViewTextBoxEditingControl ctr = dataGridView1.EditingControl as DataGridViewTextBoxEditingControl;
                ctr.KeyDown -= new KeyEventHandler(ctr_KeyDown);
                ctr.KeyDown += new KeyEventHandler(ctr_KeyDown);
            }

            void ctr_KeyDown(object sender, KeyEventArgs e)
            {
                string tmpStr;
               int iCol = dataGridView1.CurrentCell.ColumnIndex;
                int iRow = dataGridView1.CurrentCell.RowIndex;
                IntPtr himc = ImmGetContext(dataGridView1.Handle);
                if (iCol == 0)
                {
                    if (himc == IntPtr.Zero
                        || e.KeyCode == Keys.Back || e.KeyCode == Keys.Left || e.KeyCode == Keys.Shift)
                    {
                        return;
                    }
                    try
                    {
                        int dwSize = ImmGetCompositionString(himc, GCS_RESURTREADSTR, null, 0);
                        StringBuilder lpBuf = new StringBuilder(dwSize);

                        ImmGetCompositionString(himc, GCS_RESURTREADSTR, lpBuf, dwSize);
                        lpBuf.Length = dwSize;
                        tmpStr = lpBuf.ToString();
                        Furigana += tmpStr;
                        dataGridView1[iCol + 1, iRow].Value = Furigana;
                        Furigana = "";
                    }
                    finally
                    {
                        ImmReleaseContext(dataGridView1.Handle, himc);
                    }
                }
            }

     

     

    提示してもらったソースだと矢印を押してセルを移動すると振り仮名がいろんな行に設定されるようです。すこし見てみます。

    2008年6月7日 10:23
  • 提示もらったソースのように処理を行う場合はKeyDownイベントではなくCellEndEditで処理を書いたほうがうまくいきます。

    CellEndEditは編集完了時に呼び出されるので確実です。

     

    Code Snippet

            private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
            {
                string tmpStr;

                IntPtr himc = ImmGetContext(dataGridView1.Handle);
                if(himc == IntPtr.Zero) return;
                if (e.ColumnIndex == 0)
                {
                    try
                    {
                        int dwSize = ImmGetCompositionString(himc, GCS_RESURTREADSTR, null, 0);
                        StringBuilder lpBuf = new StringBuilder(dwSize);

                        ImmGetCompositionString(himc, GCS_RESURTREADSTR, lpBuf, dwSize);
                        lpBuf.Length = dwSize;
                        tmpStr = lpBuf.ToString();
                        Furigana += tmpStr;
                        dataGridView1[e.ColumnIndex + 1, e.RowIndex].Value = Furigana;
                        Furigana = "";
                    }
                    finally
                    {
                        ImmReleaseContext(dataGridView1.Handle, himc);
                    }
                }
            }
        }

     

     

    振り仮名を取得する方法が勉強になりました。
    2008年6月7日 10:48
  • handcraftさんには素早く対応していただき、とても感謝しています。ありがとうございました。

     

     

     

    2008年6月7日 11:35