Binding SelectedItem vs SelectedIndex - When shoul

2020-03-19 01:35发布

Let's say that you have an observable collection of object type Foo, and you have a custom ListView that the user will select from.

Your bound data object:

// property with getter / setter / INotifyPropertyChanged
ObservableCollection<Foo> MyCollection; 

In XAML:

<ListView ItemsSource={Binding MyCollection} />

Is it more appropriate to bind to the SelectedIndex in XAML and create the following in your data object:

int SelectedIndex { get; set; } // also raising property changed notifications
Foo SelectedObject
{
   get { return MyCollection[SelectedIndex]; }
}

Or to create this and bind to the SelectedItem in XAML:

Foo SelectedObject { get; set; } // also raising property changed notifications

And why?

标签: c# wpf xaml mvvm
4条回答
别忘想泡老子
2楼-- · 2020-03-19 02:22

Both cases are acceptable, however which you choose usually depends on the design of your data models, and which method would require the least amount of code to get working.

A few rules I use to determine which one to select

  1. If SelectedObject cannot be null (such as an enum), and you need to default to be no item selected, then use SelectedIndex.

  2. If SelectedObject may not be considered .Equals() to any item in your Items list, use SelectedIndex. This is because SelectedItem compares objects with the Items collection using .Equals(), so a reference comparism will return false which will result in your object not becomming selected.

    This usually happens when your selected item comes from a different location than where your list of items is. For example, one database calls to load the Items for the list, and a separate database call obtaining an object that includes a SelectedObject property.

  3. If you need to reference only one of SelectedObject or SelectedIndex in other parts of your code, use that one.

  4. If your data models already have a SelectedIndex or SelectedObject property, then use that.

  5. If all other things are equal, I use a SelectedObject property to bind the SelectedItem property.

    This is because to me it makes more sense to refer to something like SelectedUser instead of SelectedUserIndex in the code behind, and I prefer to avoid looking up the item in the collection anytime I want to do something with the selected item.

查看更多
够拽才男人
3楼-- · 2020-03-19 02:26

Both approaches are fine. Use the one you find easier to use. I don't find myself relying on indices often, but your cases may be different.

If you look at MVVM libraries, Caliburn.Micro, for example, expects you to use SelectedObject approach. It explicitly supports this convention.

And note on collection properties. In general, it's better idea to have read-only auto-properties and set them in constructor (property change notification won't be necessary). It is not advised to change instances of collections. While WPF supports it, it's much easier to subsribe to collection events in your own code if the instance doesn't change.

查看更多
【Aperson】
4楼-- · 2020-03-19 02:34

Depends on your needs. If you need to set the selected item, you need the second version. If you need the selected item's index, you need the first version. If you need neither, it's up to your personal preference.

查看更多
男人必须洒脱
5楼-- · 2020-03-19 02:38

I personal think bind to the SelectedObject is much cleaner unless you need access to the SelectedIndex

The only time I use SelectedIndex is when I want to set a default value of 0 to select the first item.

查看更多
登录 后发表回答