I am searching about how to create the columns of the DataGrid from the ToolKit dynamic in MvvM way. But looks like it is impossible !
Is there some one that had to do the samething ?
there is no need to create a usercontrol or another开发者_如何学Go control that comes from DataGrid, I just want to set de ItemSource of the grid to my custom object and in some point I want to define the columns of the grid in runtime dynamic based in the kind of the object.
Is that possible ?
cheers
I'm going to preface this by saying it maybe isn't the best solution to be doing and may not work in some situations but you can give it a try and see if it will work for what you want. I just whipped this up so it may have some bugs in it. Its still going to involve some code, but it keeps your model from knowing about you view.
What you need to do is create an extension property that will allow you to bind the Columns property on the DataGrid. Here is an example that I put together.
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
public static class DataGridExtension
{
public static ObservableCollection<DataGridColumn> GetColumns(DependencyObject obj)
{
return (ObservableCollection<DataGridColumn>)obj.GetValue(ColumnsProperty);
}
public static void SetColumns(DependencyObject obj, ObservableCollection<DataGridColumn> value)
{
obj.SetValue(ColumnsProperty, value);
}
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.RegisterAttached("Columns",
typeof(ObservableCollection<DataGridColumn>),
typeof(DataGridExtension),
new UIPropertyMetadata (new ObservableCollection<DataGridColumn>(),
OnDataGridColumnsPropertyChanged));
private static void OnDataGridColumnsPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
if (d.GetType() == typeof(DataGrid))
{
DataGrid myGrid = d as DataGrid;
ObservableCollection<DataGridColumn> Columns =
(ObservableCollection<DataGridColumn>)e.NewValue;
if(Columns != null)
{
myGrid.Columns.Clear();
if (Columns != null && Columns.Count > 0)
{
foreach (DataGridColumn dataGridColumn in Columns)
{
myGrid.Columns.Add(dataGridColumn);
}
}
Columns.CollectionChanged += delegate(object sender,
NotifyCollectionChangedEventArgs args)
{
if(args.NewItems != null)
{
foreach (DataGridColumn column
in args.NewItems.Cast<DataGridColumn>())
{
myGrid.Columns.Add(column);
}
}
if(args.OldItems != null)
{
foreach (DataGridColumn column
in args.OldItems.Cast<DataGridColumn>())
{
myGrid.Columns.Remove(column);
}
}
};
}
}
}
}
Then you attach it to you DataGrid like this (Where columns is the an ObservableCollection property on your view model)
<Controls:DataGrid AutoGenerateColumns="False"
DataGridExtension.Columns="{Binding Columns}" />
I'm not sure how well it is going to respond if you start adding and remove columns, but it seems to work from my basic testing. Good Luck!
Having a similar problem, I did not want to add another dependency property. My workaround was to organise the data to display in the DataGrid in a DataTable and bind the DataGrid ItemSource property to this DataTable (with of course AutoGenerateColumns set to true).
It works well, DataGrids seem happy with DataTable as source.
I would like to extend the previous example (answer) the ability to subscribe and unsubscribe on event CollectionChanged. Link on my answer in related theme.
精彩评论