This is a migrated thread and some comments may be shown as answers.

RadGridView columns binding MVVM?

15 Answers 1114 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Calabonga
Top achievements
Rank 2
Calabonga asked on 30 Jun 2010, 10:00 PM
How to I can in my ViewModel bind columns collection to the grid?

15 Answers, 1 is accepted

Sort by
0
Calabonga
Top achievements
Rank 2
answered on 30 Jun 2010, 11:51 PM
I'm founded my own simple solution:
1. Create attached property:
/// <summary>  
    /// Calabonga: класс-помощник для RadGridView контрола.  
    /// </summary>  
    public class RadGridViewHelper  
    {
        #region GridColumns  
        /// <summary>  
        /// Calabonga: Коллекция колонок для MVVM  
        /// </summary>  
        public static readonly DependencyProperty ColumnsCollectionProperty =  
            DependencyProperty.RegisterAttached("ColumnsCollection",  
            typeof(GridViewColumnCollection),  
            typeof(RadGridViewHelper),  
            new PropertyMetadata(ColumnsCollectionsChanged));  
 
 
        private static void ColumnsCollectionsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
        {  
            GridViewDataControl grid = d as GridViewDataControl;  
            if (grid != null)  
            {  
                GridViewColumnCollection collection = (GridViewColumnCollection)e.NewValue;  
                foreach (GridViewColumn item in collection)  
                {  
                    grid.Columns.Add(item);  
                }  
            }  
        }  
 
        /// <summary>  
        /// Calabogna: Установка свойства   
        /// </summary>  
        /// <param name="d">объект</param>  
        /// <param name="columns">колонки</param>  
        public static void SetColumnsCollection(DependencyObject d, GridViewColumnCollection columns)  
        {  
            d.SetValue(ColumnsCollectionProperty, columns);  
        }  
 
        /// <summary>  
        /// Calabonga: Чтение свойтсва  
        /// </summary>  
        /// <param name="d">объект</param>  
        /// <returns></returns>  
        public static GridViewColumnCollection GetColumnsCollection(DependencyObject d)  
        {  
            return (GridViewColumnCollection)d.GetValue(ColumnsCollectionProperty);  
        }
        #endregion  

2. using it in XAML:
<telerikGrid:RadGridView Grid.Row="1" 
grid:RadGridViewHelper.ColumnsCollection="{Binding Path=ColumnsCollection}" 
AutoGenerateColumns="False" 
ItemsSource="{Binding ElementName=Source, Path=Data}"/> 

3. and in viewmodel create the columns collection.



0
Moe Aboulkheir
Top achievements
Rank 1
answered on 13 Jul 2010, 04:02 PM
Exactly what I was looking for.  Thanks!
0
Daní
Top achievements
Rank 1
answered on 17 Sep 2010, 09:05 AM
Thank you so much Calabonga, really usefull example, I'm using it with a little modification to reach a more MVVM behavior.
public class RadGridViewColumnsBinding
    {
        public static readonly DependencyProperty ColumnsCollectionProperty =
            DependencyProperty.RegisterAttached("ColumnsCollection", typeof (ObservableCollection<ColumnDefinition>),
                                                typeof(RadGridViewColumnsBinding),
                                                new PropertyMetadata(OnColumnsCollectionChanged));
        private static void OnColumnsCollectionChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            GridViewDataControl gridView = o as GridViewDataControl;
            if (gridView == null) return;
            gridView.Columns.Clear();
            if (e.NewValue == null) return;
            var collection = e.NewValue as ObservableCollection<ColumnDefinition>;
             
            if (collection == null) return;
            collection.CollectionChanged += (sender, arguments) =>
            {
                switch (arguments.Action)
                {
                    case NotifyCollectionChangedAction.Add:
                        foreach (ColumnDefinition col in arguments.NewItems)
                        {
                            var column = GetColumn(col);
                            gridView.Columns.Add(column);
                            column.DisplayIndex = arguments.NewStartingIndex;
                            col.PropertyChanged += (s, args) =>
                            {
                                var c = s as ColumnDefinition;
                                column.IsVisible = c.IsVisible;
                            };
                        }
                        break;
                    case NotifyCollectionChangedAction.Remove:
                        foreach(ColumnDefinition col in arguments.OldItems)
                        {
                            var column = gridView.Columns[col.UniqueName];
                            if(column != null)
                                gridView.Columns.Remove(column);
                        }
                        break;
                }
            };
            foreach (var col in collection)
            {
                var column = GetColumn(col);
                gridView.Columns.Add(column);
                col.PropertyChanged += (s, args) =>
                {
                    var c = s as ColumnDefinition;
                    column.IsVisible = c.IsVisible;
                };
            }
            //gridView.Columns.Add(col);
        }
 
        private static GridViewDataColumn GetColumn(ColumnDefinition col)
        {
            var column = new GridViewDataColumn
                             {
                                 UniqueName = col.UniqueName,
                                 CellStyleSelector = col.CellStyleSelector,
                                 DataMemberBinding = col.DataMemberBinding,
                                 Header = col.Header,
                                 HeaderCellStyle = col.HeaderCellStyle,
                                 HeaderTextAlignment = col.HeaderTextAlignment,
                                 IsFilterable = col.IsFilterable,
                                 IsGroupable = col.IsGroupable,
                                 IsReadOnly = col.IsReadOnly,
                                 IsResizable = col.IsResizable,
                                 IsSortable = col.IsSorteable,
                                 IsVisible = col.IsVisible,
                                 CellTemplateSelector = col.CellTemplateSelector,
                                 MaxWidth = col.MaxWidth
                             };
 
            return column;
        }
 
         
 
        public static void SetColumnsCollection(DependencyObject o, ObservableCollection<ColumnDefinition> value)
        {
            o.SetValue(ColumnsCollectionProperty, value);
        }
        public static ObservableCollection<ColumnDefinition> GetColumnsCollection(DependencyObject o)
        {
            return o.GetValue(ColumnsCollectionProperty) as ObservableCollection<ColumnDefinition>;
        }
    }
 
    public class ColumnDefinition: ViewModelBase
    {
        public string UniqueName { get; set; }
        private int _displayIndex = -1;
 
        public int DisplayIndex
        {
            get
            {
                return this._displayIndex;
            }
            set
            {
                if (this._displayIndex != value)
                {
                    this._displayIndex = value;
                    this.OnPropertyChanged("DisplayIndex");
                }
            }
        }
        private bool _isVisible = true;
 
        public bool IsVisible
        {
            get
            {
                return this._isVisible;
            }
            set
            {
                if (this._isVisible != value)
                {
                    this._isVisible = value;
                    this.OnPropertyChanged("IsVisible");
                }
            }
        }
        private string _header;
 
        public string Header
        {
            get
            {
                return this._header;
            }
            set
            {
                if (this._header != value)
                {
                    this._header = value;
                    this.OnPropertyChanged("Header");
                }
            }
        }
        private Style _headerCellStyle;
 
        public Style HeaderCellStyle
        {
            get
            {
                return this._headerCellStyle;
            }
            set
            {
                if (this._headerCellStyle != value)
                {
                    this._headerCellStyle = value;
                    this.OnPropertyChanged("HeaderCellStyle");
                }
            }
        }
        private Binding _dataMemberBinding;
 
        public Binding DataMemberBinding
        {
            get
            {
                return this._dataMemberBinding;
            }
            set
            {
                if (this._dataMemberBinding != value)
                {
                    this._dataMemberBinding = value;
                    this.OnPropertyChanged("DataMemberBinding");
                }
            }
        }
        private bool _isResizable;
 
        public bool IsResizable
        {
            get
            {
                return this._isResizable;
            }
            set
            {
                if (this._isResizable != value)
                {
                    this._isResizable = value;
                    this.OnPropertyChanged("IsResizable");
                }
            }
        }
        private bool _isSorteable;
 
        public bool IsSorteable
        {
            get
            {
                return this._isSorteable;
            }
            set
            {
                if (this._isSorteable != value)
                {
                    this._isSorteable = value;
                    this.OnPropertyChanged("IsSorteable");
                }
            }
        }
        private bool _isReadOnly;
 
        public bool IsReadOnly
        {
            get
            {
                return this._isReadOnly;
            }
            set
            {
                if (this._isReadOnly != value)
                {
                    this._isReadOnly = value;
                    this.OnPropertyChanged("IsReadOnly");
                }
            }
        }
        private bool _isGroupable;
 
        public bool IsGroupable
        {
            get
            {
                return this._isGroupable;
            }
            set
            {
                if (this._isGroupable != value)
                {
                    this._isGroupable = value;
                    this.OnPropertyChanged("IsGroupable");
                }
            }
        }
        private bool _isFilterable;
 
        public bool IsFilterable
        {
            get
            {
                return this._isFilterable;
            }
            set
            {
                if (this._isFilterable != value)
                {
                    this._isFilterable = value;
                    this.OnPropertyChanged("IsFilterable");
                }
            }
        }
        private TextAlignment _headerTextAlignment;
 
        public TextAlignment HeaderTextAlignment
        {
            get
            {
                return this._headerTextAlignment;
            }
            set
            {
                if (this._headerTextAlignment != value)
                {
                    this._headerTextAlignment = value;
                    this.OnPropertyChanged("HeaderTextAlignment");
                }
            }
        }
        private StyleSelector _cellStyleSelector;
 
        public StyleSelector CellStyleSelector
        {
            get
            {
                return this._cellStyleSelector;
            }
            set
            {
                if (this._cellStyleSelector != value)
                {
                    this._cellStyleSelector = value;
                    this.OnPropertyChanged("CellStyleSelector");
                }
            }
        }
        private DataTemplateSelector _cellTemplateSelector;
 
        public DataTemplateSelector CellTemplateSelector
        {
            get
            {
                return this._cellTemplateSelector;
            }
            set
            {
                if (this._cellTemplateSelector != value)
                {
                    this._cellTemplateSelector = value;
                    this.OnPropertyChanged("CellTemplateSelector");
                }
            }
        }
        private double _maxWidth = 1000;
 
        public double MaxWidth
        {
            get
            {
                return this._maxWidth;
            }
            set
            {
                if (this._maxWidth != value)
                {
                    this._maxWidth = value;
                    this.OnPropertyChanged("MaxWidth");
                }
            }
        }
 
        public object Tag { get; set; }
    }

In my case, I'm not using a GridViewColumnCollection directly but I defined a ColumnDefinition class and the attached property is an ObservableCollection<ColumnDefinition>. So, I'm able to "listent" when new columns are added/deleted and I'm also able to "listen" changes in ColumnDefinition properties  so I can modiy at runtime visibility,.. in columns.

Hope this helps somebody
0
Jerry Kurata
Top achievements
Rank 1
answered on 05 Nov 2010, 08:12 PM
Ignore
0
Radoslaw
Top achievements
Rank 1
answered on 12 Nov 2010, 12:10 PM
Dani, could you present how you use your RadGridViewColumnsBinding class in code, xaml ???
0
Daní
Top achievements
Rank 1
answered on 12 Nov 2010, 03:19 PM
Hi Radoslaw,

Of course I can help you but at this moment I'm little busy. I'll try create a simple example (to avoid you the innecessaty stuff from my own project) this weekend and I'll upload it in this post or at code library. Hope you are not in hurry.
0
Timothy
Top achievements
Rank 1
answered on 31 Mar 2011, 07:59 AM
Dani, can you please provide your code samples. This is exactly what I need?

Thanks
0
Philipp
Top achievements
Rank 1
answered on 16 Nov 2011, 12:16 PM
Can anybody provide a full code example, please?

Thanks
0
Alex
Top achievements
Rank 1
answered on 21 Dec 2011, 01:34 PM
Thanks a lot for this sample! It helped me a lot.

I have an other question to move forward.

Is it possible to sync the column reordering with the order of ColumnDefinitions in the view model? In other words, if I reorder some column from UI I need that it's column definition object was also reordered accordingly.

What's the best way to do this? 

Thanks
0
Alex
Top achievements
Rank 1
answered on 21 Dec 2011, 03:34 PM
I don't really need the code for it, just an advice will be highly appreciated. Thanks
0
Alex
Top achievements
Rank 1
answered on 21 Dec 2011, 04:50 PM
Solved it. Here's steps:
  1. Add a dictionary with GridViewColumn as a key and ColumnDescriptor as a value.
  2. Subscribe to RowReordering even of a grid.
  3. In RowReordering handler you'll have a column and new index. Set handled = cancel = true (we'll handle reordering manually).
  4. Get ColumnDescriptor from the dictionary by column.
  5. Get your view model from grid.DataContext
  6. Call your VM's method with ColumnDescriptor and newIndex, which will remove ColumnDescriptor from your collection and Insert in with new index.
  7. That's it.
0
Nicolaas
Top achievements
Rank 1
answered on 25 May 2012, 11:07 AM
any luck with the xaml code you promised?
0
Роман
Top achievements
Rank 1
answered on 05 Feb 2016, 03:27 AM
Thanks! But could you provide a viewmodel example code?
0
Daní
Top achievements
Rank 1
answered on 05 Feb 2016, 10:12 AM

Hi Pomah,

 

What do you exactly need?

 

 

0
Andrey Smiryagin
Top achievements
Rank 1
answered on 29 Apr 2017, 03:10 AM
Has anyone figured out how to create a ColumnDefinition with proper bindings from Dani's example? I have a property in my VM that is an ObervableCollection<T> and I want its nested properties to represent the Columns of my gridview. I can't figure out how to set the DataMemberBinding property of my ColumnDefinition items.
Tags
GridView
Asked by
Calabonga
Top achievements
Rank 2
Answers by
Calabonga
Top achievements
Rank 2
Moe Aboulkheir
Top achievements
Rank 1
Daní
Top achievements
Rank 1
Jerry Kurata
Top achievements
Rank 1
Radoslaw
Top achievements
Rank 1
Timothy
Top achievements
Rank 1
Philipp
Top achievements
Rank 1
Alex
Top achievements
Rank 1
Nicolaas
Top achievements
Rank 1
Роман
Top achievements
Rank 1
Andrey Smiryagin
Top achievements
Rank 1
Share this question
or