【问题标题】:Binding SelectedItem vs SelectedIndex - When should I choose one over the other?绑定 SelectedItem 与 SelectedIndex - 我应该何时选择一个而不是另一个?
【发布时间】:2014-09-24 14:19:10
【问题描述】:

假设您有一个对象类型为 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

为什么?

【问题讨论】:

  • 根据本站guidelines,这里是为了了解任何最佳实践,或者讨论 任何东西,所以你的问题显然是off topic。因此,我投票决定关闭它。对于我的 2 美分,我总是建议使用 SelectedItem 方法,但这真的取决于你。用一个,如果你不喜欢,就用另一个。
  • @Sheridan 我的理解是,大多数“X 的最佳方法是什么”问题过于宽泛,这就是它们被关闭的原因,但是像这样的具体问题是使用哪种方法而不是另一种方法以及为什么似乎它完全是该网站的主题。事实上,这也是我感兴趣的答案。如果你认为标题中的“Best practice”字样会导致更接近的投票,也许我们可以将它们编辑掉,并用更具体的东西替换它们,例如 “使用 SelectedItem 或 SelectedIndex 有区别吗,我什么时候应该选择一个而不是另一个?”
  • @Rachel 我完全同意,这可能不应该是“最佳实践”,而是“哪种方式更好”...
  • @Sheridan,您对问题或标题有疑问吗?我会在万维网的什么地方发布这样的问题?
  • 这是一个很好的链接@Sheridan:meta.stackoverflow.com/questions/271863/…

标签: c# wpf xaml mvvm


【解决方案1】:

这两种情况都可以接受,但是您选择哪种通常取决于数据模型的设计,以及哪种方法需要最少的代码才能工作。

我用来确定选择哪一个的一些规则

  1. 如果SelectedObject不能为null(如枚举),并且需要默认不选中任何项,则使用SelectedIndex

  2. 如果您的Items 列表中的任何项目都不能将SelectedObject 视为.Equals(),请使用SelectedIndex。这是因为SelectedItem 使用.Equals() 将对象与Items 集合进行比较,因此引用比较将返回false,这将导致您的对象未被选中。

    当您选择的项目与您的项目列表所在的位置不同时,通常会发生这种情况。例如,一个数据库调用加载列表的Items,另一个数据库调用获取包含SelectedObject 属性的对象。

  3. 如果您只需要在代码的其他部分中引用SelectedObjectSelectedIndex 之一,请使用那个。

  4. 如果您的数据模型已经有 SelectedIndexSelectedObject 属性,请使用它。

  5. 如果所有其他条件都相同,我使用SelectedObject 属性绑定SelectedItem 属性。

    这是因为对我来说,在后面的代码中引用 SelectedUser 而不是 SelectedUserIndex 更有意义,而且我更愿意避免在任何时候在想要使用选定的项目。

【讨论】:

    【解决方案2】:

    取决于您的需求。如果你需要设置选中的项目,你需要第二个版本。如果您需要所选项目的index,则需要第一个版本。如果您两者都不需要,这取决于您的个人喜好。

    【讨论】:

      【解决方案3】:

      这两种方法都很好。使用你觉得更容易使用的那个。我发现自己并不经常依​​赖索引,但您的情况可能会有所不同。

      如果您查看 MVVM 库,例如,Caliburn.Micro 期望您使用 SelectedObject 方法。它明确支持这种约定。

      并注意集合属性。一般来说,最好有只读的自动属性并将它们设置在构造函数中(不需要属性更改通知)。不建议更改集合的实例。虽然 WPF 支持它,但如果实例没有更改,则在您自己的代码中订阅集合事件要容易得多。

      【讨论】:

      • Caliburn.Micro 期望如何使用 SelectedObject 方法?似乎这两种方式都可以简单地完成。
      • 我用来帮助我决定使用哪种方法的另一件事是SelectedObject 是否将始终指向项目列表中对象的引用。例如,在某些情况下,我会从一个数据库调用中获取我的项目列表,而我选择的项目来自另一个数据库调用。在这些情况下,如果两个对象不相等,那么使用SelectedObject 将不起作用,因此我经常使用SelectedIndex 而不是覆盖对象上的.Equals() 方法。但在大多数情况下,我更喜欢SelectedItem 而不是SelectedIndex
      • @KingArthur x:Name="Foos" 变成 ItemsSource={Binding Foos} SelectedItem={Binding SelectedFoo}, iirc。 SelectedIndex 是否支持这种方式?
      • 是的,您可以改为设置 ItemsSource={Binding Foos} SelectedIndex={Binding MyFoosIndex},并在继承自 CM.Micro 的 PropertyChangedBase 类的对象上创建 MyFoosIndex 属性,这实际上是一样。
      • @KingArthur 你说的是显式绑定,我说的是基于约定的绑定。 Caliburn.Micro.Platform/ConventionManager.cs — 我看不到对 Selected*Index 属性约定的支持。
      【解决方案4】:

      我个人认为绑定到 SelectedObject 会更干净,除非您需要访问 SelectedIndex

      我唯一使用 SelectedIndex 的时候是我想设置默认值 0 来选择第一个项目。

      【讨论】:

        猜你喜欢
        • 2019-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-01
        相关资源
        最近更新 更多