How to create events dynamically? C#

Asked

Viewed 341 times

1

I am doing a project of a statistical calculator, in it I made a method that creates tabs in a tab control and inside them a datagridview to display the different tables generated by the program.

I need an event that auto-populates the datagrid cells as soon as the user enters with two terms.

I’m wearing an event like:

private void CalculaPasso(object sender, DataGridViewCellEventArgs e) //evento de alteração nas celulas
{
    DataGridView dgv = dgvTabela;
    dgvControle.calculaPasso(numeroLinhas, dgv);
    dgvControle.calculaFi(numeroLinhas, dgv);
}

public void calculaPasso(int numeroLinhas, DataGridView dgv)//calcula o passo automaticamente quando a pessoa entra com um valor
{
    //esse comando String.IsNullOrEmpty verifica se a celula está vazia. 
    //Usa-se String.IsNullOrEmpty(Aqui vem a celula, no caso o (string) vai converter o valor da celula em texto

    if ((String.IsNullOrEmpty((string)dgv.Rows[].Cells[1].Value)) | String.IsNullOrEmpty((string)dgv.Rows[].Cells[2].Value))
    {
        dgv.Rows[numeroLinhas].Cells[1].Value = "h = 0";
    }
    else
    {
        double passo = Convert.ToDouble(dgv.Rows[].Cells[2].Value) - Convert.ToDouble(dgv.Rows[].Cells[1].Value);
        dgv.Rows[numeroLinhas].Cells[1].Value = "h = " + passo;

        preencheLimites(passo, numeroLinhas, dgv);
    }
}

public void preencheLimites(double passo, int numeroLinhas, DataGridView dgv)//é chamado pelo método calculaPasso
{
    int i;
    int linhas = numeroLinhas - 1;
    for (i = 1; i < numeroLinhas; i++)
    {
        dgv.Rows[i].Cells[1].Value = Convert.ToDouble(dgv.Rows[i - 1].Cells[1].Value) + passo;
        dgv.Rows[i].Cells[2].Value = Convert.ToDouble(dgv.Rows[i - 1].Cells[2].Value) + passo;
    }
}

public void calculaFi(int numeroLinhas, DataGridView dgv)
{
    int i;
    int Fi = ;

    for (i = ; i < numeroLinhas; i++)
    {
        if (string.IsNullOrEmpty((string)dgv.Rows[i].Cells[3].Value))
        {
            Fi += ;
        }
        else
            Fi += Convert.ToInt32(dgv.Rows[i].Cells[3].Value);                                             
    }
    dgv.Rows[numeroLinhas].Cells[3].Value = Fi;  
}

This worked fine when I only created a datagridview in the form, but now I need to create the grids as the user requests*.

How to create an event that sees which grid has been modified and so fill the cells?

*To create the datagrids I am doing so:

public DataGridView criaTabEDgv(string nome) //chame criaTabEDgv com o nome da tabela a ser criada, por exemplo TDF ou Mtc...
{           
    this.SuspendLayout();
    // primeiro criamos o grid dinamicamente
    var dg = new System.Windows.Forms.DataGridView();
    dg.Dock = System.Windows.Forms.DockStyle.Fill;
    dg.Location = new System.Drawing.Point(3, 3);
    dg.Name = "dgv" + nome;
    dg.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.DisplayedCells;
    dg.AllowUserToAddRows = false;

    // adiciona a aba dinamicamente
    var aba = new System.Windows.Forms.TabPage();            
    aba.Location = new System.Drawing.Point(4, 32);
    aba.Name = "tab" + nome;
    aba.Padding = new System.Windows.Forms.Padding(3);
    aba.Size = new System.Drawing.Size(638, 300);
    aba.TabIndex = tabControl1.TabCount;
    aba.Text = nome;
    aba.Controls.Add(dg); // adiciona o Grid nesta aba                                 

    // adiciona a tabPage no tabControl1
    tabControl1.Controls.Add(aba);

    return dg;            //retorna a dgv que acabou de ser criada para que outros metodos possam altera-la            
}

1 answer

1


The value passed to the parameter sender of the method CalculaPasso() contains the Control that launched the event.

Change the method this way:

private void CalculaPasso(object sender, DataGridViewCellEventArgs e)
{
    //Obtem a grid que lançou o evento
    DataGridView dgv = sender as DataGridView;
    dgvControle.calculaPasso(numeroLinhas, dgv);
    dgvControle.calculaFi(numeroLinhas, dgv);
}

By creating the Datagridview must indicate that it is the CalculaPasso() that will treat the event Cellvaluechanged:

public DataGridView criaTabEDgv(string nome) //chame criaTabEDgv com o nome da tabela a ser criada, por exemplo TDF ou Mtc...
{           
    this.SuspendLayout();
    // primeiro criamos o grid dinamicamente
    var dg = new System.Windows.Forms.DataGridView();
    .......
    .......
    //Regista o método CalculaPasso() para o evento CellValueChanged
    dg.CellValueChanged += CalculaPasso;
    dg.AllowUserToAddRows = false;

    // adiciona a aba dinamicamente
    var aba = new System.Windows.Forms.TabPage();
    .......
    .......
    return dg;            
}
  • It worked perfectly, thank you! Just one more thing... The methods inside the Calculator need to receive the little numbers that are in another class, I pass this number by parameter to the method constructor and it is passed to each method. How do I pass the numberLines to the calculatThat if the function you call is Calculapasso? You can include in the Calculator another parameter besides the Sender and datagrid?

  • Unfortunately not. What is this numberLines?

  • It’s the number of rows my datagrid has, need to create the grid and then to access and change the last row (it displays the total of each column).

  • dgv.RowCount does not serve?

  • No... When I go over this number he says An unhandled Exception of type 'System.He argued tofrangeexception' occurred in mscorlib.dll Additional information: The index was out of range. It should be non-negative and smaller than the size of the collection. ...

  • In the Meumenu class I did: public int numbersLines { get { Return Convert.Toint32(txtNumerLines.Text); } } but, in the Tabcan class I can’t access the numbersLines, even if I have Meumenu meuMenu = new Meumenu(); What’s missing?

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.