【发布时间】:2021-09-24 13:40:42
【问题描述】:
我试图显示一个 ComboBox,其 ItemsSource 是控件的集合(它是 PropertyGrid 的一部分,ComboBox 应该显示控件的名称,并且用户应该能够选择其中一个控件)。这是问题的极其简化的再现:
<ComboBox ItemsSource="{Binding GroupBoxes}" SelectedValue="{Binding SelectedGroupBox}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
GroupBoxes 和 SelectedGroupBox 是 ObservableCollection 和 GroupBox 类型的 DependencyProperties。
绑定起作用 - 控件名称显示在 ComboBox-DropDown 中,如果我选择不同的项目,我可以看到 SelectedGroupBox 属性已正确更新。问题:所选项目永远不会显示在 ComboBox 中。从代码中设置 SelectedGroupBox 属性也可以按预期工作 - ComboBox 引发 SelectionChanged 并且其 SelectedValue 是正确的,但它仍然不显示当前值。
如果我对任何其他类型的课程做同样的事情,一切都会按预期进行。
在寻找答案的过程中,我遇到了很多人的帖子,他们有类似的声音问题,但几乎所有帖子都是绑定问题,而这里不是这样。
编辑:
为了简化试用,下面是代码。只需将上面的 XAML 放到一个新的 Window 中,下面的代码放在后面的代码中。
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
【问题讨论】:
-
如果您只使用 {Binding} 而不是 {Binding Name} 它会起作用并显示控件的默认 ToString 方法结果吗?
-
不,它不会改变任何东西;它显示 ToString()-content 而不是 DropDown 中的 Name 但仍然存在不可见 SelectedValue 的问题。
-
你的
WPF Trace Settings都打开了吗?这些默认情况下是关闭的。 Visual Studio 吃掉了很多 WPF 警告和错误。 -
我把它们都打开了,但没有问题。