2012-03-17 8 views
4

私はSamsの本 "24時間で自分自身を教える"を使います。ある時点で、著者はリストボックスの選択項目値をプロパティにバインドする方法を示します。私はそれを得る、それはかなり簡単です。しかし、私自身のListBoxItemsで自分自身のListBoxコントロールを作成しようとすると、動作させることができません。WPF ListBox ListBoxItem Binding

作品リストボックスは、その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を使ってFontSizeを設定したかったのです。

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

私はサイズのリストボックスをクリックすると、それが変化していることがわかりますが、私もいることがわかり(私は15のエントリをクリックしたとき)のSelectedItemは、このよう表示されます。 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がListBoxItemのコレクションをテキストとして返さないのか不明です。 ListBoxのPath参照がListBoxItem型のSelectedItemオブジェクトを返す場合、SelectedItem.Valueのパスなどを使用することができますが、動作しないため、Intellisenseが役に立たなくなります。

私はこの誤解を解消するのに役立つので、この例を取りたいと思います。選択されたサイズのListBoxItemの数値部分だけを渡すPath参照を持つことが全く不可能でない限り、他の方法で動作させるためにソリューションをリファクタリングしないでください。

答えて

2

Pathによって返される実際の値は、SelectedItemとなりますか?

それはあるSystem.Windows.Controls.ListBoxItem:15(あなたは「15に設定されたコンテンツとListBoxItem」としてこれを読むことができます)あなたは動作しませんバインディング理由、それはだ - それは数値ではなく、ListBoxItemを期待しています。この作業を行うにはPathSelectedItem.Contentと指定できます。 ListBoxの "Size"のSelectedValuePathを "Content"に設定し、SelectedItemではなくSelectedValueプロパティにバインドすることもできます。

解決方法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 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

1
:あなたはコード内でフォントサイズのコレクションを定義し、そのコレクションにListBox'es ItemsSourceプロパティをバインドするか、直接XAMLで System.Double値のコレクションとしてあなたのListBoxの内容を定義する場合は、フォントサイズと同じ動作を実現することができます

1)SelectedItemバインディングによって返される実際の値は、ListBoxItemオブジェクトです。これはタイプので、共変の操作です)

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

2:あなたは、あなたがリストボックス項目のContentプロパティ値を取得するには、コンバータを使用したり、結合パスもう少し明示を作ることができる結合から値(15)を取得するには各リストアイテムのソースから推測されます。フォントファミリのアイテムコントロール(ListBox)によって生成されるアイテムは、バインドされたコレクションの結果です。 Itemsプロパティ(ItemsSource依存プロパティを使用して設定)は、対応するコンテキストオブジェクトの型をとる汎用オブジェクトのItemCollectionです。

+0

私は "contravariant操作"の詳細を読む予定です。ありがとうございました! – Jazimov

+0

C#の共分散と反寄与に関する良いリンクがあります:http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx – KodeKreachor