DataTemplate’s RadComboBox SelectedValue binding not working

2 posts, 0 answers
  1. EDGAR JIMENEZ
    EDGAR JIMENEZ avatar
    8 posts
    Member since:
    Apr 2010

    Posted 24 Feb 2012 Link to this post

     

    When applying a DataTemplate in the code behind(and view model) that
    contains a RadComboBox to an instance of DataFormComboBoxField,
    that DataTemplate’s RadComboBox’s  SelectedValue binding does not
    work. If however, that same code is used without applying the
    DataTemplate (which includes having the bindings and properties
    of the “standard/default” ComboBox that is part of the default
    DataFormComboBoxField set explicitly), everything works fine.
    This implies that code is proper
    constructed, but something else is going on when the DataTemplate
    is applied.

    We need to set the bindings in the code behind or view model
    because we are dealing with dynamic data, and we won’t know
    the properties to bind to until runtime.

    Note: Not able to attach the Project due to the size of the files. The xaml code, code behind and the ViewModel code has been pasted below.

    Page.xaml:

     

    <UserControl x:Class="RadGridView_SL4_AR_236.MainPage"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

    xmlns:my="clr-namespace:RadGridView_SL4_AR_236"

    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"

    d:DesignHeight="700"

    d:DesignWidth="700"

    mc:Ignorable="d">

    <UserControl.Resources>

    <my:MyViewModel x:Key="MyViewModel" />

    <DataTemplate x:Key="AuditTemplate">
    <Grid>

    <Grid.RowDefinitions>
    <RowDefinition />

    </Grid.RowDefinitions>

    <P><Grid.ColumnDefinitions></P>
    <P><BR><ColumnDefinition /></P>
    <P><BR><ColumnDefinition Width="Auto" MinWidth="50" /></P>
    <P><ColumnDefinition Width="Auto" MinWidth="50" /></P>
    <P></Grid.ColumnDefinitions></P>

     

    <telerik:RadComboBox x:Name="Combo" />

    <CheckBox Grid.Row="0"
    Grid.Column="1"

    Width="Auto"

    Margin="3,0,3,0"

    HorizontalAlignment="Left"

    VerticalAlignment="Center"
    Content="Verified">

    <CheckBox.Height>

     

    <Binding ElementName="Combo" Path="Height" />
    </CheckBox.Height>
    </CheckBox>
    <Button Grid.Row="0"

    Grid.Column="2"
    Width="Auto"

    Margin="3,0,3,0"

    HorizontalAlignment="Left"

    VerticalAlignment="Center">

    <Button.Content>

    <Binding ElementName="Combo" Path="Name" />

    </Button.Content>
    </Button>

    </Grid>

    </DataTemplate>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot"
    Background="White"

    DataContext="{StaticResource MyViewModel}">

    <telerik:RadDataForm Name="clubsForm"

    Margin="5"
    AutoGeneratingField="ClubsFormAutoGeneratingField"
    ItemsSource="{Binding Clubs}"
    ScrollViewer.HorizontalScrollBarVisibility="Auto" />
    </Grid>
    </UserControl>

    ------------------------------

    page.cs

        public partial class MainPage
        {
            public MainPage()
            {
                InitializeComponent();
            }

            private void ClubsFormAutoGeneratingField(object sender, AutoGeneratingFieldEventArgs e)
            {
                if (e.PropertyName == "Location")
                {
                    e.DataField = new DataFormComboBoxField
                                      {
                                          ItemsSource = Club.GetLocations(),
                                          SelectedValuePath = "LocationId",
                                          DisplayMemberPath = "City",
                                          DataMemberBinding =
                                              new Binding("Location") {Mode = BindingMode.TwoWay},
                                          Label = "Location",
                                          //when the ContentTemplate is set, the ComboBox no longer binds the SelectedValue property to the target property
                                          //when the ContentTemplate is NOT set, the (re)binding works fine proving that the binding is at least specified correctly
                                          ContentTemplate = Resources["AuditTemplate"] as DataTemplate
                                      };

                    e.DataField.Loaded += delegate(object o, RoutedEventArgs eventArgs)
                                              {
                                                  var field = o as DataFormComboBoxField;
                                                  foreach (
                                                      DependencyObject child in field.ChildrenOfType<DependencyObject>())
                                                  {
                                                      var comboBox = child as RadComboBox;

                                                      if (comboBox != null)
                                                      {
                                                          //if this is not set and used, when the binding happens on the SelectedValue property, it is set to null
                                                          //I don't know what this is the case - this looks to me like incorrect behavior
                                                          var selectedIndex = comboBox.SelectedIndex;
                                                          comboBox.ItemsSource = Club.GetLocations();
                                                          comboBox.SelectedValuePath = "LocationId";
                                                          comboBox.DisplayMemberPath = "City";
                                                          comboBox.SelectedValue = new Binding("Location") { Mode = BindingMode.TwoWay };
                                                        
                                                          //set the original selected item after binding - again - not sure why this is the case?
                                                          comboBox.SelectedIndex = selectedIndex;
                                                      }
                                                  }
                                              };
                }
            }
        }

     

     

    ViewModel:

    public class MyViewModel : INotifyPropertyChanged
        {
            private ObservableCollection<Club> _clubs;
            private object _selectedItem;

            public ObservableCollection<Club> Clubs
            {
                get
                {
                    if (_clubs == null)
                    {
                        _clubs = Club.GetClubs();
                    }

                    return _clubs;
                }
            }

            public object SelectedItem
            {
                get { return _selectedItem; }
                set
                {
                    if (value != _selectedItem)
                    {
                        _selectedItem = value;
                        OnPropertyChanged("SelectedItem");
                    }
                }
            }

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            #endregion

            protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, args);
                }
            }

            private void OnPropertyChanged(string propertyName)
            {
                OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
            }
        }

     

     

     

  2. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 27 Feb 2012 Link to this post

    Hello Edgar,

    Please create binding for SelectedValue property instead:

    private void ClubsFormAutoGeneratingField(object sender, AutoGeneratingFieldEventArgs e)
            {
                if (e.PropertyName == "Location")
                {
                    e.DataField = new DataFormComboBoxField{
                        ItemsSource = Club.GetLocations(),
                        SelectedValuePath = "LocationId",
                        DisplayMemberPath = "City",
                        DataMemberBinding = new Binding("Location") {Mode = BindingMode.TwoWay},
                        Label = "Location",
                        ContentTemplate = Resources["AuditTemplate"] as DataTemplate
                    };
     
                    e.DataField.Loaded += delegate(object o, RoutedEventArgs eventArgs)
                    {
                        var field = o as DataFormComboBoxField;
                        foreach (RadComboBox child in field.ChildrenOfType<RadComboBox>())
                        {
                            var comboBox = child as RadComboBox;
     
                            if (comboBox != null)
                            {                      
                                comboBox.ItemsSource = Club.GetLocations();
                                comboBox.SelectedValuePath = "LocationId";
                                comboBox.DisplayMemberPath = "City";
                                comboBox.SetBinding(RadComboBox.SelectedValueProperty, new Binding("Location") { Mode = BindingMode.TwoWay });                     
                            }
                        }
                    };
                }

    I hope it helps. 


    Kind regards,
    Maya
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. DevCraft banner
Back to Top