Home > Enterprise >  WinForm C# how attach an Method to a Control programmaticaly created
WinForm C# how attach an Method to a Control programmaticaly created

Time:10-04

In my apps, I generated a bunch of DataGridView programmaticaly. I can add/remove rows to it and retrieve all the data from it and copy the data in another DataGrid.

for instance when Im creating it

public void Example(TabControl tab)
        for(int i=0;i<tab.TabCount;i  )
        {
        tab.TabPages.Add("Panneau "   tab.TabCount);
        
        DataGridView panGridView = new DataGridView();
        panGridView.Name = "panGridView_"   tab.TabCount;
        panGridView.Location = new System.Drawing.Point(0, 0);
        panGridView.RowTemplate.Height = 24;
        panGridView.Size = new System.Drawing.Size(1375, 458);
        panGridView.Columns.Add("id", "id");
        panGridView.Columns.Add("part_code", "part_code");
        panGridView.Columns[0].Width = 100;
        panGridView.Columns[1].Width = 150;
        panGridView.Visible = true;
        panIndex.Items.Add(tab.TabCount - 1);
        tab.TabPages[tab.TabCount - 1].Controls.Add(panGridView);

        }

Now, I want to attach Method to this Control. I think the best way would be to attach it when I initialize the Control. For example I would attach a Method like this one

public void Action(DataGridViewCellMouseEventArgs e)
{
 if(e.RowIndex==2)
 {
  MessageBox.Show("Hello");
 }

I tried a lot of this but cant figure out how do it.

Thanks

CodePudding user response:

It seems to me that you want a special kind of DataGridView. You want a DataGridView with an attached method. You've learned, whenever you need a "class, very similar to another class, but with just a small thing different", you need to create a derived class, or make a composition, if you don't want to expose all methods of the base class.

class DataGridViewWithAttachedMethod : DataGridView   // TODO: invent proper name
{
    ...
}

class MySpecialDataGridView : UserControl
{
    private DataGridView dgv1;

    ...
}

The advantage of the first method is that users of your class (= code, not operators) have access to all DataGridView methods, so it will be very flexible to use. Disadvantage: they have access to all DataGridView methods, so they can mess up your DataGridView.

Whether you will use derivation or composition depends on how fool proof your class needs to be, in other words: do you want to expose methods that you prefer not to be used by others?

I want to attach Method to this Control.

This is not really clear. Do you want to give DataGridView an extra method, always the same one? Or do you want to Dynamically attach a method: dgv1 has another attached method than dgv2.

class DgvWithExtraMethod : ...
{
    public void Action(DataGridViewCellMouseEventArgs e)
    {
        if(e.RowIndex==2)
        {
             MessageBox.Show("Hello");
        }
    }
}

All instances of this dgv will have the same extra method. All you have to do is create an object of this class, and you will have this method.

However, if you want to attach different methods to instances of the class, you need a property that contains this method.

class DgvWithMethod : ...
{
    public Action<DataGridViewCellMouseEventArgs> ExtraMethod {get; set;}
}

If you want your class fool proof, consider to initialize the method with a "no operation (NOP)"

private static Action<DataGridViewCellMouseEventArgs> NOP = (e) => {};

public Action<DataGridViewCellMouseEventArgs> ExtraMethod {get; set;} = NOP;

Usage:

DgvWithMethod dgv1 = new DgvWithMethod
{
    ExtraMethod = (e) =>
    {
        if(e.RowIndex==2)
        {
             MessageBox.Show("Hello");
        }
    }
}

This is the exact answer to your question. However, what I think that you want to know is: if the operator click on row 2, then I want to execute method F(), and if he clicks on row 3, I want to execute method G(), etc

If that is what you want, use visual studio designer to add an event handler on DataGridView.CellMouseClick, or if you want to reuse this class (derivation / composition) override DataGridView.OnCellMouseClick.

private void DataGridView1_CellMouseClick(Object sender,
    DataGridViewCellMouseEventArgs e)
{
    // find out which column is clicked
    switch (e.ColumnIndex)
    {
        case 0: // column Id clicked
            this.ProcessColumnIdClick(e);
            break;
        case 1: // column Name clicked
            this.ProcessColumnNameClick(e);
            break;
        ...

Take care though: if you allow column reordering, you should compare ColumnIndex with the DisplayIndex of each column.

if (e.ColumnIndex == this.columnId.DisplayIndex)
    this.ProcessColumnIdClick(e);
else if (e.ColumnIndex == this.columnName.DisplayIndex)
    ...

CodePudding user response:

Like @CurleD stated, you simply subscribe your method to specific EventHandler. So change your Action to this:

private void panGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if(e.RowIndex==2)
    {
        MessageBox.Show("Hello");
    }
}

and then subscribe to the CellMouseClick event:

panGridView.CellMouseClick  = panGridView_CellMouseClick;
  • Related