EditingControl.TextChangedイベントの発生回数を制御する方法
対象製品
MultiRow for Windows Forms 10.0J
詳細
DataGridViewコントロールとGcMultiRowコントロールでそれぞれセル編集コントロール(EditingControl)のTextChangedイベントを実装したとき、イベントの発生回数が異なります。これは、GcMultiRowコントロールがセル移動時にセル編集コントロールの編集開始位置が常に適正になるように、内部で一度EditingControl.Textプロパティを初期化していることによるものです。
次のコードは、この現象を確認します。
[Visual Basic]
[C#]
この現象を回避し、DataGridViewと同じ回数だけEditingControl.TextChangedイベントを発生させるには、次のようにコードを書き換えます。
[Visual Basic]
[C#]
セルの移動時にEditingControl.TextChangedイベントを発生させず、ユーザーによる編集が行われた場合のみEditingControl.TextChangedイベントを発生させるには、次のように書き換えます。
[Visual Basic]
[C#]
EditingControl.TextChangedイベントの代わりにGcMultiRow.CellEditedFormattedValueChangedイベントを使用することもできます。
次のコードは、この現象を確認します。
[Visual Basic]
Imports GrapeCity.Win.MultiRow Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load DataGridView1.RowCount = 10 For i As Integer = 0 To DataGridView1.RowCount - 1 DataGridView1.Rows(i).Cells(0).Value = i Next Dim textBoxCell = New TextBoxCell() textBoxCell.Name = "textBoxCell" GcMultiRow1.Template = Template.CreateGridTemplate(New Cell() {textBoxCell}) GcMultiRow1.RowCount = 10 For i As Integer = 0 To GcMultiRow1.RowCount - 1 GcMultiRow1.SetValue(i, "textBoxCell", i) Next End Sub Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing If TypeOf DataGridView1.CurrentCell Is DataGridViewTextBoxCell Then Dim textBox As DataGridViewTextBoxEditingControl = TryCast(e.Control, DataGridViewTextBoxEditingControl) RemoveHandler textBox.TextChanged, AddressOf dataGridView_textBox_TextChanged AddHandler textBox.TextChanged, AddressOf dataGridView_textBox_TextChanged End If End Sub Private Sub dataGridView_textBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Dim textBox As DataGridViewTextBoxEditingControl = TryCast(sender, DataGridViewTextBoxEditingControl) Console.WriteLine("DataGridView_textBox_TextChanged:{0}", textBox.Text) End Sub Private Sub GcMultiRow1_EditingControlShowing(ByVal sender As System.Object, ByVal e As GrapeCity.Win.MultiRow.EditingControlShowingEventArgs) Handles GcMultiRow1.EditingControlShowing If TypeOf GcMultiRow1.CurrentCell Is TextBoxCell Then Dim textBox As TextBoxEditingControl = TryCast(e.Control, TextBoxEditingControl) RemoveHandler textBox.TextChanged, AddressOf gcMultiRow_textBox_TextChanged AddHandler textBox.TextChanged, AddressOf gcMultiRow_textBox_TextChanged End If End Sub Private Sub gcMultiRow_textBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Dim textBox As TextBoxEditingControl = TryCast(sender, TextBoxEditingControl) Console.WriteLine("GcMultiRow_textBox_TextChanged:{0}", textBox.Text) End Sub
[C#]
using GrapeCity.Win.MultiRow; private void Form1_Load(object sender, EventArgs e) { dataGridView1.RowCount = 10; for (int i = 0; i < dataGridView1.RowCount; i++) { dataGridView1.Rows[i].Cells[0].Value = i; } dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(dataGridView1_EditingControlShowing); TextBoxCell textBoxCell = new TextBoxCell(); textBoxCell.Name = "textBoxCell"; gcMultiRow1.Template = Template.CreateGridTemplate(new Cell[] { textBoxCell }); gcMultiRow1.RowCount = 10; for (int i = 0; i < gcMultiRow1.RowCount; i++) { gcMultiRow1.SetValue(i, "textBoxCell", i); } gcMultiRow1.EditingControlShowing += new EventHandler<GrapeCity.Win.MultiRow.EditingControlShowingEventArgs>(gcMultiRow1_EditingControlShowing); } private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (dataGridView1.CurrentCell is DataGridViewTextBoxCell) { DataGridViewTextBoxEditingControl textBox = e.Control as DataGridViewTextBoxEditingControl; textBox.TextChanged -= new EventHandler(dataGridView_textBox_TextChanged); textBox.TextChanged += new EventHandler(dataGridView_textBox_TextChanged); } } private void dataGridView_textBox_TextChanged(object sender, EventArgs e) { DataGridViewTextBoxEditingControl textBox = sender as DataGridViewTextBoxEditingControl; Console.WriteLine("DataGridView_textBox_TextChanged:{0}", textBox.Text); } private void gcMultiRow1_EditingControlShowing(object sender, EditingControlShowingEventArgs e) { if (gcMultiRow1.CurrentCell is TextBoxCell) { TextBoxEditingControl textBox = e.Control as TextBoxEditingControl; textBox.TextChanged -= new EventHandler(gcMultiRow_textBox_TextChanged); textBox.TextChanged += new EventHandler(gcMultiRow_textBox_TextChanged); } } private void gcMultiRow_textBox_TextChanged(object sender, EventArgs e) { TextBoxEditingControl textBox = sender as TextBoxEditingControl; Console.WriteLine("GcMultiRow_textBox_TextChanged:{0}", textBox.Text); }
この現象を回避し、DataGridViewと同じ回数だけEditingControl.TextChangedイベントを発生させるには、次のようにコードを書き換えます。
[Visual Basic]
Private editingControlRemoving As Boolean = False Private Sub GcMultiRow1_ControlRemoved(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles GcMultiRow1.ControlRemoved If e.Control Is GcMultiRow1.EditingPanel Then editingControlRemoving = True GcMultiRow1.EditingControl.Text = String.Empty editingControlRemoving = False End If End Sub Private Sub gcMultiRow_textBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Dim textBox As TextBoxEditingControl = TryCast(sender, TextBoxEditingControl) If Not editingControlRemoving Then Console.WriteLine("GcMultiRow_textBox_TextChanged:{0}", textBox.Text) End If End Sub
[C#]
private void Form1_Load(object sender, EventArgs e) { ... // 以下のコードを追加 gcMultiRow1.ControlRemoved += new ControlEventHandler(gcMultiRow1_ControlRemoved); } bool editingControlRemoving = false; private void gcMultiRow1_ControlRemoved(object sender, ControlEventArgs e) { if (e.Control == gcMultiRow1.EditingPanel) { editingControlRemoving = true; gcMultiRow1.EditingControl.Text = string.Empty; editingControlRemoving = false; } } private void gcMultiRow_textBox_TextChanged(object sender, EventArgs e) { TextBoxEditingControl textBox = sender as TextBoxEditingControl; if (!editingControlRemoving) { Console.WriteLine("gcMultiRow_textBox_TextChanged:{0}", textBox.Text); } }
セルの移動時にEditingControl.TextChangedイベントを発生させず、ユーザーによる編集が行われた場合のみEditingControl.TextChangedイベントを発生させるには、次のように書き換えます。
[Visual Basic]
Private _currentCellPosition As CellPosition = CellPosition.Empty Private Sub GcMultiRow1_EditingControlShowing(ByVal sender As System.Object, ByVal e As GrapeCity.Win.MultiRow.EditingControlShowingEventArgs) Handles GcMultiRow1.EditingControlShowing If TypeOf GcMultiRow1.CurrentCell Is TextBoxCell Then _currentCellPosition = GcMultiRow1.CurrentCellPosition Dim textBox As TextBoxEditingControl = TryCast(e.Control, TextBoxEditingControl) RemoveHandler textBox.TextChanged, AddressOf gcMultiRow_textBox_TextChanged AddHandler textBox.TextChanged, AddressOf gcMultiRow_textBox_TextChanged End If End Sub Private Sub gcMultiRow_textBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Dim textBox As TextBoxEditingControl = TryCast(sender, TextBoxEditingControl) If textBox.GcMultiRow.CurrentCellPosition.Equals(_currentCellPosition) Then Console.WriteLine("GcMultiRow_textBox_TextChanged:{0}", textBox.Text) End If End Sub
[C#]
private CellPosition _currentCellPosition = CellPosition.Empty; private void gcMultiRow1_EditingControlShowing(object sender, EditingControlShowingEventArgs e) { if (gcMultiRow1.CurrentCell is TextBoxCell) { _currentCellPosition = gcMultiRow1.CurrentCellPosition; TextBoxEditingControl textBox = e.Control as TextBoxEditingControl; textBox.TextChanged -= new EventHandler(gcMultiRow_textBox_TextChanged); textBox.TextChanged += new EventHandler(gcMultiRow_textBox_TextChanged); } } private void gcMultiRow_textBox_TextChanged(object sender, EventArgs e) { TextBoxEditingControl textBox = sender as TextBoxEditingControl; if (textBox.GcMultiRow.CurrentCellPosition.Equals(_currentCellPosition)) { Console.WriteLine("gcMultiRow_textBox_TextChanged:{0}", textBox.Text); } }
EditingControl.TextChangedイベントの代わりにGcMultiRow.CellEditedFormattedValueChangedイベントを使用することもできます。