Получение значения из динамического NumericUpDown от Sender C#

Я столкнулся с довольно раздражающей проблемой.

У меня есть эти глобальные переменные (для сохранения имени и т. Д.)

List<object> NumeriekVakken = new List<object>();
        List<decimal> bedragenLijst = new List<decimal>();
        List<string> namenlijstVanNumericFields = new List<string>();
        List<string> namenLijst = new List<string>();

После этого у меня есть функция, которая делает NumericUpDowns, в зависимости от количества записей в БД. Функция выглядит так:

private void InitializeComponentControlArrayKnoppenTextboxenEnLabels()
        {

    foreach (DataRow dr in blCategorie.getAlleCategorieenMetLimieten())
            {
        double limiet = (double) dr.Field<double>("maximumBedrag");
                NumericUpDown numeriekVak = new NumericUpDown();
                numeriekVak.Name = "numeriekvak" + i;
                numeriekVak.Width = 100;
                numeriekVak.Maximum = 30000;
                numeriekVak.Minimum = 0;
                numeriekVak.Increment = 10;
                numeriekVak.Value = Convert.ToDecimal(limiet);
                numeriekVak.Location = new Point(250, beginhoogte + verhogenMet);
                this.Controls.Add(numeriekVak);

        NumeriekVakken.Add(numeriekVak);
                bedragenLijst.Add(numeriekVak.Value);
                namenlijstVanNumericFields.Add(numeriekVak.Name);
                namenLijst.Add(categorie);

        //to make unique names for my Numerics etc.
        i++;
                counter++;

                //click event aanmaken
                button.Click += new EventHandler(buttonWijzig_Click);
            }
}

И в конце я хочу обновить запись всякий раз, когда пользователь изменяет numericUpDown (нажав на numericupdown или изменив числа)

private void buttonWijzig_Click(object sender, EventArgs e)
        {
            Button knop = (Button)sender;
            NumericUpDown numeriekvak = (NumericUpDown)sender;

            for (int i = 0; i < counter; i++)
            {
                if (knop.Name == "knop" + i)
                {
                    int id = i, maximumBedrag = 0;

                    if (namenlijstVanNumericFields[i] == "numeriekvak" + i)
                    {
                        // update limit
                        DBManager.LimietRow limiet = new DBManager.LimietDataTable().NewLimietRow();
                        maximumBedrag = Convert.ToInt32(numeriekvak.Value);
                        blLimiet.updateLimiet(id, maximumBedrag);
                    }

                    labelBevestigingLimiet.Text = "Limiet " + namenLijst[i].ToString() + " is succesvol gewijzigd naar " + maximumBedrag + "€";

                    //stopping of loop if right button is found.
                    break;
                }
            }
        }

Но каждый раз, когда я запускаю это, я получаю ту же проблему.. "Не удается преобразовать объект из типа System.Windows.Forms.Button в тип System.Windows.Forms.NumericUpDown"

Как я могу это исправить и обновить запись в зависимости от нового номера, который указан в NumericUpDown? Я не могу заставить это работать, у меня есть чувство, что это имеет отношение к отправителю, который не работает хорошо..

Спасибо за помощь! Yenthe

3 ответа

Решение

Вы назначили обработчик события buttonWijzig_Click к кнопке управления.
Этот элемент управления не определен нигде в вашем коде выше. (Кстати, вы назначаете метод для одного и того же элемента управления для каждого цикла)

Я думаю, что вы хотите назначить свой обработчик событий для каждого NumericUpDown, созданного в цикле как

numeriekVak.Click += new EventHandler(buttonWijzig_Click);

Конечно, обработчик событий теперь получает элемент управления NumericUpDown в аргументе отправителя, а не кнопку, поэтому код обработчика событий должен быть соответствующим образом изменен.

private void buttonWijzig_Click(object sender, EventArgs e)
{
     NumericUpDown numeriekvak = (NumericUpDown)sender;
     int id = 0, maximumBedrag = 0;

     // The ID could be extracted from the control name starting at 11 position
     id = Convert.ToInt32(numeriekvak.Name.Substring(11));

     // update limit
     DBManager.LimietRow limiet = new DBManager.LimietDataTable().NewLimietRow();
     maximumBedrag = Convert.ToInt32(numeriekvak.Value);
     blLimiet.updateLimiet(id, maximumBedrag);

     // The control name is already available, no need to use the list to retrieve it
     labelBevestigingLimiet.Text = "Limiet " + numeriekVak.Name + " is succesvol gewijzigd naar " + maximumBedrag + "€";

}

Однако позвольте мне сказать, что для вашей заявленной цели:

И в конце я хочу обновить запись всякий раз, когда пользователь изменяет numericUpDown (нажав на numericupdown или изменив числа)

лучше использовать ValueChanged событие, потому что оно будет запущено также, когда пользователь изменяет значение вручную, а не кнопками вверх / вниз. Приведенный выше код также подойдет для события ValueChanged

РЕДАКТИРОВАТЬ Исходя из вашего комментария ниже, назначение обработчика события возвращается к кнопке (код для создания кнопки отсутствует, поэтому я предположил, что вы следовали тому же соглашению об именах, что и для вашего NumericUpDown), но не использовали список для отслеживания вашего NumericUpDown, я бы использовал Dictionary<int, NumericUpDown> где целое число - это идентификатор, необходимый для извлечения соответствующего NumericUpDown из имени кнопки.

В декларации изменить

Dictionary<int, NumericUpDown> NumeriekVakken = new Dictionary<int, NumericUpDown> ();

В инициализации внутри InitializeComponentControlArrayKnoppenTextboxenEnLabels менять

namenlijstVanNumericFields.Add(i, numeriekVak);

В коде нажатия кнопки

private void buttonWijzig_Click(object sender, EventArgs e)
{
     Button knop = sender as Button;
     int id = 0, maximumBedrag = 0;

     // The ID could be extracted from the control name starting at 4th position
     id = Convert.ToInt32(knop.Name.Substring(4));

     // The ID is the key to find the corresponding NUmericUpDown in the dictionary
     NumericUpDown numeriekvak = NumeriekVakken[id];

     // update limit
     DBManager.LimietRow limiet = new DBManager.LimietDataTable().NewLimietRow();
     maximumBedrag = Convert.ToInt32(numeriekvak.Value);
     blLimiet.updateLimiet(id, maximumBedrag);

     // The control name is already available, no need to use the list to retrieve it
     labelBevestigingLimiet.Text = "Limiet " + numeriekVak.Name + " is succesvol gewijzigd naar " + maximumBedrag + "€";

}

Проблема в том, что, поскольку ваше событие запускается кнопкой, вы не можете преобразовать отправителя в числовое обновление.

Я вижу, у вас есть только один button и это не объявлено в вашем коде. Я предполагаю, что это в форме, верно???

Вы хотели добавить это событие многократно к одной кнопке???

Или вы хотели добавить события to each NumericUpDown???

Если это второй вариант, вы должны добавить событие щелчка к каждому числовому обновлению. Смотрите эту строку в своем коде.

//click event aanmaken
button.Click += new EventHandler(buttonWijzig_Click);
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if(e.RowIndex >= 0) {
            DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex];

            iD_supplierNumericUpDown.Value = row.Cells["ID"].Selected(); // this is the problem
            nSupplierTextBox.Text = row.Cells["NSupplier"].Value.ToString();
            e_mailTextBox.Text = row.Cells["E_mailTextBox"].Value.ToString();
            phoneTextBox.Text = row.Cells["Phone"].Value.ToString();
        }
Другие вопросы по тегам