I am trying to show a ComboBox whose ItemsSource is a collection of Controls (it is part of a PropertyGrid, the ComboBox should display the names of the controls, and the user should be able to select one of the controls). Here is an extremely simplified reproduction of the problem:
<ComboBox ItemsSource="{Binding GroupBoxes}" SelectedValue="{Binding SelectedGroupBox}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
GroupBoxes and SelectedGroupBox are DependencyProperties of type ObservableCollection and GroupBox.
The Bindings work - the control names are displayed in the ComboBox-DropDown, and if I select a different item I can see that the SelectedGroupBox property is updated correctly. The problem: the selected item is never displayed in the ComboBox. Setting the SelectedGroupBox property from code also works as expected - the ComboBox raises SelectionChanged and its SelectedValue is correct, but it still doesn't display the current value.
If I do the exact same thing with any other type of class, everything works as expected.
Searching for an answer I came across many posts from people having similar sounding problems, but almost all of them were Binding proplems which is not the case here.
Edit:
To simplify trying it out, here's the code behind. Just drop the above XAML in a new Window, and the code below in the code behind.
public MainWindow() {
InitializeComponent();
this.DataContext = this;
this.GroupBoxes = new ObservableCollection<GroupBox>();
this.GroupBoxes.Add(new GroupBox() { Name = "AAA", Header = "AAA", Height = 100, Background = Brushes.Purple });
this.GroupBoxes.Add(new GroupBox() { Name = "BBB", Header = "BBB", Height = 100, Background = Brushes.Purple });
this.GroupBoxes.Add(new GroupBox() { Name = "CCC", Header = "CCC", Height = 100, Background = Brushes.Purple });
this.GroupBoxes.Add(new GroupBox() { Name = "DDD", Header = "DDD", Height = 100, Background = Brushes.Purple });
this.GroupBoxes.Add(new GroupBox() { Name = "EEE", Header = "EEE", Height = 100, Background = Brushes.Purple });
}
#region GroupBoxesProperty
public static readonly DependencyProperty GroupBoxesProperty = DependencyProperty.Register(
"GroupBoxes", typeof(ObservableCollection<GroupBox>), typeof(MainWindow)
);
public ObservableCollection<GroupBox> GroupBoxes {
get { return (ObservableCollection<GroupBox>)GetValue(GroupBoxesProperty); }
set { SetValue(GroupBoxesProperty, value); }
}
#endregion
#region SelectedGroupBoxProperty
public static readonly DependencyProperty SelectedGroupBoxProperty = DependencyProperty.Register(
"SelectedGroupBox", typeof(GroupBox), typeof(MainWindow),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (s, e) => (s as MainWindow).OnSelectedGroupBoxChanged())
);
public GroupBox SelectedGroupBox {
get { return (GroupBox)GetValue(SelectedGroupBoxProperty); }
set { SetValue(SelectedGroupBoxProperty, value); }
}
void OnSelectedGroupBoxChanged() {
Console.WriteLine("selection is now " + this.SelectedGroupBox.Name);
}
#endregion
See Question&Answers more detail:
os