Как выбрать элемент в моем WPF ComboBox на основе привязки данных? - PullRequest
6 голосов
/ 03 декабря 2009

У меня установлен DataContext для объекта Book. Книга имеет свойства: Название, Категория.

У меня есть 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" />

Приведенный выше код правильно отображает название книги, а затем отображает список названий категорий в выпадающем списке. Но это не выбирает категорию книги. Вместо этого он просто выбирает первый элемент в списке.

Ответы [ 2 ]

6 голосов
/ 03 декабря 2009

Вы слишком сильно привязываетесь; вам нужно только установить SelectedValue и SelectedValuePath или SelectedItem. В этом случае, похоже, что вы на самом деле пытаетесь привязать к определенному объекту. Если вы пытаетесь установить ComboBox свойство Category на вашем Book, а текущий объект Book фактически имеет ссылку на экземпляр Category, который находится в categoryList, тогда вам следует использовать SelectedItem переплет и удаление привязок для SelectedValue и SelectedValuePath.

Редактировать

Чтобы немного рассказать о том, как это делается, SelectedValue предназначен для использования, когда у вас есть общая часть информации, чтобы связать связанный элемент со свойством в источнике списка. Например, допустим, у меня есть класс Book со свойством CategoryID.

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, с другой стороны, для случая, когда связанный экземпляр имеет фактическую ссылку на (или, точнее, объект, который эквивалентен) элементу в связанном списке. Итак, давайте предположим, что класс Book на самом деле выглядит так:

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

В этом случае вы должны сделать:

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

Но очень важно отметить, что это не сработает, если класс Book не имеет ссылку на тот же экземпляр Category, как в списке . Если ссылки различаются (даже если значения классов равны), это не сработает, поскольку ComboBox не сможет найти Category, на который есть ссылка в Book в списке.

Реальная проблема с тем, как вы связывали его сверху (связывая с Category.ID), заключается в том, что вы смешиваете схемы. У вас есть ссылка, но вместо этого вы пытаетесь связать ключ. Все, что вам нужно сделать, это попытаться установить значение для вашей ссылки, он не будет пытаться изменить ссылку для вашего класса .

1 голос
/ 04 декабря 2009

Чтобы описать в коде, о чем говорит Адам:

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

, вероятно, более уместно. Обычно лучше обращаться с SelectedValue только для чтения и использовать SelectedItem, чтобы выбрать, какой элемент вы хотите выбрать. Когда вы связываете SelectedItem с Category книги, она все равно автоматически устанавливает для вас SelectedValue.

Если это по-прежнему не работает, вы можете проверить, что ваша привязка к Category работает правильно. В частности, добавление DebugConverter хорошо работает, чтобы гарантировать, что ожидаемое значение будет связано. Вы можете увидеть использование DebugConverter - ответ на этот вопрос.

-Doug

...