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