Dynamically set RadComboBox ItemsSource

5 posts, 1 answers
  1. Mattias
    Mattias avatar
    8 posts
    Member since:
    Dec 2011

    Posted 20 Jan 2012 Link to this post

    A combobox in my gridview needs to have different ItemsSource depending on the value of another column.
    I've tried to solve this by listening on the gridview's PreparingCellForEdit event:
    private void RadGridView_PreparingCellForEdit(object sender, GridViewPreparingCellForEditEventArgs e)  
    {  
        switch (e.column.Name) 
        
            case "MyDynamicColumn"
                var combobox = e.EditingElement as RadComboBox;  
                combobox.ItemsSource = List<string> { "1", "2", "3" }; //TODO: Replace with some dynamic business logic here  
                combobox.SetBinding(RadComboBox.SelectedValueProperty, "MyComboValue");   
                break
            
        
    }

    ...and this kind-of works. The combobox displays its SelectedValue once it is selected and the dropdown shows the correct list of values.

    However, when the combobox is not in edit-mode, it looks empty. I'd like to bind a TextBlock with the SelectedValue for display, but don't know how to accomplish that.

    Any thoughts would be appreciated.
  2. Answer
    Vlad
    Admin
    Vlad avatar
    11100 posts

    Posted 20 Jan 2012 Link to this post

    Hi,

     It will be better if you create custom column, override CreateCellElement/CreateCellEditElement and create/bind the combo in the way you want. 

    Regards,
    Vlad
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. Mattias
    Mattias avatar
    8 posts
    Member since:
    Dec 2011

    Posted 20 Jan 2012 Link to this post

    Thanks for your input. This works fine.

    For future documentation, in case others have the same problem, this is what I've done:

    using System;
    using System.Windows;
    using Telerik.Windows.Controls;
    using Telerik.Windows.Controls.GridView;
      
    namespace MyProject.Helpers
    {
        public class CellElementCreatedEventArgs : EventArgs
        {
            public GridViewCell Cell { get; set; }
            public GridViewColumn Column { get; set; }
            public FrameworkElement Element { get; set; }
            public object DataItem { get; set; }
        }
      
        public class DynamicComboBoxColumn : GridViewComboBoxColumn
        {
            public event EventHandler<CellElementCreatedEventArgs> CellElementCreated;
            protected void OnCellElementCreated(CellElementCreatedEventArgs e)
            {
                if (CellElementCreated != null)
                    CellElementCreated(this, e);
            }
      
            public override System.Windows.FrameworkElement CreateCellElement(GridViewCell cell, object dataItem)
            {
                var element = base.CreateCellElement(cell, dataItem);
                var e = new CellElementCreatedEventArgs { Cell = cell, Column = cell.Column, Element = element, DataItem = dataItem };
                OnCellElementCreated(e);
                return element;
            }
      
            public override System.Windows.FrameworkElement CreateCellEditElement(GridViewCell cell, object dataItem)
            {
                var element = base.CreateCellEditElement(cell, dataItem);
                var e = new CellElementCreatedEventArgs { Cell = cell, Column = cell.Column, Element = element, DataItem = dataItem };
                OnCellElementCreated(e);
                return element;
            }
        }
    }

    And then added GridView to xaml-page:

    <telerik:RadGridView ItemsSource="{Binding GridViewItemsSource}" AutoGenerateColumns="False">
        <telerik:RadGridView.Columns>
            <telerik:GridViewDataColumn Header="Id" DataMemberBinding="{Binding ID}"/>
            <helpers:DynamicComboBoxColumn Header="Dynamic 1" x:Name="Dynamic1" 
                    DataMemberBinding="{Binding DynValue1}" 
                    CellElementCreated="RadGridView_CellElementCreated"/>
            <helpers:DynamicComboBoxColumn Header="Dynamic 2" x:Name="Dynamic2" 
                    DataMemberBinding="{Binding DynValue2}" 
                    CellElementCreated="RadGridView_CellElementCreated"/>
        </telerik:RadGridView.Columns>
    </telerik:RadGridView>
    (Don't forget to add xmlns:helpers="clr-namespace:MyProject.Helpers" to the top of the xaml-page)

    And finally in the xaml code-behind:

    private void RadGridView_CellElementCreated(object sender, CellElementCreatedEventArgs e)
    {
        var rowItem = e.DataItem as MyData;
        switch (e.Column.Name)
        {
            case "Dynamic1":
                SetItemsSource(e.Element, (this.DataContext as MyViewModel).GetDynData1(rowItem.ID));
                break;
            case "Dynamic2":
                SetItemsSource(e.Element, (this.DataContext as MyViewModel).GetDynData2(rowItem.ID));
                break;
        }
    }
      
    /// <summary>
    /// Sets the ItemsSource dynamically for Netting.Helpers.DynamicComboBoxColumn's
    /// </summary>
    /// <param name="element"></param>
    /// <param name="itemsSource"></param>
    void SetItemsSource(FrameworkElement element, IEnumerable itemsSource)
    {
        if (element is LookupElement)
        {
            (element as LookupElement).ItemsSource = itemsSource;
        }
        else if (element is ItemsControl)
        {
            var oldBinding = element.GetBindingExpression(Selector.SelectedValueProperty);
            (element as ItemsControl).ItemsSource = itemsSource;
            if (oldBinding != null)
                element.SetBinding(Selector.SelectedValueProperty, oldBinding.ParentBinding.Path.Path);
        }
        else
            throw new NotSupportedException();
    }
  4. Guillaume
    Guillaume avatar
    2 posts
    Member since:
    Jan 2013

    Posted 28 Feb 2013 Link to this post

    Hi,
    I'm using Mattias solution to get a GridViewComboBoxColumn cell to bind to a dynamic collection. My GridView is inside a Tabcontrol. The first time the GridView is displayed, my GridViewComboBoxColumn cell displays the selected item correctly. But when I switch tab and come back on the GridView, the GridViewComboBoxColumn cell doesn't display the selected item. If I click that cell for editing, the selected item is displayed.

    Any idea on how to fix this problem? Should I use another method to link GridViewComboBoxColumn to a dynamic collection?

    I'm using Telerik WPF Q2 2012.

    Thanks

  5. Yoan
    Admin
    Yoan avatar
    1182 posts

    Posted 05 Mar 2013 Link to this post

    Hi Guillaume,

    Can you please check this troubleshooting article on this matter. I hope you find it useful. 

    Regards,
    Yoan
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top