EditingControl.TextChanged イベントの発生回数を制御する方法

文書番号 : 28416     文書種別 : 使用方法     最終更新日 : 2010/01/15
文書を印刷する
対象製品
MultiRow for Windows Forms 5.0J
詳細
DataGridViewコントロールとGcMultiRowコントロールでそれぞれセル編集コントロール(EditingControl)のTextChangedイベントを実装したとき、イベントの発生回数が異なります。これは、GcMultiRowコントロールがセル移動時にセル編集コントロールの編集開始位置が常に適正になるように、内部で一度EditingControl.Textプロパティを初期化していることによるものです。

次のコードは、この現象を確認します。

[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);
  }
}


次期バージョン MultiRow for Windows Forms 6.0J では、EditingControl.TextChangedイベントの代わりにGcMultiRow.CellEditedFormattedValueChangedイベントを使用することもできます。

この文書は、以前は次のFAQ IDで公開されていました : 12771