Dynamically add Columns to DataGrid in wpf

19,263

You can dynamically build the columns of a DataGrid as follows.

public void buildTable(string[] headers)
{
    myGrid.Columns.Clear();
    foreach (string header in headers)
    {
        DataGridTextColumn c = new DataGridTextColumn();
        c.Header = header;
        myGrid.Columns.Add(c);
    }
}

If you are setting ItemsSource, however, the number of rows and columns will automatically adjust to match the value of ItemsSource. For example, the following code produces a DataGrid with 3 rows and 3 columns.

dt = new DataTable();

for (int i = 0; i < 3; i++)
    dt.Columns.Add("col" + i.ToString());

for (int i = 0; i < 3; i++)
{
    DataRow r = items.NewRow();
    r[0] = "a" + i.ToString();
    r[1] = "b" + i.ToString();
    r[2] = "c" + i.ToString();
    dt.Rows.Add(r);
}

myGrid.ItemsSource = dt;
+------+------+------+  
| col0 | col1 | col2 |  
+------+------+------+  
|  a0  |  b0  |  c0  |  
+------+------+------+  
|  a1  |  b1  |  c1  |  
+------+------+------+  
|  a2  |  b2  |  c2  |   
+------+------+------+ 

Without knowing your exact requirements, I would not bother with manually drawing a table in code unless you have some special need custom graphics and even in that case I would look into using XAML to restyle the DataGrid or it's elements before attempting to render it myself. That's just my opinion though. Best of luck!

EDIT:

If you want to generate the table columns based on user input, you would just need to put the column generation code in a event handler. In your example you could add an event handler for the Textbox TextChanged event as follows. This event handler will run every time the text changes in the Textbox. You may want to add validation to prevent users from keying in large numbers.

private void numColsTextbox_TextChanged(object sender, TextChangedEventArgs e)
{
    int numCols;
    if (Int32.TryParse(tb.Text, out numCols))
    {
        myGrid.Columns.Clear();
        for (int i = 1; i <= numCols; i++)
        {
            DataGridTextColumn c = new DataGridTextColumn();
            c.Header = "Column " + i.ToString();
            myGrid.Columns.Add(c);
        }
    }
}
Share:
19,263
Abhinav
Author by

Abhinav

Updated on June 18, 2022

Comments

  • Abhinav
    Abhinav almost 2 years

    I am currently working on a custom canvas and in that i have to add a table,So i thought dataGrid would be fine. SO i Want to create a "Table" from "Datagrid" by which user can add a table to the canvas at runtime.

    Till now, I have tried to Populate DataGrid With a list and succeded.

    How Can I add Columns to a Datagrid at runtime,such that the number of columns and header value Would be taken from the user at runtime using a textbox and based on the value of the textbox the datagrid should add columns and header value.

    Actually I want to develop a Table in which user passes the no of columns and the column header and the table should be generated.

    Or

    "Can you suggest me with a way where i should look in order to to "Draw" a Table using DrawingVisual class"

    It is a part of GraphicsTable Class

    //Custom Classes "DrawingCanvas & GraphicsTable" 
    public void CreateDataGrid(GraphicsTable graphicsTable, DrawingCanvas drawingCanvas)
    {
        dt = new DataGrid();
        dt.Name = "Data";
        dt.ItemsSource = person();
        dt.AllowDrop = true;
        dt.AutoGenerateColumns = true;
        dt.Height = graphicsTable.Rectangle.Height;
        dt.Width = graphicsTable.Rectangle.Width;
        drawingCanvas.Children.Add(dt);
        Canvas.SetTop(dt, graphicsTable.Rectangle.Top);
        Canvas.SetLeft(dt, graphicsTable.Rectangle.Left);
        dt.Width = dt.Width;
        dt.Height = dt.Height;
        dt.Focus();
    }
    //I have just tried to add dome dummy data to the datagrid.
    
    public List<Person> person()
    {
        List<Person> peep = new List<Person>();
        peep.Add(new Person() {});
        return peep;
    }
    
    public class Person
    {
        private string name;
        private double salary;
        public string Names
        {
            get { return name; }
            set { name = value; }
        }
        public double Salary
        {
            get { return salary; }
            set { salary = value; }
        }
    }