2012-03-17 127 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

相關問題