WPF DataGrid Dilemma: Add Column to Bound DataTable

Published 8/10/2012

C# dev

Well after many hours of being stumped and perusing the web; I finally have a solution to my dilemma surrounding the WPF DataGrid.

It seemed like a simple problem: Bind a DataGrid to a DataTable and have it update all it's contents both ways. Getting the initial content worked like a charm, but then trying to add a new column to add new data wasn't working at all. It was a nightmare and I any example I found just stopped at loading initial data in.

It turns out that while the DataTable behind is happy to update itself and other things bound to it will update their collections, even with AutoGenerateColumns set to true, the DataGrid just happily ignores the new column and doesn't display a thing.

The solution I finally came upon requires that you create your own column on the DataGrid to bind back to the column added in the DataTable.

So, first I have my DataTable property and a DataView property I'll bind to my DataGrid:


        private DataTable myDataTable;
        public DataTable MyDataTable
        {
            get
            {
                if (myDataTable == null)
                {
                    myDataTable = new DataTable("MyTable");
                }
                return myDataTable;
            }
            set
            {
                myDataTable = value;
                NotifyPropertyChanged("MyDataTable");
                NotifyPropertyChanged("MyDataView");
            }
        }

        public DataView MyDataView
        {
            get 
            {
                return this.MyDataTable != null ? this.MyDataTable.DefaultView : null; 
            }
        }

Now I can bind my Grid to my DataView:


        <DataGrid x:Name="MyDataGrid" ItemsSource="{Binding MyDataView}" SelectionMode="Single" AutoGenerateColumns="True"/>

And finally if I want to add a new column, I can do this:


        // Add Column to Data Table
        MyDataTable.Columns.Add(columnname);

        // Create new DataGrid Column (could be of any type, just picking text here)
        DataGridTextColumn dgtc = new DataGridTextColumn();
        dgtc.Header = columnname;
        dgtc.Binding = new Binding(columnname); // This is the important part to get it to hook itself up to the Table behind.
        // Add it to my DataGrid
        MyDataGrid.Columns.Add(dgtc);

        // Notify any one bound to these properties there's an update, as per the usual!
        NotifyPropertyChanged("MyDataTable");
        NotifyPropertyChanged("MyDataView");

And voila, a fully connected and expandable DataGrid. You should find out more about what this was used for in a few weeks.

And if you have a better way, I'd love to see it, as apparently no one on the net besides me is adding columns after loading data in a DataGrid...