There are several other posts that looked similar and I used their code to come close but I am still having problems.
Problem: I have a datatable with a number of columns which I have bound to the radgridview. This works. What I want to do now is restrict the columns based on additional data in the view model. The modelview contains the datatable and the columns which I would like to bind. I am somewhat new to WPF and MVVM. I used the example from this post http://www.telerik.com/forums/column-collections but again it didn't work as I expect.
Thank you for any suggestions or code.
4 Answers, 1 is accepted
Can you please share some more details on what are the restrictions you need to apply to the columns and what difficulties did you face using the example you referred?
I would also like to encourage you to open a new support ticket with a sample project illustrating your current implementation attached, as this would be the fastest way to guide you to a solution.
I am looking forward to your reply.
Best Regards,
Stefan
Telerik
Sure, I have a datatable with some number of columns. I am using the first column as the X on a graph, and each of the other columns represent a curve in the Y)
Each of the other columns mapped to controls which when selected SHOULD change the datagrid to display the first column and which ever other column is associated with that control. (The graph shows the other column in the Y on the graph) So when I select the control the view and viewmodel are set and bound, but during the binding I need to be able to only show the specified columns.
<telerik:RadGridView x:Name="dataGrid" ItemsSource="{Binding Table.DefaultView}" AutoGenerateColumns="false" AllowDrop="True" CanUserDeleteRows="True" AlternateRowBackground="#FFCDCDCD" CanUserInsertRows="True" SelectionMode="Extended" SelectionUnit="Cell" AlternationCount="2" ClipToBounds="True" AutoExpandGroups="True" ClipboardCopyMode="All" ClipboardPasteMode="AllSelectedCells" > <i:Interaction.Behaviors> <local:ColumnBindingBehavior Columns="{Binding Columns}" /> </i:Interaction.Behaviors> </telerik:RadGridView.ContextMenu>ColumnBindingBehaviour is similar to a previous post
public class ColumnBindingBehavior : Behavior<RadGridView> { private RadGridView Grid { get { return AssociatedObject; } } public INotifyCollectionChanged Columns { get { return (INotifyCollectionChanged)GetValue(ColumnsItemsProperty); } set { SetValue(ColumnsItemsProperty, value); } } public static readonly DependencyProperty ColumnsItemsProperty = DependencyProperty.Register("Columns", typeof(INotifyCollectionChanged), typeof(ColumnBindingBehavior), new PropertyMetadata(OnColumnsPropertyChanged)); private static void OnColumnsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) { var behavior = (ColumnBindingBehavior)target; var collection = args.NewValue as INotifyCollectionChanged; if (collection != null) { collection.CollectionChanged -= behavior.ContextColumns_CollectionChanged; collection.CollectionChanged += behavior.ContextColumns_CollectionChanged; } } protected override void OnAttached() { base.OnAttached(); Transfer(Columns as IList, Grid.Columns); Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged; Grid.Columns.CollectionChanged += GridColumns_CollectionChanged; } void ContextColumns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { UnsubscribeFromEvents(); Transfer(Columns as IList, Grid.Columns); SubscribeToEvents(); } void GridColumns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { UnsubscribeFromEvents(); Transfer(Grid.Columns, Columns as IList); SubscribeToEvents(); } private void SubscribeToEvents() { Grid.Columns.CollectionChanged += GridColumns_CollectionChanged; if (Columns != null) { Columns.CollectionChanged += ContextColumns_CollectionChanged; } } private void UnsubscribeFromEvents() { Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged; if (Columns != null) { Columns.CollectionChanged -= ContextColumns_CollectionChanged; } } public static void Transfer(IList source, IList target) { if (source == null || target == null) return; target.Clear(); foreach (var o in source) { target.Add(o); } } }
If the autogeneratecolumns is on I get all of them, if off I get nothing.
There is something Im doing wrong but I don't know what.
So I figured it out. When I set the Datacontext for the control, the all the CollectionChanged delegates where called THEN the Columns changed property was called. The Columns value was then set but nothing else was changed. Notice I added the Transfer to the OnColumnsPropertyChanged and it all started to work.
public class ColumnBindingBehavior : Behavior<RadGridView> { private RadGridView Grid { get { return AssociatedObject; } } public INotifyCollectionChanged Columns { get { return (INotifyCollectionChanged)GetValue(ColumnsItemsProperty); } set { SetValue(ColumnsItemsProperty, value); } } public static readonly DependencyProperty ColumnsItemsProperty = DependencyProperty.Register("Columns", typeof(INotifyCollectionChanged), typeof(ColumnBindingBehavior), new PropertyMetadata(OnColumnsPropertyChanged)); private static void OnColumnsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args) { var behavior = (ColumnBindingBehavior)target; var collection = args.NewValue as INotifyCollectionChanged; if (collection != null) {// collection.CollectionChanged -= behavior.ContextColumns_CollectionChanged;// behavior.Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged; Transfer(behavior.Columns as IList, behavior.Grid.Columns);// collection.CollectionChanged += behavior.ContextColumns_CollectionChanged; } } protected override void OnAttached() { base.OnAttached(); Transfer(Columns as IList, Grid.Columns); //Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged; //Grid.Columns.CollectionChanged += GridColumns_CollectionChanged; } void ContextColumns_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { UnsubscribeFromEvents(); Transfer(Columns as IList, Grid.Columns); SubscribeToEvents(); } void GridColumns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { UnsubscribeFromEvents(); Transfer(Grid.Columns, Columns as IList); SubscribeToEvents(); } private void SubscribeToEvents() { //Grid.Columns.CollectionChanged += GridColumns_CollectionChanged; //if (Columns != null) //{ // Columns.CollectionChanged += ContextColumns_CollectionChanged; //} } private void UnsubscribeFromEvents() { //Grid.Columns.CollectionChanged -= GridColumns_CollectionChanged; //if (Columns != null) //{ // Columns.CollectionChanged -= ContextColumns_CollectionChanged; //} } public static void Transfer(IList source, IList target) { if (source == null || target == null) return; target.Clear(); foreach (var o in source) { target.Add(o); } } }Hope someone else can use this.
I am glad that you have found a resolution for the issue you were experiencing. Thank you for sharing it with us.
Do not hesitate to contact us in case you have any other questions on our controls.
Best Regards,
Stefan
Telerik