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

Binding a subset of columns from a Datatable to RadGridView

4 Answers 69 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Carl
Top achievements
Rank 1
Carl asked on 16 Sep 2015, 01:37 AM

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

Sort by
0
Stefan
Telerik team
answered on 17 Sep 2015, 08:59 AM
Hi Carl,

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
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Carl
Top achievements
Rank 1
answered on 18 Sep 2015, 02:34 AM

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.

 

0
Carl
Top achievements
Rank 1
answered on 18 Sep 2015, 04:53 AM

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.  

 

 

0
Stefan
Telerik team
answered on 22 Sep 2015, 01:02 PM
Hello Carl,

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
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
GridView
Asked by
Carl
Top achievements
Rank 1
Answers by
Stefan
Telerik team
Carl
Top achievements
Rank 1
Share this question
or