Obtener el valor de un NumericUpDown dinámico por Sender c#

I've ran into quite an annoying problem.

I've got these global variables (for keeping the name etc)

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

Afterwards I have a function that makes NumericUpDowns, depending on the number of records in the db. The function looks like this:

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

And in the ending I want to update a record whenever the numericUpDown is changed by the user (by clicking on the numericupdown or changing the numbers)

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

But evertime I run this I get the same problem.. "Can't convert the object from the type System.Windows.Forms.Button to the type System.Windows.Forms.NumericUpDown"

How can I fix this and update the record depending on the new number thats filled in on the NumericUpDown? I can't get this working, I've got a feeling it has to do with the sender thats not working good..

Thanks for all the help! Yenthe

preguntado el 05 de mayo de 13 a las 19:05

3 Respuestas

You have assigned the event handler buttonWijzig_Click to a control button.
This control is not defined anywhere in your code above. (By the way, you assign the method at the same control for every loop)

I think you want to assign your event handler to every NumericUpDown created in the loop as

numeriekVak.Click += new EventHandler(buttonWijzig_Click);

Of course the event handler now receives a NumericUpDown control in the sender argument and not a button, so the code of the event handler should be changed accordingly

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 + "€";

}

However, let me say that for your stated purpose:

And in the ending I want to update a record whenever the numericUpDown is changed by the user (by clicking on the numericupdown or changing the numbers)

es mejor usar el ValueChanged event because this will be fired also when the user changes the value manually and not with up/down buttons. The code above will fit as well for the ValorCambiado evento

EDITAR Based on your comment below then the assignment of the event handler goes back to the button (there is no code to create the button, so I have assumed that you have followed the same naming convention as for yours NumericUpDown), but insted of using a list to keep track of your NumericUpDown I would use a Dictionary<int, NumericUpDown> where the integer is the id needed to retrieve the corresponding NumericUpDown from the button name.

In declaration change

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

In Initialization inside InitializeComponentControlArrayKnoppenTextboxenEnLabels cambiar

namenlijstVanNumericFields.Add(i, numeriekVak);

In button click code

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 + "€";

}

contestado el 06 de mayo de 13 a las 10:05

Woha this does what I want for 95%+! But how could I only trigger this when a button is clicked? The thing is I'd want it to update when the correct BUTTON is clicked, but not the NumericUpDown. That would save numerous of updates (which are a bit unneedded in my idea?) Thank you for this already Steve! :) - yenthe

So you have ONE button named (for example) Save and you want to update the limits of all of your NumericUpDown when your press this button? - Steve

In fact I have eight buttons and eight numericUpDowns, with all different values. And I want it to only update the corresponding NumericUpDown that matches to the clicked button! - yenthe

OK then I assume that your buttons have the same naming convetion of the NumericUpDown (I.E. "knop1" is related to "numeriekvak1"?). I need to ask because your code doesn't show how do you create dinamucally these buttons - Steve

Just so its easy for you to follow: int id = (int)dr.Field<int>("id"); Button button = new Button(); button.Name = "knop" + i; button.Width = 30; button.Height = 30; button.BackgroundImage = Properties.Resources.OKIcoon; button.Text = Convert.ToString(id); button.Location = new Point(380, (beginhoogte + verhogenMet) - 4); this.Controls.Add(button); So yeah, the buttons and the numericUpDowns match eachother with 1,2,3,4,5, ... and are related :) - yenthe

The problem is: since you event is fired by a button, you cannot convert the sender to numeric updown.

I see you have only one button and it's not declared in you code. I assume it's in the form, right???

Did you mean to add that click event many times to a single button???

Or did you mean to add events to each NumericUpDown???

If it's the second option, you should add the click event to each numeric updown. See this line in your code.

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

Respondido el 20 de junio de 20 a las 10:06

^The thing is that you can't use the button.Click since you can't sender a button to a NumericUpDown, as Steve explained me up there! So this won't work, sadly :( - yenthe

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

Respondido 25 Feb 16, 20:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.