2012-03-17 83 views
4

我通过萨姆斯书会“自学WPF在24小时内”。在某一时刻,作者展示了如何将列表框的选定项值绑定到属性。我明白了,这很简单。但是,当我尝试使用自己的ListBoxItems创建自己的ListBox控件时,似乎无法使其工作。WPF ListBox的ListBoxItem的绑定

的作品列表框使用系统集合作为其ItemsSource属性:

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

从该列表框中选择的值,然后在一个TextBlock使用方法如下:

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

注意,路径被设置为SelectedItem。现在

,我想用一个包含3种不同尺寸的另一个列表框设置字号。下面是我做的:

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

然后我加入到文本框的大小属性的绑定,如下所示:

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

当我运行该程序的大小不会改变。所以,我想补充我使用尺寸的文本属性绑定 - 为了看它的价值:

<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" /> 

我看到我点击列表框的尺寸,它是变化的,但我也看到,该是的SelectedItem显示,因为这(当我点击进入15): System.Windows.Controls.ListBoxItem:15

我的问题: 1)什么是所谓的SelectedItem路径返回的实际值?是“System.Windows.Controls.ListBoxItem:15”还是“15”?如果它不是15,我怎么能指定一个返回15而不是System.Windows.Controls.ListBoxItem的路径:15?

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

我想这个例子中工作,因为这将有助于明确一些误解我。请不要重构解决方案以使其以某种其他方式工作,除非我完全不可能拥有一个Path参考,它只会给我选择的Size ListBoxItem的数字部分。

回答

2

什么是所谓的SelectedItem路径返回的实际值?

这是System.Windows.Controls.ListBoxItem:15(你可以看这是“值设置为15内容ListBoxItem的”),这就是为什么你的约束力不工作 - 它需要一个数值,而不是ListBoxItem。您可以指定Path作为SelectedItem.Content来完成此项工作。您还可以设置列表框“尺寸”到“内容”的SelectedValuePath,并结合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属性绑定到该集合或定义列表框的内容作为System.Double值直接在XAML集合:

<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> 
+0

太棒了!谢谢! – Jazimov 2012-03-17 23:47:12

1

1)您的SelectedItem绑定返回的实际值是一个ListBoxItem对象。

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

2)这是这样的类型协变操作:从您的绑定,您可以使用一个转换器或让你的绑定路径更明确一点得到列表框项目的内容属性值中获得的价值(15)每个列表项目的来源都是从其来源推断出来的。由您的字体家族项目控件(ListBox)生成的项目是它绑定到的集合的结果。 Items属性(通过ItemsSource依赖项属性填充)是通用对象的ItemCollection,它们承担相应上下文对象的类型。

+0

我会阅读更多关于“逆变操作”的内容。谢谢! – Jazimov 2012-03-17 23:48:07

+0

这里有一个很好的C#协变和反变换的链接:http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx – KodeKreachor 2012-03-18 00:47:27

相关问题