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

Wpf 数据绑定ComboBox.ItemsSource和SelectedItem会导致SelectedItem设置得太早,wpf,data-binding,combobox,devexpress,selecteditem,Wpf,Data Binding,Combobox,Devexpress,Selecteditem,我有一个奇怪的WPF问题,我第一次在Developer Express组件中注意到这个问题(问题在) 组合框似乎过早地将SelectedItem数据绑定,我似乎不知道该怎么办 从developer express版本复制(为清晰起见,进行了一些更改): 我的XAML中有以下Comboxedit: <dxe:ComboBoxEdit Name="CharacteristicDropdown" ItemsSource="{Binding Path=Characteristics}" Selec

我有一个奇怪的WPF问题,我第一次在Developer Express组件中注意到这个问题(问题在)

组合框似乎过早地将SelectedItem数据绑定,我似乎不知道该怎么办

从developer express版本复制(为清晰起见,进行了一些更改):

我的XAML中有以下Comboxedit:

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

(注意-由于普通的组合框,显然存在相同的问题,因此我将代码保留在这里)

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

要完全清楚,这是一系列事件:

1) 我有一个绑定到绑定项列表的网格数据

2) 我有一个与网格相同的绑定列表的组合框数据计数

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

4) 组合框的SelectedItem是自动设置的!发生这种情况的原因很简单,因为组合框的支持列表现在有一个项

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


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

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

有几点建议:

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

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

public IEnumerable<Drink> DrinkCollection
     {
         get { return this.drinks; }
     }
私有ObservableCollection饮料=新ObservableCollection();
公共IEnumerable DrinkCollection
{
获取{返回此。饮料;}
}
并将组合绑定到属性

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


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

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

有几点建议:

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

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

public IEnumerable<Drink> DrinkCollection
     {
         get { return this.drinks; }
     }
私有ObservableCollection饮料=新ObservableCollection();
公共IEnumerable DrinkCollection
{
获取{返回此。饮料;}
}
并将组合绑定到属性

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


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

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

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

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