3

I need some help as Im relatively new to C#. Im basically trying to clone a datagridview component properties(the row/column content is different).

Basically I have a tab page control... and at run time if the user wants to add another table, a new page is created with the new datagridview in it having the same properties as the existing datagridview component:

string newpagetitle = "tab_page" + (tab_control01.TabCount + 1);
TabPage newTab_page = new TabPage(newpagetitle);

DataGridView clonedDGV = new DataGridView();

clonedDGV = this.dataGridView1; //need to clone this
clonedDGV.Name=("DataGridView" + tab_control01.TabCount + 1);
clonedDGV.DataSource = exam_Results_Table;
newTab_page.Controls.Add(clonedDGV);
this.tab_control01.TabPages.Add(newTab_page);
svick
  • 236,525
  • 50
  • 385
  • 514
Magikarp
  • 492
  • 6
  • 19
  • I don't think you'll get where you want this way... I would create a data template for grids of this kind and bind it to a data source (view model). If your user creates a new table (new data source) you bind it to a new instance of a grid using the same data template. This results in a "visual clone" of your grid with new data in it. – Paul Michalik Mar 06 '12 at 18:54

2 Answers2

4

You definitely don't want to do this:

clonedDGV = this.dataGridView1;

That line does not clone dataGridView1. Instead, it just takes the variable clonedDGV and points it to the same grid object that dataGridView1 points to. That means if you make any changes to clonedDGV, you'll also be making them to dataGridView1. Remember that in C#, (almost) all object variables are actually references to objects, not objects themselves.

There is no built in way to clone a DataGridView in C#. If all you want to do is copy the structure to a new grid, then you can do something like this:

DataGridView clonedDGV = new DataGridView();
foreach(DataGridViewColumn col in this.dataGridView1.Columns) {
    clonedDGV.Columns.Add(new DataGridViewColumn(col.CellTemplate));
}

That will give you a new grid with the same structure, but without any data. If you want to copy the data too, then loop through the rows in the original grid and add new rows to the new grid.

If there are other properties that need to be copied as well, just set them one by one on the new grid.

Edit: If all you care about is cloning the properties of your original grid, you'll have to do all the work yourself. If this is something you plan on doing often, I'd advise you to create an extension method and keep all your logic in there. Something like this:

public static class Extentions {
    public static DataTable Clone(this DataGridView oldDGV) {
        DataGridView newDGV = new DataGridView();

        newDGV.Size = oldDGV.Size;
        newDGV.Anchor = oldDGV.Anchor;

        return newDGV;
    }
}

Once that's been created you can call it like this:

DataGridView clonedDGV = dataGridView1.Clone();

You'll still have to write a line of code for each property that matters to you, but at least your logic will be in one place.

ean5533
  • 8,884
  • 3
  • 40
  • 64
  • I am well aware of that... but I'm just filling it there right now just to see if my code works... It's that part that i need replacement. Its not the columns that I want to copy but the component properties, like its set size, boundary properties, etc etc. The source/column is totally different – Magikarp Mar 06 '12 at 18:18
  • There is no built in way to do what you're asking. You'll have to manually set each property of the new grid to the value of that property on the old grid. – ean5533 Mar 06 '12 at 18:25
  • @ArjiSamosa See my update for a quick suggestion on making your coding easier. – ean5533 Mar 06 '12 at 18:44
2

Instead of this clonedDGV = this.dataGridView1 you need to go over properties and copy them individually. Otherwise you are resetting clonedDGV to be just another reference to old data grid.

Note: it is normally not possible to "clone" object unless it is designed to be cloned.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179