I am trying to figure out how to bind a WPF DataGrid\'s column header and main data to a data source using an MVVM pattern. The result I\'m looking for would look like this:
Here's what I ended up doing to use this with the MVVM pattern:
I have two sets of data for binding on my view model: one for the actual grid data and one for the column headers. Currently these are exposed as two properties:
// INotifyPropertyChanged support not shown for brevity
public DataTable GridData { get; set; }
public BindingList ColumnData { get; set; }
The trick to working with two differing sets of data is in the grid. I have subclassed the DataGrid and given the grid an additional data source called ColumnSource, as a dependency property. This is what is bound to the ColumnData on my view model. I then set the header of each auto-generated column to the appropriately indexed data in the ColumnSource data source. The code is as follows:
public class ImporterDataGrid : DataGrid
{
protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
{
base.OnAutoGeneratingColumn(e);
int columnIndex = this.Columns.Count;
var column = new ImporterDataGridColumn();
column.Header = ColumnSource[columnIndex];
column.Binding = new Binding(e.PropertyName) { Mode = BindingMode.OneWay };
e.Column = column;
}
public IList ColumnSource
{
get { return (IList)GetValue(ColumnSourceProperty); }
set { SetValue(ColumnSourceProperty, value); }
}
public static readonly DependencyProperty ColumnSourceProperty = DependencyProperty.Register("ColumnSource", typeof(IList), typeof(ImporterDataGrid), new FrameworkPropertyMetadata(null));
}
I can now perform normal data binding in the templated header of my columns, which will all bind against the data in the ColumnData property of my view model.
UPDATE: I was asked to show the XAML for my grid. It's really basic, but here it is:
And here is the ImporterColumnHeaderStyle: