Member 9646334 Ответов: 2

Событие Leave вызывается более одного раза в C#


У меня есть следующий код

public void panel_item_collections_Click(object sender, EventArgs e)

        {



TextBox[] textbox_item_array = new TextBox[5];

            item_textbox.Add(textbox_item_array);

            textbox_item_array[0] =

new TextBox();

            textbox_item_array[0].Width = label_item_code.Width;

            textbox_item_array[0].Height = 26;

            textbox_item_array[0].Font = print_font_default;

            textbox_item_array[0].Location =

new Point(label_item_code.Location.X, 45 + (20 * row_count));

            textbox_item_array[0].Name =

string.Concat("item_code", row_count.ToString());

            panel_item_collections.Controls.Add(textbox_item_array[0]);

            textbox_item_array[0].Leave +=

new EventHandler(dynamic_text_item_code_Leave);

            textbox_item_array[0].KeyDown +=

new KeyEventHandler(bill_new_Form_KeyPress);

            textbox_item_array[0].DoubleClick +=

new EventHandler(bill_new_Form_DoubleClick);

            textbox_item_array[1] =

new TextBox();

            textbox_item_array[1].Width = label_item_descrition.Width;

            textbox_item_array[1].Font = textbox_item_array[0].Font;

            textbox_item_array[1].Location =

new Point(label_item_descrition.Location.X, textbox_item_array[0].Location.Y);

            textbox_item_array[1].Name =

string.Concat("item_description", row_count.ToString());

            panel_item_collections.Controls.Add(textbox_item_array[1]);

            textbox_item_array[2] =

new TextBox();

            textbox_item_array[2].Width = label_item_price.Width;

            textbox_item_array[2].Font = textbox_item_array[0].Font;

            textbox_item_array[2].Location =

new Point(label_item_price.Location.X, textbox_item_array[0].Location.Y);

            textbox_item_array[2].Name =

string.Concat("item_price", row_count.ToString());

            panel_item_collections.Controls.Add(textbox_item_array[2]);

            textbox_item_array[3] =

new TextBox();

            textbox_item_array[3].Width = label_item_quantity.Width;

            textbox_item_array[3].Font = textbox_item_array[0].Font;

            textbox_item_array[3].Location =

new Point(label_item_quantity.Location.X, textbox_item_array[0].Location.Y);

            textbox_item_array[3].Name =

string.Concat("item_quantity", row_count.ToString());

            panel_item_collections.Controls.Add(textbox_item_array[3]);

            textbox_item_array[4] =

new TextBox();

            textbox_item_array[4].Width = label_item_total.Width;

            textbox_item_array[4].Font = textbox_item_array[0].Font;

            textbox_item_array[4].Location =

new Point(label_item_total.Location.X, textbox_item_array[0].Location.Y);

            textbox_item_array[4].Name =

string.Concat("item_total", row_count.ToString());

            panel_item_collections.Controls.Add(textbox_item_array[4]);

            row_count++;

        }



void dynamic_text_item_code_Leave(object sender, EventArgs e)
{
    //MessageBox.Show(((Control)sender).Name.Substring(((Control)sender).Name.Length - 1, 1));
    int i;
    string name_textbox = ((Control)sender).Name;
    i = System.Convert.ToInt32(name_textbox.Substring(name_textbox.Length - 1, 1));
    //MessageBox.Show(i.ToString());
    //i--;
    TextBox[] textbox_item_array = new TextBox[5];
    textbox_item_array = (TextBox[])(item_textbox[i]);
    double item_total;
    Item item = new Item();
    //textbox_item_array[0].Leave -= dynamic_text_item_code_Leave;
    if (long.TryParse(textbox_item_array[0].Text, out item.item_code) == true)
    {
        if (item.get_item() == 0)
        {
            textbox_item_array[1].Text = item.item_details;
            textbox_item_array[2].Text = item.sell_price.ToString();
            textbox_item_array[3].Text = "1";
            item_total = System.Convert.ToInt32(textbox_item_array[3].Text) * item.sell_price;
            textbox_item_array[4].Text = item_total.ToString();
        }
    }
    else
    {
        //TextBox[] textbox_item_array = new TextBox[5];
        textbox_item_array = (TextBox[])(item_textbox[item_textbox.Count - 1]);
        panel_item_collections.Controls.Remove(textbox_item_array[0]);
        //textbox_item_array[0].Leave -= dynamic_text_item_code_Leave;
        panel_item_collections.Controls.Remove(textbox_item_array[1]);
        panel_item_collections.Controls.Remove(textbox_item_array[2]);
        panel_item_collections.Controls.Remove(textbox_item_array[3]);
        panel_item_collections.Controls.Remove(textbox_item_array[4]);
        item_textbox.RemoveAt((item_textbox.Count - 1));
        //MessageBox.Show("Deleted");
        //textbox_item_array[0].Leave -= dynamic_text_item_code_Leave;
        //MessageBox.Show(item_textbox.Count.ToString());
        row_count--;
    }
}


Итак, проблема заключается в следующем:
Если пользователь оставит текстовое поле пустым, строка будет удалена. Странная проблема заключается в следующем:
Если нажать клавишу tab, то обработчик события leave будет выполнен дважды. Это означает, что он будет пытаться удалить одно и то же текстовое поле дважды, и это создаст проблему. Может ли кто-нибудь помочь мне, как избежать этого двойного вызова?

Спасибо

ZurdoDev

Как выглядит стек вызовов? Поставьте точку останова и посмотрите, будет ли стек вызовов указывать, почему он был вызван?

Member 9646334

Я поставил точку останова, но она не была упомянута. Пожалуйста помогите как я могу это сделать

Member 9646334

Я попытался поставить точку разрыва, и это было просто событие перед ним.

Alexander Dymshyts

Вы пытались поставить e.Handled = true в конце вашего мероприятия?

Member 9646334

Он не поддерживается. e.Handled не поддерживается.

Sergey Alexandrovich Kryukov

Посмотрите на окно отладки "стек вызовов".
—СА

Member 9646334

Теперь я точно расскажу, как это делается:
dynamic_text_item_code_Leave недействительным(объект отправителя, EventArgs в электронной)
{
//MessageBox.Показать(((контроля)отправителя).Имя.Подстрока(((контроля)отправителя).Имя.Длина - 1, 1));
int i;
строка name_textbox = ((Control)sender).Name;
i = система.Преобразовать.ToInt32(name_textbox.Substring(name_textbox.Длина - 1, 1));
//MessageBox.Показать(i.ToString());
//я--;
TextBox[] textbox_item_array = новое текстовое поле[5];
textbox_item_array = (текстовое поле[])(item_textbox[я]);
двойной item_total;
Элемент = новый товар();
если (долго.TryParse(textbox_item_array[0].Текст, деталь.item_code) == истина)
{
if (item.get_item() == 0)
{
textbox_item_array[1].Текст = товар.item_details;
textbox_item_array[2].Текст = товар.стоимость_при_продаже.Метод toString();
textbox_item_array[3].Текст = "1";
item_total = система.Преобразовать.ToInt32(textbox_item_array[3].Text) * item.sell_price;
textbox_item_array[4].Текст = item_total.Метод toString();
}
}
еще
{
//TextBox[] textbox_item_array = новое текстовое поле[5];
textbox_item_array = (текстовое поле[])(item_textbox[item_textbox.Количество - 1]);
panel_item_collections.Управления.Удалить(textbox_item_array[0]);

После этого он вызывает ту же функцию

dynamic_text_item_code_Leave недействительным(объект отправителя, EventArgs в электронной)
{
//MessageBox.Показать(((контроля)отправителя).Имя.Подстрока(((контроля)отправителя).Имя.Длина - 1, 1));
int i;
строка name_textbox = ((Control)sender).Name;
i = система.Преобразовать.ToInt32(name_textbox.Substring(name_textbox.Длина - 1, 1));
//MessageBox.Показать(i.ToString());
//я--;
TextBox[] textbox_item_array = новое текстовое поле[5];
textbox_item_array = (текстовое поле[])(item_textbox[я]);
двойной item_total;
Элемент = новый товар();
если (долго.TryParse(textbox_item_array[0].Текст, деталь.item_code) == истина)
{
if (item.get_item() == 0)
{
textbox_item_array[1].Текст = товар.item_details;
textbox_item_array[2].Текст = товар.стоимость_при_продаже.Метод toString();
textbox_item_array[3].Текст = "1";
item_total = система.Преобразовать.ToInt32(textbox_item_array[3].Text) * item.sell_price;
textbox_item_array[4].Текст = item_total.Метод toString();
}
}
еще
{
//TextBox[] textbox_item_array = новое текстовое поле[5];
textbox_item_array = (текстовое поле[])(item_textbox[item_textbox.Количество - 1]);
panel_item_collections.Управления.Удалить(textbox_item_array[0]);
panel_item_collections.Управления.Удалить(textbox_item_array[1]);
panel_item_collections.Управления.Удалить(textbox_item_array[2]);
panel_item_collections.Управления.Удалить(textbox_item_array[3]);
panel_item_collections.Управления.Удалить(textbox_item_array[4]);
item_textbox.RemoveAt((item_textbox.Количество - 1));
количество строк--;
}
}

Затем он продолжается здесь

panel_item_collections.Управления.Удалить(textbox_item_array[1]);
panel_item_collections.Управления.Удалить(textbox_item_array[2]);
panel_item_collections.Управления.Удалить(textbox_item_array[3]);
panel_item_collections.Управления.Удалить(textbox_item_array[4]);
item_textbox.RemoveAt((item_textbox.Количество - 1));
количество строк--;
}
}

Sergey Alexandrovich Kryukov

Пожалуйста, не помещайте код в комментарии, он не читается. Вместо этого используйте "улучшить вопрос": кликните сюда.
—СА

2 Ответов

Рейтинг:
2

adriancs

Это не очень хорошее решение, но может предотвратить дублирование одних и тех же событий.

bool leaveEventIsAlreadyCalled = false;

private void SomeMethod()
{
    if (!leaveEventIsAlreadyCalled)
    {
        leaveEventIsAlreadyCalled = true; 
        // do something
    }
    else
    {
        // do nothing
    }
}


Рейтинг:
0

W∴ Balboos, GHB

Я обнаружил, что с некоторыми обработчиками событий они могут вызываться рекурсивно (например, обработчик onchange, который изменяет элемент, вызвавший событие, снова вызовет себя).

Я заявляю что-то вроде:

статический bool beenHere = false;

Я использую его следующим образом

eventHandler() {

static bool beenHere = false;

 if(beenHere) {
   beenHere = false;
   return;
 }

 beenHere=true;
 /* event handler code */
 /* event handler code */
 /* event handler code */
 /* event handler code */
 return;

} // eventHandler()