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

DataTemplate’s RadComboBox SelectedValue binding not working

1 Answer 381 Views
DataForm
This is a migrated thread and some comments may be shown as answers.
EDGAR JIMENEZ
Top achievements
Rank 1
EDGAR JIMENEZ asked on 24 Feb 2012, 06:57 PM

 

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));
        }
    }

 

 

 

1 Answer, 1 is accepted

Sort by
0
Maya
Telerik team
answered on 27 Feb 2012, 08:59 AM
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 >>
Tags
DataForm
Asked by
EDGAR JIMENEZ
Top achievements
Rank 1
Answers by
Maya
Telerik team
Share this question
or