views:

109

answers:

1

Hi,

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 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

+1  A: 

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.

 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!

David Osborn