假设您有一个可观察的对象类型Foo集合,并且您有一个用户可以选择的自定义ListView。
您的绑定数据对象:
// property with getter / setter / INotifyPropertyChanged
ObservableCollection<Foo> MyCollection;
在XAML中:
<ListView ItemsSource={Binding MyCollection} />
更合适的是绑定到XAML中的SelectedIndex并在数据对象中创建以下内容:
int SelectedIndex { get; set; } // also raising property changed notifications
Foo SelectedObject
{
get { return MyCollection[SelectedIndex]; }
}
或者创建它并绑定到XAML中的SelectedItem:
Foo SelectedObject { get; set; } // also raising property changed notifications
为什么?
答案 0 :(得分:3)
这两种情况都是可以接受的,但是您选择的情况通常取决于数据模型的设计,以及哪种方法需要最少量的代码才能正常工作。
我用一些规则来确定选择哪一个
如果SelectedObject
不能为空(例如枚举),并且您需要默认不选择任何项目,请使用SelectedIndex
。
如果您SelectedObject
列表中的任何项目.Equals()
可能不被视为Items
,请使用SelectedIndex
。这是因为SelectedItem
使用Items
将对象与.Equals()
集合进行比较,因此参考比较将返回false,这将导致您的对象不被选中。
当您选择的商品来自与商品列表所在位置不同的位置时,通常会发生这种情况。例如,一个数据库调用为列表加载Items
,并且单独的数据库调用获取包含SelectedObject
属性的对象。
如果您只需要在代码的其他部分引用SelectedObject
或SelectedIndex
中的一个,请使用该代码。
如果您的数据模型已具有SelectedIndex
或SelectedObject
属性,请使用该属性。
如果所有其他条件相同,我使用SelectedObject
属性绑定SelectedItem
属性。
这是因为对我来说更有意义的是在后面的代码中引用SelectedUser
而不是SelectedUserIndex
之类的内容,我更愿意避免在我想要的任何时候查找集合中的项目对所选项目做一些事情。
答案 1 :(得分:0)
取决于您的需求。如果您需要设置所选项目,则需要第二个版本。如果您需要所选项目的索引,则需要第一个版本。如果您不需要,则取决于您的个人偏好。
答案 2 :(得分:0)
两种方法都很好。使用您觉得更容易使用的那个。我经常发现自己不依赖指数,但你的情况可能会有所不同。
例如,如果你看一下MVVM库,Caliburn.Micro希望你使用SelectedObject
方法。它明确支持这一惯例。
并注意集合属性。一般来说,更好的想法是拥有只读自动属性并在构造函数中设置它们(无需更改属性更改通知)。不建议更改集合的实例。虽然WPF支持它,但如果实例没有改变,那么在您自己的代码中收集事件要容易得多。
答案 3 :(得分:0)
我个人认为,除非您需要访问SelectedIndex
,否则绑定到SelectedObject会更加清晰我唯一一次使用SelectedIndex是我想设置默认值0来选择第一项。