Binding not working for GridViewComboBoxColumn

8 posts, 1 answers
  1. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 31 Jan 2018 Link to this post

    I see the datatype instead of the values I should see..

    using System.ComponentModel;
     
    namespace TelerikGridViewTests.Models
    {
        public class CarsViewModel : ViewModelBase
        {
            public CarsViewModel()
            {
                _cars = new BindingList<CarViewModel>();
     
                _cars.Add(new CarViewModel()
                {
                    Id = 0m,
                    Description = "Ford",
                    Colors = new ColorsViewModel().Colors,
                });
     
                _cars.Add(new CarViewModel()
                {
                    Id = 1m,
                    Description = "Chevy",
                    Colors = new ColorsViewModel().Colors,
                });
     
                _cars.Add(new CarViewModel()
                {
                    Id = 2m,
                    Description = "Dodge",
                    Colors = new ColorsViewModel().Colors,
                });
            }
     
            BindingList<CarViewModel> _cars;
            public BindingList<CarViewModel> Cars { get { return _cars; } set { _cars = value; } }
        }
     
        public class CarViewModel : ViewModelBase
        {
            public decimal Id { get; set; }
            public string Description { get; set; }
     
            BindingList<ColorViewModel> _colors;
            public BindingList<ColorViewModel> Colors
            {
                get { return _colors; }
                set { _colors = value; }
            }
        }
     
        public class ColorsViewModel : ViewModelBase
        {
            public ColorsViewModel()
            {
                Colors = new BindingList<ColorViewModel>();
     
                Colors.Add(new ColorViewModel()
                {
                    Id = 1,
                    Color = "Blue",
                });
                Colors.Add(new ColorViewModel()
                {
                    Id = 2,
                    Color = "Red",
                });
                Colors.Add(new ColorViewModel()
                {
                    Id = 3,
                    Color = "Green",
                });
                Colors.Add(new ColorViewModel()
                {
                    Id = 4,
                    Color = "Yellow",
                });
            }
     
            public BindingList<ColorViewModel> Colors { get; set; }
        }
     
        public class ColorViewModel : ViewModelBase
        {
            public int Id { get; set; }
            public string Color { get; set; }
        }
    }

     

    Here is where I bind...

    public Form1()
    {
        InitializeComponent();
     
        BindingList<CarViewModel> _cars = new CarsViewModel().Cars;
        radGridView1.DataSource = _cars;
    }

     

    I've set the DisplayMember of the column to "Color", the ValueMember to "Id" and the DataType to "System.ComponentModel.BindingList`1[TelerikGridViewTests.Models.ColorViewModel]"  Instead of seeing the colors in the combobox I see "System.ComponentModel.BindingList`1[TelerikGridViewTests.Models.ColorViewModel]" instead.  See attached screens.

  2. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 31 Jan 2018 Link to this post

    sorry, this is a continuation of another issue I entered. The webpage was locking up and I didn't think the forum entry was entered since it was not in the list.  anyway, the issue is a combination of my last 2 entries in this forum talking about "binding and the gridviewcomboboxcolumn"
  3. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 31 Jan 2018 in reply to Chris Kirkman Link to this post

    I should mention that when I manually create a column in code-behind and then bind directly to an instance of a BindingList<myobject> it works.  That won't work for me though, since I will have a different set of values inside each drop down (for my real app).
  4. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3770 posts

    Posted 01 Feb 2018 Link to this post

    Hello, Chris,  

    Thank you for writing back. 

    I suppose that you use a GridViewComboBoxColumn. Let me please explain how does this column work. It is necessary to set the GridViewComboBoxColumn.DataSource property in order to specify the collection with the available options for this column, e.g. a list of custom objects. Then, set the GridViewComboBoxColumn.DisplayMember property to indicate which property of the custom objects you will be displayed in the grid cells, set the GridViewComboBoxColumn.ValueMember property to specify which property of the custom objects will be stored in the cells' values. Consider the following example: you have a class Person containing Id and Name properties. The GridViewComboBoxColumn.DisplayMember property is set to Name, the GridViewComboBoxColumn.ValueMember property is set to Id. The DataSource is set to a list of Person objects. Then, the grid cells belonging to this columns should contain the Id values, not the Person object itself. Otherwise, the column won't match the values properly. In your case RadGridView is bound to a collection CarViewModel records. The CarViewModel has 3 properties: a numeric Id, a string Description and a collection of ColorViewModel objects. The third property doesn't return a single record but a whole collection. Hence, you can use this collection to populate a separate column with data explicitly specifying the column's DataSource to the cell's value. I have prepared a sample project for your reference demonstrating better how to handle this case with populating the combo column. However, have in mind that need to store the color selection in a separate property because otherwise you can't store it since you have only a collection. The achieved behavior is illustrated in the following screenshot:


    I hope this information helps. If you have any additional questions, please let me know. 

     Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 01 Feb 2018 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    I think I wasn't as clear as I needed to be.  In your example you're binding the DataSource of the GridViewComboBoxColumn to the BindingList<ColorViewModel> for the 1st item in my radGridView1.DataSource.  I need each row in the GridView to have a different set of items in the GridViewComboBoxColumn.  I.e. Red, Blue, Green in one row.  Yellow, Brown, Purpose in another.  Pink, Magenta, Red in another.  Does that make sense?  In other words, the reason I have a property in my model which is of type BindingList<ColorViewModel> is so I can do what I'm explaining above.
  6. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3770 posts

    Posted 02 Feb 2018 Link to this post

    Hello, Chris,

    Thank you for writing.  

    The provided explanation is greatly appreciated. Yes, it does make sense. In order to achieve it you still have to set the GridViewComboBoxColumn.DataSource property but it is necessary to set it to a collection which contains all possible options (all colors in your case). Then, handle the CellEditorInitialized event where you can assign the RadDropDownListEditorElement.DataSource property to a subset of all colors considering the stored list in the current row. In order words, bind the column to a full colors list and restrict the list for each row by assigning a subset of the list for the editor per row. 

    The following KB article demonstrates a similar approach to control the drop dow list per row however it is considered a neighboring cell's value instead: https://www.telerik.com/support/kb/winforms/gridview/details/cascading-comboboxes-in-radgridview

    I hope this information helps. Should you have further questions I would be glad to help. 
     
     Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  7. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 02 Feb 2018 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    There is an unfortunate flaw in your suggested approach.  The example project I provided was a simple test app to test functionality, it's not my real application.  The data that would go in to the drop down can't be prefilled and then filtered down to a subset per row.  This is because in my case there could be 1,000,000+ records that would go in to this master list of items.  I was able to take a different approach yesterday where I abandoned the idea of using a drop down.  Instead I used as a TextBox column and then used the EditorRequired event to bind the datasource for the current row to the values required to be displayed for the row.  This method still behaves as if the column is a drop down without actually being one.  See below...

     

    private void MyGridEditorRequired(object sender, EditorRequiredEventArgs e)
    {
        if (MyGrid.CurrentColumn.Name == "ColumnToShowList")
        {
            RadDropDownListEditor editor = new RadDropDownListEditor();
            RadDropDownListEditorElement element = editor.EditorElement as RadDropDownListEditorElement;
            element.DropDownStyle = RadDropDownStyle.DropDownList;
            element.DataSource = ((MyModel)MyGrid.CurrentRow.DataBoundItem).MyPropertyWithListOfValues;
            element.DisplayMember = "Id";
            e.Editor = editor;
        }
    }

     

    Technically, I could use my approach to putting anything I want in the "drop down".  Using this strategy I could conceivably put a list of colors in one row, a list of sizes in another, a list of countries in another, the list goes on.

     

  8. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3770 posts

    Posted 02 Feb 2018 Link to this post

    Hello, Chris,  

    Thank you for writing back. 

    Indeed, filling 1,000,000+ records in the GridViewComboBoxColumn will be a very heavy operation for RadGridView. Having this information now, I can confirm that the approach with a simple GridViewTextBoxColumn and specifying that a RadDropDownListEditor will be used with the relevant options loaded in the editor per row is the suitable approach for handling this case. The provided code snippet looks OK. Feel free to use it with any collection that you need per each row.

    I hope this information helps. If you have any additional questions, please let me know. 

     Regards,
    Dess
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top