winforms 取消订阅DatagridView中textbox的事件处理程序并重新添加

bbuxkriu  于 2023-06-06  发布在  其他
关注(0)|答案(1)|浏览(143)

我正在处理一个我被击中的问题,我在Events calling twice error on DataGridView上问过这个问题。现在,一位受人尊敬的成员建议我在再次添加之前删除datagridview中文本框的eventhandlers。但我不能得到的概念,因为我只是一个初学者。有人能建议我怎么做吗?实际的问题是customdatagridview的OnEnter事件被触发了两次。

public partial class CustomControl1 : DataGridView
{
    public CustomControl1()
    {
        this.KeyDown += new 
        KeyEventHandler(CustomDataGridView_KeyDown);
       
        InitializeComponent();
    }

    protected override void OnEnter(EventArgs e)
    {
        base.OnEnter(e);
        this.CurrentCell = this.Rows[0].Cells[0];
        this.BeginEdit(true);
    }

现在是我使用的表单。

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();         
    }

    private void Form2_Load(object sender, EventArgs e)
    {
        customControl11.Focus();
    }
       
    private void customControl11_EditingControlShowing(object sender, 
      DataGridViewEditingControlShowingEventArgs e)
    {            
        if (customControl11.CurrentCell.ColumnIndex == 0) 
        {
           TextBox textBox = e.Control as TextBox;
            if (textBox != null)
            {
                textBox.TextChanged += TextBox_TextChanged; 
                textBox.KeyDown += TextBox_KeyDown; 
                textBox.Enter += TextBox_Enter;                 
            }
        }
    }
4ktjp1zp

4ktjp1zp1#

如上所述,您应该在添加新事件之前取消订阅。您应该认为事件已经定义了某种方法列表,这些方法在事件发生时被调用。因此,当您继续订阅事件时,列表将增长。这可能会导致您的函数将多次触发(而不仅仅是两次)。
要取消订阅事件,只需将+=(代表订阅事件)更改为-=(代表取消订阅)。
你也可以检查你的委托(事件方法)是否已经被添加。
建议通过检查来完成,这在另一张票中已经描述过:How to determine if an event is already subscribed
为了帮助您理解这个问题,我为多个方法调用编写了一个最简单的修复:

public partial class Form2 : Form
{
public Form2()
{
    InitializeComponent();         
}

private void Form2_Load(object sender, EventArgs e)
{
  customControl11.Focus();
  }
   private void customControl11_EditingControlShowing(object sender, 
  Data

GridViewEditingControlShowingEventArgs e)
{            
  if (customControl11.CurrentCell.ColumnIndex == 0) 
  {
   TextBox textBox = e.Control as TextBox;
    if (textBox != null)
    {
        textBox.TextChanged -= TextBox_TextChanged; 
        textBox.KeyDown -= TextBox_KeyDown; 
        textBox.Enter -= TextBox_Enter; 
        textBox.TextChanged += TextBox_TextChanged; 
        textBox.KeyDown += TextBox_KeyDown; 
        textBox.Enter += TextBox_Enter;                 

    }
  }
}

现在,您的事件应该只执行一次委托。
PS.在事件EditingControlShowing中这样做是一个非常糟糕的主意,因为它将在每次编辑控件即将显示时执行。

相关问题