对ComboBox.ItemsSource和SelectedItem进行数据绑定会导致SelectedItem设置得太早

时间:2011-11-11 10:23:25

标签: wpf data-binding combobox devexpress selecteditem

我在Developer Express组件中首次注意到一个奇怪的WPF问题(问题http://www.devexpress.com/Support/Center/p/Q352950.aspx)。

Comboboxes似乎过早地对SelectedItem进行数据绑定,我似乎无法弄清楚如何处理它。

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

我的XAML中有以下的comboboxedit:

<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)我有一个与网格相同的BindingList的ComboBox数据库

3)我使用网格向此列表添加内容。 (即使在项目在网格中完全填写之前,这也会被触发,但这并不重要。)

4)Combobox的SelectedItem自动设置 !这种情况只是因为组合框的支持列表现在有一个项目。

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

这让我发疯了 - 有没有人有解决方案?

2 个答案:

答案 0 :(得分:3)

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

一些建议:

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

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

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

并将组合绑定到属性。

2)在xaml中使用UpdateSourceTrigger和SynchronizeWithCurrentItem属性。

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

答案 1 :(得分:0)

我建议您切换到使用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;