WPF ListBox ListBoxItem绑定

时间:2012-03-17 21:51:30

标签: wpf binding listbox selecteditem listboxitem

我正在阅读Sams的书“24小时自学WPF”。作者一度展示了如何将ListBox的选定项值绑定到属性。我明白了,这很简单。但是当我尝试使用自己的ListBoxItems创建自己的ListBox控件时,我似乎无法让它工作。

有效的ListBox使用系统集合作为其ItemsSource属性:

<ListBox x:Name="FontList"
         DockPanel.Dock="Left"
         ItemsSource="{x:Static Fonts.SystemFontFamilies}"
         Width="160" />

然后在TextBlock中使用从此ListBox中选择的值,如下所示:

<TextBlock Text="Test" 
           FontFamily="{Binding ElementName=FontList, Path=SelectedItem}"
           TextWrapping="Wrap"
           Margin="0 0 0 4" />

请注意,Path设置为SelectedItem。

现在,我想使用另一个包含3种不同大小的ListBox来设置FontSize。这是我做的:

<ListBox x:Name="Size" >
    <ListBoxItem>10</ListBoxItem>
    <ListBoxItem>15</ListBoxItem>
    <ListBoxItem>20</ListBoxItem>
</ListBox>

然后我添加了一个绑定到TextBox的Size属性,如下所示:

<TextBlock Text="Test" 
           FontFamily="{Binding ElementName=FontList, Path=SelectedItem}"
           Size="{Binding ElementName=Size, Path=SelectedItem}"
           TextWrapping="Wrap"
           Margin="0 0 0 4" />

运行程序时,大小不会改变。所以我尝试将我用于Size的绑定添加到Text属性 - 以便查看其值:

<TextBlock Text="{Binding ElementName=Size, Path=SelectedItem}"" 
           FontFamily="{Binding ElementName=FontList, Path=SelectedItem}"
           Size="{Binding ElementName=Size, Path=SelectedItem}"
           TextWrapping="Wrap"
           Margin="0 0 0 4" />

我看到它正在改变,因为我单击Size ListBox,但我也看到SelectedItem显示为此(当我单击15条目时): System.Windows.Controls.ListBoxItem:15

我的问题: 1)名为SelectedItem的Path返回的实际值是多少?它是“System.Windows.Controls.ListBoxItem:15”还是“15”?如果它不是15,我怎么能指定一个只返回15的Path而不是System.Windows.Controls.ListBoxItem:15?

2)为什么FontFamily SelectItem有效?我意识到FontList来自系统的字体名称集合,但我不清楚为什么ListBox没有将ListBoxItems的集合作为文本返回。如果我的ListBox的Path引用返回ListBoxItem类型的SelectedItem对象,那么我认为我可以使用Path of SelectedItem.Value或类似的东西 - 但它不起作用,并且没有Intellisense来帮助我。

我想让这个例子有效,因为它有助于消除我的一些误解。请不要重构解决方案以使其以其他方式工作,除非我完全不可能有一个Path引用,它只会给我选择的Size ListBoxItem的数字部分。

2 个答案:

答案 0 :(得分:2)

  

名为SelectedItem的路径返回的实际值是多少?

它是System.Windows.Controls.ListBoxItem:15(您可以将其读作“内容设置为15的ListBoxItem”),这就是您的绑定不起作用的原因 - 它需要一个数值,而不是ListBoxItem。您可以将Path指定为SelectedItem.Content以使其正常工作。您还可以将ListBox“Size”的SelectedValuePath设置为“Content”,并绑定到SelectedValue属性而不是SelectedItem

解决方案1:

<TextBlock Size="{Binding ElementName=Size, Path=SelectedItem.Content}" />

解决方案2:

<ListBox x:Name="Size" SelectedValuePath="Content" />
<TextBlock Size="{Binding ElementName=Size, Path=SelectedValue}" />
  

为什么FontFamily SelectItem有效?

因为ListBox包含一个字体集合,而不是ListBoxItems的集合(它们仍然被创建以表示集合中的每个项目)。如果在代码中定义字体大小的集合并将ListBox'es ItemsSource属性绑定到该集合,或者直接在XAML中将ListBox的内容定义为System.Double值的集合,则可以使用字体大小实现相同的行为:

<ListBox x:Name="Size"
         xmlns:system="clr-namespace:System;assembly=mscorlib">
    <system:Double>10</system:Double>
    <system:Double>15</system:Double>
    <system:Double>20</system:Double>
</ListBox>

答案 1 :(得分:1)

1)SelectedItem绑定返回的实际值是ListBoxItem对象。要从绑定中获取值(15),您可以使用转换器或使绑定路径更加明确以获取列表框项的Content属性值:

Size="{Binding ElementName=Size, Path=SelectedItem.Content}"

2)这是一个协变操作,因此每个列表项的类型都是从其来源推断出来的。由字体系列项控件(ListBox)生成的项是它所绑定的集合的结果。 Items属性(通过ItemsSource依赖项属性填充)是一个泛型对象的ItemCollection,它采用相应上下文对象的类型。