トップ回答者
dataGridViewで特定の列のKeyDownイベントを記述する方法

質問
回答
-
提示もらったソースのように処理を行う場合はKeyDownイベントではなくCellEndEditで処理を書いたほうがうまくいきます。
CellEndEditは編集完了時に呼び出されるので確実です。
Code Snippetprivate 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);
}
}
}
}
すべての返信
-
ヘッダ列ではなく特定列のTextセルのKeyDownイベントを受け取りたいという認識でよろしいですか?
私が以前行ったのはDataGridViewのEditingControlShowingイベントで編集用のコントロールにKeyDownイベントハンドラを登録する方法です(リンク参照)。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.datagridview.editingcontrolshowing.aspx
具体的には次のようにプログラムしました。編集しているセルはDataGridViewTextBoxCellと仮定しています。
Code Snippetprivate 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イベントを処理できるようになると思います。
もしかしてもっと上手い方法があるかもしれませんが。ご参考までに。
-
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 Snippetusing 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);
}
}
}
-
0列目に漢字,1列目の同行に振り仮名が表示されればよいのですね。提示してもらったソースを1行修正しました。
KeyDownイベントは編集中のセルに登録した場合は動くようです。
Code Snippetprivate 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);
}
}
}提示してもらったソースだと矢印を押してセルを移動すると振り仮名がいろんな行に設定されるようです。すこし見てみます。
-
提示もらったソースのように処理を行う場合はKeyDownイベントではなくCellEndEditで処理を書いたほうがうまくいきます。
CellEndEditは編集完了時に呼び出されるので確実です。
Code Snippetprivate 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);
}
}
}
}