2009-12-03 21 views
7

私は自分のDataContextをBookオブジェクトに設定しました。ブックのプロパティはTitle、Categoryです。データバインディングに基づいてWPFコンボボックスのアイテムを選択するにはどうすればよいですか?

私は、カテゴリのリストを保持するCollectionViewSource "categoryList"を持っています。

質問このコンボボックスで書籍のカテゴリを選択しますか?

<TextBox Text="{Binding Path=Title}"/> 

<ComboBox SelectedValuePath="Id" 
      SelectedValue="{Binding Path=Category.Id}" 
      SelectedItem="{Binding Path=Category}" 
      ItemsSource="{Binding Source = {StaticResource categoryList}}" 
      DisplayMemberPath="Name" /> 

上記のコードは、ブックのタイトルを正しく表示し、コンボボックスにカテゴリ名のリストを表示します。しかし、それは本のカテゴリを選択しません。代わりに、リスト内の最初の項目を選択するだけです。

答えて

7

あなたはあまりにも拘束力があります。 SelectedValueSelectedValuePathまたはSelectedItemと設定する必要があります。この場合、実際に特定のオブジェクトにバインドしようとしているようです。あなたはComboBoxがあなたのBookCategoryプロパティを設定し、現在Bookオブジェクトが実際にcategoryListにありますCategoryインスタンスへの参照を持っている、あなたはバインディングSelectedItemを使用してSelectedValueSelectedValuePathのバインディングを削除する必要があります。持ってしようとしている場合

編集

リストソースのプロパティを使用してバインドされたアイテムをリンクする情報の共通部分を持っている場合SelectedValueを使用するように設計され、これがどのように行われるかについて少しを展開します。たとえば、CategoryIDプロパティを持つBookクラスがあるとします。この場合

public class Book 
{ 
    public string CategoryID { get; set; } 
    public string Title { get; set; } 
} 

public class CategoryID 
{ 
    public string ID { get; set; } 
    public string Name { get; set; } 
} 

、あなたはどうなる:

<ComboBox SelectedValue = "{Binding CategoryID}" 
      SelectedValuePath = "ID" 
      DisplayMemberPath = "Name" /> 

SelectedItemを、一方、結合したインスタンスは、より正確に、実際の参照(または、あるオブジェクトを持っているときのためにありますバインドされたリストの項目に相当する)。

<ComboBox SelectedItem = "{Binding Category}" 
      DisplayMemberPath = "Name" /> 

しかし、それは、 これはBookクラスがない限り動作しないことに注意することは非常に重要です:この場合

public class Book 
{ 
    public Category Category { get; set; } 
    public string Title { get; set; } 
} 

、あなたはどうなる:それでは、Bookクラスは、実際にこのようになりますと仮定しましょうリストにあるとおり、Categoryという同じインスタンスへの参照があります。参照が異なる場合(たとえクラスの値が同じであっても)、ComboBoxBookで参照されているCategoryをリスト内に見つけることができないため、機能しません。

あなたがそれを上にバインドする方法(Category.IDにバインドすることによって)の実際の問題は、あなたがスキームを混在させることです。参照がありますが、代わりにキーでバインドしようとしています。これはすべてあなたの参照に値を設定しようとすることです。あなたのクラスの参照を変更しようとしません。アダムさんが話してどのようなコードで記述するために

+0

はい申し訳ありませんが、私はちょうど種類のそこにすべてを投げました。 :) SelectedValue + SelectedValuePathは機能しません。 SelectedItemはそれ自身のものでもありません。または、SelectedItem + SelectedValuePathのDougが以下のように表示されます。 Ergh。私はcategoryListのカテゴリが何らかの形で私の能力を妨害していると思います(もし私がちょうどその下のテキストフィールドのCategory.Nameに直接バインドすると、私は間違った値を取得します。)しかし、categoryListへのバインディングをコメントアウトすると、 )。 彼のデバッグの提案を試しに行く。ありがとう。 –

+0

これは本当に役に立ちました、ありがとうございました。しかし、奇妙なことに私はisSynchronizedWithCurrentItem = Trueを使用する必要がありました(私は上記のようにSelectedItemを使用しています)。その部分を理解していない。 –

+0

@Abby: 'Category'オブジェクトのこのリストを他のデータソースにバインドしていますか?もしそうなら、それは理にかなっています。 –

2

<ComboBox 
    SelectedValuePath="Id" 
    SelectedItem="{Binding Path=Category}" 
    ItemsSource="{Binding Source={StaticResource categoryList}}" 
    DisplayMemberPath="Name" /> 

はおそらく、より適切です。通常はSelectedValueを読み取り専用として扱い、SelectedItemを使用して選択する項目を選択することをお勧めします。 SelectedItemを書籍のCategoryにバインドすると、自動的にSelectedValueプロパティが設定されます。

これでもうまくいかない場合は、Categoryへのバインディングが正しく機能しているかどうかを確認したい場合があります。特に、DebugConverterを追加すると、期待する価値が確実に守られます。 You can see the use of DebugConverter is the answer to this question.

-Doug

+0

これは本当です(この場合は 'SelectedValuePath'は必須ではありません)。ただし、バインドされたオブジェクトがリスト内の要素と同じ参照を共有する場合のみです。それらが異なる参照で共通キーを共有している場合、これは間違っています。 –

+0

WOW、デバッグのアイディアに感謝します。これは素晴らしいことです。私はそれを使用し、それは何とか私のCategory値(ConvertBack上)をComboBoxリストの最初の項目に設定していることがわかりました。今私は本当に混乱しています。しかし、少なくとも良いツールで、ありがとう。 –

+0

これを(ちょうどフォローアップする)IsSynchronizedWithCurrentItem = Trueを追加することで修正されましたが、なぜ私はその理由がわかりません。 –