Collections of Collections and row select

6 posts, 0 answers
  1. Chris
    Chris avatar
    20 posts
    Member since:
    Nov 2009

    Posted 22 Nov 2009 Link to this post

    RadControls for WPF Q3 2009.

    I would like to know how best to represent two collections of data in two GridView controls.
    We currently have situation where we have a collection of a data to be displayed and edited.  The objects in this collection have additional collections of other data, also which need to be edited.  (there are also cases where we have third level collections).

    Currently we are forced to use WPF ListView controls to display this data, and edit them in TextBox/ComboBox fields.  The ListView supports the IsSynchronizedWithCurrentItem property, which synchonises the ListViews at multiple levels of the Business Object.

    From what I can tell, the RadGridView does not appear to support IsSynchronizedWithCurrentItem.  I have attempted to use the SelectionChanged event on the RadGridView, with dissapointing results.  On particular occasions when clearing the binding on the second RadGridView, I get an exception "Cannot change ObservableCollection during a CollectionChanged event".
    This occurs when the user clears the Row selection, by holding down the Ctrl key, and clicks on the row on the second time.  (Ie.  Selects a row, unselects the row, selects a row, unselects the row.)

    Is there a particular method or way that I can occomplish this?

    Here is an example of the ListView, next to our partially functioning RadGridView.
    <Grid> 
        <Grid> 
            <Grid.RowDefinitions> 
                <RowDefinition/> 
                <RowDefinition/> 
            </Grid.RowDefinitions> 
            <Grid.ColumnDefinitions> 
                <ColumnDefinition/> 
                <ColumnDefinition/> 
                <ColumnDefinition/> 
                <ColumnDefinition/> 
            </Grid.ColumnDefinitions> 
            <ListView Name="uxListView1" Grid.Column="1" Grid.Row="0">  
                <ListView.View> 
                    <GridView> 
                        <GridView.Columns> 
                            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" /> 
                            <GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" /> 
                            <GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" /> 
                        </GridView.Columns> 
                    </GridView> 
                </ListView.View> 
            </ListView> 
            <ListView Name="uxListView2" Grid.Column="1" Grid.Row="1">  
                <ListView.View> 
                    <GridView> 
                        <GridView.Columns> 
                            <GridViewColumn Header="AreaCode" DisplayMemberBinding="{Binding AreaCode}" /> 
                            <GridViewColumn Header="Number" DisplayMemberBinding="{Binding Number}" /> 
                        </GridView.Columns> 
                    </GridView> 
                </ListView.View> 
            </ListView> 
            <telerik:RadGridView xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"   
                    Grid.Column="3" Grid.Row="0" 
                    AutoGenerateColumns="False" CanUserFreezeColumns="False"   
                    CanUserSortColumns="True" 
                    CanUserInsertRows="True" 
                    ShowGroupPanel="False" 
                    x:Name="uxRad4GridView" UseAlternateRowStyle="False" telerik:StyleManager.Theme="Office_Black">  
                <telerik:RadGridView.Columns> 
                    <telerik:GridViewDataColumn IsFilterable="False" DataMemberBinding="{Binding Name}" /> 
                    <telerik:GridViewDataColumn IsFilterable="False" DataMemberBinding="{Binding City}"/>  
                    <telerik:GridViewDataColumn IsFilterable="False" DataMemberBinding="{Binding Country}"/>  
                </telerik:RadGridView.Columns> 
            </telerik:RadGridView> 
            <telerik:RadGridView xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"   
                    Grid.Column="3" Grid.Row="1" 
                    AutoGenerateColumns="False" CanUserFreezeColumns="False"   
                    CanUserSortColumns="True" 
                    CanUserInsertRows="True" 
                    ShowGroupPanel="False" 
                    x:Name="uxRad5GridView" UseAlternateRowStyle="False" telerik:StyleManager.Theme="Office_Black">  
                <telerik:RadGridView.Columns> 
                    <telerik:GridViewDataColumn IsFilterable="False" DataMemberBinding="{Binding AreaCode}" /> 
                    <telerik:GridViewDataColumn IsFilterable="False" DataMemberBinding="{Binding Number}"/>  
                </telerik:RadGridView.Columns> 
            </telerik:RadGridView> 
        </Grid> 
    </Grid> 
     
    using System.Collections.ObjectModel;  
    using System.ComponentModel;  
     
    public class Customer : INotifyPropertyChanged  
    {
        #region fields  
        private string _name;  
        private string _country;  
        private string _city;  
        private ObservableCollection<Phone> _phoneNumbers;
        #endregion  
     
        #region ctor  
        public Customer()  
        {  
            _phoneNumbers = new ObservableCollection<Phone>();  
        }  
     
        public Customer(string name, string country, string city)  
        {  
            _name = name;  
            _country = country;  
            _city = city;  
            _phoneNumbers = new ObservableCollection<Phone>();  
        }  
     
        public Customer(string name, string country, string city, ObservableCollection<Phone> phoneNumbers)  
        {  
            _name = name;  
            _country = country;  
            _city = city;  
            _phoneNumbers = phoneNumbers;  
        }
        #endregion  
     
        #region properties  
        public string Name  
        {  
            get { return _name; }  
            set 
            {  
                _name = value;  
                NotifyPropertyChanged("Name");  
            }  
        }  
     
        public string City  
        {  
            get { return _city; }  
            set 
            {  
                _city = value;  
                NotifyPropertyChanged("City");  
            }  
        }  
     
        public string Country  
        {  
            get { return _country; }  
            set 
            {  
                _country = value;  
                NotifyPropertyChanged("Country");  
            }  
        }  
     
        public ObservableCollection<Phone> PhoneNumbers  
        {  
            get { return _phoneNumbers; }  
            set 
            {  
                _phoneNumbers = value;  
                NotifyPropertyChanged("PhoneNumbers");  
            }  
        }
        #endregion  
     
        #region Interface INotifyPropertyChanged  
        public event PropertyChangedEventHandler PropertyChanged;  
     
        private void NotifyPropertyChanged(string propertyName)  
        {  
            if (PropertyChanged != null)  
                PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
        }
        #endregion  
    }  
     
    public class Phone : INotifyPropertyChanged  
    {
        #region fields  
        private string _areaCode;  
        private string _number;
        #endregion  
     
        #region ctor  
        public Phone()  
        {  
     
        }  
     
        public Phone(string areaCode, string number)  
        {  
            _areaCode = areaCode;  
            _number = number;  
        }
        #endregion  
     
        #region properties  
        public string AreaCode  
        {  
            get { return _areaCode; }  
            set 
            {  
                _areaCode = value;  
                NotifyPropertyChanged("AreaCode");  
            }  
        }  
     
        public string Number  
        {  
            get { return _number; }  
            set 
            {  
                _number = value;  
                NotifyPropertyChanged("Number");  
            }  
        }
        #endregion  
     
        #region Interface INotifyPropertyChanged  
        public event PropertyChangedEventHandler PropertyChanged;  
     
        private void NotifyPropertyChanged(string propertyName)  
        {  
            if (PropertyChanged != null)  
                PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
        }
        #endregion  
    }  
     
    using System;  
    using System.Collections.ObjectModel;  
    using System.Windows;  
    using System.Windows.Controls;  
    using System.Windows.Data;  
    using Telerik.Windows.Controls;  
     
    /// <summary>  
    /// Interaction logic for Window5.xaml  
    /// </summary>  
    public partial class Window5 : Window  
    {  
        public Window5()  
        {  
            InitializeComponent();  
     
            Binding binding;
            #region ListView.  Works by using IsSynchronizedWithCurrentItem  
            ObservableCollection<Customer> list2 = CreateList();  
            binding = new Binding();  
            binding.Source = list2;  
            uxListView1.IsSynchronizedWithCurrentItem = true;  
            uxListView1.SetBinding(ListView.ItemsSourceProperty, binding);  
     
            binding = new Binding();  
            binding.Source = list2;  
            binding.Path = new PropertyPath("PhoneNumbers");  
            uxListView2.IsSynchronizedWithCurrentItem = true;  
            uxListView2.SetBinding(ListView.ItemsSourceProperty, binding);
            #endregion  
     
            ObservableCollection<Customer> list4 = CreateList();  
            binding = new Binding();  
            binding.Source = list4;  
            //uxRad4GridView.IsSynchronizedWithCurrentItem = true;   // Doesn't seem to be supported.  
            uxRad4GridView.SelectionChanged += new EventHandler<SelectionChangeEventArgs>(uxRad4GridView_SelectionChanged);  // Using this instead of IsSynchronizedWithCurrentItem  
            uxRad4GridView.SetBinding(RadGridView.ItemsSourceProperty, binding);  
     
            /// No point in binding it, as IsSynchronizedWithCurrentItem isn't supported.  
            //binding = new Binding();  
            //binding.Source = list4;  
            //binding.Path = new PropertyPath("PhoneNumbers");  
            //uxRad5GridView.IsSynchronizedWithCurrentItem = true;      // Doesn't seem to be supported.  
            //uxRad5GridView.SetBinding(RadGridView.ItemsSourceProperty, binding);  
        }  
     
        void uxRad4GridView_SelectionChanged(object sender, SelectionChangeEventArgs e)  
        {  
            /// When the user holds "ctrl" to unselect a row, we must clear the secondary Grid.  
            /// This however causes an exception to occur the second time a Row is unselected.  
            if (uxRad4GridView.SelectedItem == null)  
            {  
                uxRad5GridView.ClearValue(RadGridView.ItemsSourceProperty);  
            }  
            else 
            {  
                Binding binding = new Binding();  
     
                binding.Source = uxRad4GridView.SelectedItem;  
                binding.Path = new PropertyPath("PhoneNumbers");  
                uxRad5GridView.SetBinding(RadGridView.ItemsSourceProperty, binding);  
            }  
        }  
     
     
        private ObservableCollection<Customer> CreateList()  
        {  
            ObservableCollection<Customer> customers = new ObservableCollection<Customer>();  
            customers.Add(new Customer("John""USA""Chicago"new ObservableCollection<Phone>(new Phone[] { new Phone("XX""1234"), new Phone("XX""5678") })));  
            customers.Add(new Customer("Tim""USA""NY"new ObservableCollection<Phone>(new Phone[] { new Phone("AA""2345"), new Phone("AA""6789") })));  
            customers.Add(new Customer("Jeff""USA""W.D.C"new ObservableCollection<Phone>(new Phone[] { new Phone("ZZ""3456"), new Phone("ZZ""7890") })));  
            customers.Add(new Customer("Zhang""China""Shanghai"new ObservableCollection<Phone>(new Phone[] { new Phone("BB""4567"), new Phone("BB""8901") })));  
            customers.Add(new Customer("Li""China""Beijing"new ObservableCollection<Phone>(new Phone[] { new Phone("YY""5678"), new Phone("YY""9012") })));  
            customers.Add(new Customer("Wang""China""HongKong"new ObservableCollection<Phone>(new Phone[] { new Phone("CC""6789"), new Phone("CC""0123") })));  
            return customers;  
        }  
    }  
     






  2. Milan
    Admin
    Milan avatar
    1989 posts

    Posted 26 Nov 2009 Link to this post

    Hi Chris,

    I was not able to reproduce the exception and I am sending you the application that I used. Maybe I have missed something although I have copied all of the code that you have provided.

    I would like to ask you if you are using the official release assemblies or a more recent version - for example assemblies from our latest internal build?

    In regard to the IsSynchronizedWithCurrent property, we have plans to implement it and there is a slight change that this property will be introduced with the the upcoming service pack.



    Best wishes,
    Milan
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Chris
    Chris avatar
    20 posts
    Member since:
    Nov 2009

    Posted 03 Dec 2009 Link to this post

    Hi Milan.

    I've retested the issue, and it seems to have gone away.  I'm not sure why.  I've retested with a number of versions of the recent Telerik releases, and the exception is not there.
    I guess Visual Studio was having a bad day.  I don't remember restarting Visual Studio that particular day when testing the Multi Collection scenario.  I have observed on occassion Visual Studio will encouner some error when developing WPF applications, and when the application is run under Visual Studio (both debugging and not), the application will throw an unusual exception in the locations where an exception shouldn't occur.

    Thanks for you time on this.

    As for the IsSynchronizedWithCurrent property.  We are most interested in seeing this in the near future.

    Regards,
    Chris.
  5. Peter Taylor
    Peter Taylor avatar
    4 posts
    Member since:
    Dec 2009

    Posted 11 Jan 2010 Link to this post

    Hi

    Did you manage to include IsSynchronizedWithCurrentItem in the Service Pack for Q3 2009?

    Regards
  6. Milan
    Admin
    Milan avatar
    1989 posts

    Posted 12 Jan 2010 Link to this post

    Hello Peter Taylor,

    We will not be able to introduce this property with our upcoming service pack but fortunately it will be available in our 2010 Q1 release.


    Regards,
    Milan
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  7. Hidayet ÇELEN
    Hidayet ÇELEN avatar
    10 posts
    Member since:
    Apr 2010

    Posted 26 Feb 2011 Link to this post

    Hi,

    I want to add textbox which filter values in radgridview(columns) like your 'search As you Type' sample. I am using now latest Q1 2011 Beta.There is one different from your sample , is radgridview={Binding}" and binds in page initialization to a DATASET.

    I tried maybe 20 times with different ways, first 15 is not filtering (but gridview seems refresh something) , after than 15 project fails with 'Cannot change ObservableCollection during a CollectionChanged Event.' I rollbacked changes and try again but always that error.

    Everything same ( as 15 times experiments) , but now the error occurs.

    What can I do now? Does the problem depend on my faults or Beta version?

    Thanks.
Back to Top
UI for WPF is Visual Studio 2017 Ready