トップ回答者
DataGridの指定セルを入力不可に設定したい

質問
回答
すべての返信
-
DataGrid ではセル単位のスタイルは設定できませんから、列のイベントで特定の行の入力を弾くしかないように思います。
次の例は1列目の2行目のセルが編集されるときだけ、入力を弾きます。
private void Form1_Load(object sender, EventArgs e)
{
DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = "DataTable1";
DataGridTextBoxColumn textBoxColumn = new DataGridTextBoxColumn();
textBoxColumn.MappingName = "Column1";
textBoxColumn.TextBox.KeyPress += new KeyPressEventHandler(TextBox_KeyPress);
tableStyle.GridColumnStyles.Add(textBoxColumn);
dataGrid1.TableStyles.Add(tableStyle);
}
void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (dataGrid1.CurrentRowIndex == 1)
{
e.Handled = true;
}
}
-
基本的な考え方はにょりさんと同じなんですが、KeyPressの判断では貼り付けられると入力されてしまうので、根本的には、DataGridTextBoxColumnを継承したクラスで、Editをオーバーライドして、例えば、
protected override void Edit(CurrencyManager source, int rowNum,
Rectangle bounds, bool readOnly,
string instantText, bool cellIsVisible)
{
base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
if (rowNum == 1)
this.TextBox.Enabled = false;
else
this.TextBox.Enabled = true;
}
のようにしてしまえばいいんじゃないかと思います。 -
trapemiya さん、辛島さんありがとうございます。
次のコードで確認できました。KeyPress イベントを使う方法に比べて、入力不可が明示できて良いですね。
private void Form1_Load(object sender, EventArgs e)
{
DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = "DataTable1";
DataGridTextBoxColumnEx textBoxColumn = new DataGridTextBoxColumnEx();
textBoxColumn.MappingName = "Column1";
tableStyle.GridColumnStyles.Add(textBoxColumn);
dataGrid1.TableStyles.Add(tableStyle);
}
public class DataGridTextBoxColumnEx : DataGridTextBoxColumn
{
protected override void Edit(CurrencyManager source, int rowNum,
Rectangle bounds, bool readOnly,
string instantText, bool cellIsVisible)
{
if (rowNum == 1)
{
readOnly = true;
}
base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
}
}
trapemiya さんからの引用 KeyPressの判断では貼り付けられると入力されてしまうので
いえいえ、クリップボードからの入力でも KeyPress イベントは発生しますよ。
-
trapemiya さんからの引用 CTR+Vだとキーを押すことになるので発生しますが、マウスでメニューから貼り付けを選ぶと貼り付けられてしまうんです。
おっしゃる通りでした。確認が不十分で申し訳ございません・・・orz
kimcheenabe さんからの引用 もし、表示された行のAセルの値によって、BセルをReadOnlyにするかを動的に判断
したい場合はにょりさんの最初のご解答(列のイベントで特定の行の入力を弾く方法)で
いくしかないと思われますが、この認識でよろしいでしょうか。KeyPress イベントではなく、 Enter イベントと ReadOnly プロパティを使えばよいと気がつきました。
private void Form1_Load(object sender, EventArgs e)
{
DataGridTableStyle tableStyle = new DataGridTableStyle();
tableStyle.MappingName = "DataTable1";
DataGridTextBoxColumn textBoxColumn = new DataGridTextBoxColumn();
textBoxColumn.MappingName = "Column1";
textBoxColumn.TextBox.Enter += new EventHandler(TextBox_Enter);
tableStyle.GridColumnStyles.Add(textBoxColumn);
dataGrid1.TableStyles.Add(tableStyle);
}
void TextBox_Enter(object sender, EventArgs e)
{
if (((TextBox)sender).Text.StartsWith("123") == true)
{
((TextBox)sender).ReadOnly = true;
}
}
こんな感じでいかがでしょうか。値が 123 で始まっているときにセルが読み取り専用になります。コンテキストメニューも抑制されます。