Разница между SelectedItem, SelectedValue и SelectedValuePath

352

Какая разница между следующим:

Все эти свойства зависимостей определены в классе Selector . Я часто путаю SelectedItemс SelectedValueи SelectedValueс SelectedValuePath.

Я хотел бы знать разницу между ними, а также когда мы их используем, особенно SelectedValueи SelectedValuePath. Пожалуйста, объясните их использование с несколькими простыми примерами.

Наваз
источник
3
У Bea есть пост в блоге с пояснениями и примером кода, который вы можете скачать ... bea.stollnitz.com/blog/?p=9
Аарон Макивер
2
возможный дубликат [Confused с wpf ComboBox DisplayMemberPath, SelectedValue и SelectedValuePath] ( stackoverflow.com/questions/3797034/… )

Ответы:

552

Их имена могут быть немного запутанными :). Вот резюме:

  • Свойство SelectedItem возвращает весь объект, с которым связан ваш список. Допустим, вы связали список с коллекцией Categoryобъектов (каждый объект Category имеет свойства Name и ID). например. ObservableCollection<Category>, SelectedItemСвойство вернет вам текущий выбранный Categoryобъект. Однако для целей связывания это не всегда то, что вам нужно, поскольку это позволяет вам связать весь объект Category со свойством, с которым связан список, а не со значением одного свойства в этом объекте Category (например, его IDсвойство). ).

  • Поэтому у нас есть свойство SelectedValuePath и свойство SelectedValue в качестве альтернативного средства привязки (вы используете их вместе друг с другом). Допустим, у вас есть Productобъект, с которым связано ваше представление (со свойствами для таких вещей, как ProductName, Weight и т. Д.). Предположим также, что у вас есть CategoryIDсвойство для этого объекта Product, и вы хотите, чтобы пользователь мог выбрать категорию для продукта из списка категорий. Необходимо, чтобы свойство ID объекта Category было присвоено CategoryIDсвойству объекта Product. Это где SelectedValuePathиSelectedValueсвойства вступают в силу. Вы указываете, что свойство ID объекта Category должно быть присвоено свойству объекта Product, с которым связан список SelectedValuePath='ID', а затем привязываете SelectedValueсвойство к свойству DataContext (т. е. Product).

Пример ниже демонстрирует это. У нас есть ComboBox, связанный со списком категорий (через ItemsSource). Мы привязываем свойство CategoryID к Продукту как выбранное значение (используя свойство SelectedValue). Мы связываем это со свойством ID категории через свойство SelectedValuePath. И мы говорим только отображать свойство Name в ComboBox, со свойством DisplayMemberPath).

<ComboBox ItemsSource="{Binding Categories}" 
          SelectedValue="{Binding CategoryID, Mode=TwoWay}" 
          SelectedValuePath="ID" 
          DisplayMemberPath="Name" />
public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class Product
{
    public int CategoryID { get; set; }
}

Поначалу это немного смущает, но, надеюсь, это немного проясняет ... :)

Крис

Крис Андерсон
источник
8
Спасибо за объяснение. Вы тот самый парень, который написал книгу о Silverlight? Я не верю, что говорю с тобой. : -) ... Я читаю эту книгу в настоящее время. Действительно потрясающая работа. :-)
Наваз
22
Да, это я :). Я слоняюсь вокруг этих частей, чтобы ответить на вопросы, когда смогу. Рад, что вы наслаждаетесь книгой :). Поскольку у вас есть книга, вы найдете больше информации по этой теме на страницах 69-70 и 204.
Крис Андерсон,
8
+1. +100. Вы, сэр, золотой бог среди меньших людей. Да благословит вас Господь и всех, кто плывет в вас. :) Серьезно, я просто потратил два часа, пытаясь понять это - спасибо!
TarkaDaal
1
@Chris Anderson: Что если объект Product имеет свойство Category (тип Category) вместо CategoryID? Как я могу обновить это свойство категории при изменении ComboBox через привязку?
Люцифер
2
@Lucifer: в этом случае вы бы использовали свойство SelectedItem следующим образом: <ComboBox ItemsSource = "{Binding Categories}" SelectedItem = "{Binding Category, Mode = TwoWay}" /> Надеюсь, это поможет.
Крис Андерсон
69

Чтобы ответить немного более концептуально:

SelectedValuePathопределяет, какое свойство (по его имени) объектов, связанных с ListBox, ItemsSourceбудет использоваться в качестве элемента SelectedValue.

Например, если ваш ListBox привязан к коллекции Personобъектов, каждый из которых имеет Name, Ageи Genderсвойства, SelectedValuePath=Nameвызывает значение выбранного Person«s Nameимущества , которое будет возвращено в SelectedValue.

Обратите внимание, что если вы переопределите элемент управления ListBox ControlTemplate (или примените стиль), который указывает, какое свойство должно отображаться, SelectedValuePathиспользовать нельзя.

SelectedItemМежду тем, возвращает весь Personвыбранный объект.

(Вот еще один пример из MSDN с использованием TreeView)

Обновление: как указал @Joe, свойство DisplayMemberPath не связано со свойствами Selected *. Его правильное описание следующее:

Обратите внимание, что эти значения отличаются от DisplayMemberPath(которые определены в ItemsControl, а не в Selector), но это свойство имеет сходное поведение SelectedValuePath: в отсутствие стиля / шаблона оно определяет, какое свойство объекта, связанного с элементом, следует использовать в качестве его строковое представление.

Дэн Дж
источник
8

SelectedItemявляется object. SelectedValueа такжеSelectedValuePath являются strings.

например, используя ListBox:

если вы скажете «дай мне», listbox1.SelectedValueон вернет текст текущего выбранного элемента.

string value = listbox1.SelectedValue;

если ты скажешь, дай мне, listbox1.SelectedItemэто даст тебе весь объект.

ListItem item = listbox1.SelectedItem;
string value = item.value;
capdragon
источник
3
SelectedValueэто также objectи не string. Пожалуйста, смотрите здесь
john_m
5

вдохновленный этим вопросом, я написал блог вместе с фрагментом кода здесь . Ниже приведены некоторые выдержки из блога.

SelectedItem - Выбранный элемент помогает связать фактическое значение из источника данных, который будет отображаться. Это объект типа, и мы можем связать с этим свойством любой тип, полученный из типа объекта. Поскольку в этом случае мы будем использовать привязку MVVM для наших полей со списком, это свойство, которое мы можем использовать, чтобы уведомить ВМ о том, что элемент выбран.

SelectedValue и SelectedValuePath - это два наиболее запутанных и неверно истолкованных свойства для выпадающего списка. Но эти свойства приходят на помощь, когда мы хотим связать наш комбинированный список со значением из уже созданного объекта. Пожалуйста, проверьте мой последний сценарий в следующем списке, чтобы получить краткое представление о свойствах.

Викрам
источник
1

Каждый элемент управления, который использует Коллекции для хранения данных, имеет свойство SelectedValue, SelectedItem. Примерами этих элементов управления являются ListBox, Dropdown, RadioButtonList, CheckBoxList.

Если быть более точным, если вы в буквальном смысле хотите получить текст выбранного элемента, вы можете написать:

ListBox1.SelectedItem.Text;

Ваш ListBox1 также может возвращать текст, используя свойство SelectedValue, если значение было установлено в это ранее. Но выше, это более эффективный способ получить текст.

Теперь это значение невидимо для пользователя, но используется в основном для хранения в базе данных. Мы не вставляем текст ListBox1, однако мы можем также вставить его, но мы использовали для вставки значения выбранного элемента. Чтобы получить значение мы можем использовать

ListBox1.SelectedValue

Источник

kamalpreet
источник