【问题标题】:Databinding both ComboBox.ItemsSource and SelectedItem results in SelectedItem being set too early数据绑定 ComboBox.ItemsSource 和 SelectedItem 导致 SelectedItem 设置得太早
【发布时间】:2011-11-11 10:23:25
【问题描述】:

我首先在 Developer Express 组件中发现了一个奇怪的 WPF 问题(http://www.devexpress.com/Support/Center/p/Q352950.aspx 的问题)。

Comboboxes 似乎过早地对 SelectedItem 进行数据绑定,我似乎不知道该怎么做。

从开发者快递问题中复制(为了清晰起见进行了一些更改):

我的 XAML 中有以下组合框编辑:

<dxe:ComboBoxEdit Name="CharacteristicDropdown" ItemsSource="{Binding Path=Characteristics}" SelectedItem="{Binding Path=StratifyCharacteristic}" ValueMember="CharacteristicName" DisplayMember="CharacteristicName" />

(注意 - 由于普通的 ComboBox 显然存在同样的问题,所以我只是将代码保留在这里)

我的问题是 SelectedItem 的设置比我预期的要早得多。当 ItemsSource 更改时,其中的第一个项目成为 SelectedItem。这是非常不合逻辑的——它没有被选中,只是因为它现在在列表中。此外,它实际上并没有在组合框中直观地被选中。 我希望在通过代码或 UI 交互实际选择项目时设置 SelectedItem,而不仅仅是在更改 ItemsSource 时设置。

为了完全清楚,这是事件链:

1) 我有一个 Grid 数据绑定到项目的 BindingList

2) 我有一个 ComboBox 数据绑定到与网格相同的 BindingList

3) 我使用 Grid 向此列表添加一些内容。 (甚至在项目在网格中完全填充之前就会触发,但这并不重要。)

4) Combobox 的 SelectedItem 被设置自动!发生这种情况仅仅是因为组合框的后备列表现在有一个项目。

请注意,我实际上并没有选择任何东西。我只是简单地添加到支持列表中。 然而,在简单地添加到支持列表之后,我现在有了一个 SelectedItem,即使在视觉上该项目没有被选中。此外,如果我现在尝试从下拉列表中选择项目,则不会再次设置 SelectedItem!

这快把我逼疯了——有人有解决办法吗?

【问题讨论】:

  • 不是直接的解决方案,但我想回答“不合逻辑”的部分。它不仅仅是逻辑。如果您有一个空集合,但将所选项目设置为您希望 ComboBox 保留该项目直到您将其添加到集合中?它不是那样工作的。解决它的两种快速方法是使用 CollectionView 和 SynchronizeWithCurrentItem,或者改用 SelectedIndex。
  • 谢谢,我会看看 CollectionView 和 SynchronizeWithCurrentItem,但我想你可能误解了我的意思。 没有设置 SelectedItem。 ComboBox 在后备列表获取项目时自行执行此操作。我从不直接设置它 - 我只需要它来读取已设置的任何内容。此外,即使期望的语义是一旦将单个项目添加到列表中就应该选择它(我再次觉得这不合逻辑),在 UI 中没有选择该项目仍然是非常不一致的!跨度>
  • 啊,好吧,我的错。现在我明白了。那么你是对的,很奇怪,该项目被选中,但 ComboBox 并没有将其显示为选中。当然它直接选择也很奇怪。我会尝试重现它,看看我想出了什么。

标签: wpf data-binding combobox devexpress selecteditem


【解决方案1】:

当您将项目添加到网格时,它会更新组合框的 itemsource 绑定到的属性,然后组合框会看到源已更改,然后选择集合中的第一个项目。 查看数据网格的 xaml 代码以及查看其绑定会很有帮助。

几个建议:

1) 尝试使用 IEnumerable 集合而不是绑定列表,如下所示:

private ObservableCollection<Drink> drinks = new ObservableCollection<Drink>();

public IEnumerable<Drink> DrinkCollection
     {
         get { return this.drinks; }
     }

并将组合绑定到属性。

2) 尝试使用 xaml 中的 UpdateSourceTrigger 和 SynchronizeWithCurrentItem 属性。

3) 为您的组合创建一个单独的属性。

【讨论】:

    【解决方案2】:

    我建议你改用ICollectionView:

    用新的公共财产替换您的公共财产:

    public ViewModel()
    {
        this.CharacteristicsView = CollectionViewSource.GetDefaultView(this.Characteristics);
    }
    
    public ICollectionView CharacteristicsView { get; private set; }
    

    更改绑定以指向新属性并将 IsSynchronizedWithCurrentItem 设置为 true:

    <ComboBox ItemsSource="{Binding Path=CharacteristicsView}" 
            IsSynchronizedWithCurrentItem="True" ValueMember="CharacteristicName"
            DisplayMember="CharacteristicName" />
    

    无论您需要在何处访问当前项,请使用视图的CurrentItem 属性:

    var currentItem = this.CharacteristicsView.CurrentItem;
    

    【讨论】:

      猜你喜欢
      • 2013-01-26
      • 1970-01-01
      • 2011-09-12
      • 2012-05-24
      • 2011-10-29
      • 2022-01-23
      • 2012-02-12
      • 2012-08-26
      • 2019-11-10
      相关资源
      最近更新 更多