WPF - MVVM - C# 无法在 ItemsSource 更改后设置组合框的 SelectedItem

WPF - MVVM - C# Cannot set SelectedItem of combobox after ItemsSource changes

几天来我一直在为这个问题苦苦挣扎。 我有一个组合框,它两次获取 ItemsSource。 我第一次尝试查看是否有我要显示的数据的离线备份。 显示离线数据时,软件需要从数据库下载更新后的数据。

如果我在离线备份中没有任何存储的数据,一切正常。 当我备份了一个项目列表时,问题就出现了,我把它放在组合框 itemsSource 中,然后在几秒钟后更改该列表。

列表实际上显示正确,但 selectedItem(这是我从视图模型中获得的东西)被重置,我无法从代码隐藏中再次设置它。 viewModel中的SelectedItem 属性其实是设置正确的,但是没有到达UI.

该列表是与 selectedItem 类型相同的 ObservableCollection。

我的组合框

<ComboBox ItemsSource="{Binding SomeList, Mode=OneWay}"
                          SelectedItem="{Binding ListItem, Mode=TwoWay}"
                          DisplayMemberPath="ItemProperty"
                          Margin="10,0,0,0" Width="300" VerticalAlignment="Center"/>  

我在离线和在线方法中设置 selectedItem 的方式:

SomeList= await _mainRepository.BackEndOfflineFirst_GetList();

if (SomeList.Count > 0)
{ 
      ListItem = SomeList.SingleOrDefault(list=> list.Property.Equals(SomeVariable.Property));
}

感谢任何帮助。 我应该提到,将 IsSynchronizedWithCurrentItem="True" 添加到组合框总是使 selectedItem 成为列表的第一项。

list.property 的检查等于另一个 variable.property 总是 returns 保证在列表中的单个元素,并且永远不会为空。

忘了提(有点重要,我的错),但我正在使用 Prism 并且我实现了 BindableBase,所以属性定义如下:

private ObservableCollection<Type> _someList ;
    public ObservableCollection<Type> SomeList
    {
        get { return _someList ; }
        set { SetProperty(ref _someList , value); }
    }

从您的解释中无法推断出问题的原因。 代码示例中的一切都是正确的 - 问题出在其他地方。 为了以防万一,我请你澄清一下:你是否在所有属性中引发 PropertyChanged?

一个提示(包括作为可能原因),对可观察集合使用 ReadOnly 属性:

public ObservableCollection<...> SomeList {get;}
    = new ObservableCollection<...>();
SomeList.Clear();
foreach(var item in await _mainRepository.BackEndOfflineFirst_GetList())
    SomeList.Add(item);

找出为什么它不起作用。

BindableBase propertyChanged 仅在值实际更改时引发。

我得到的是基本相同的对象(不同的对象,相同的值),所以它实际上并没有提高 propertyChanged。

为了解决这个问题,我放了一个

ListItem = null;
SomeList.Clear();

在 finally 子句中,在实际将从数据库接收到的值提供给 ListItem 之前。

如果我太快地更改属性(因此有 finally 子句),它似乎也不起作用,所以我不能只放一个

SomeList.Clear();
SomeList = await...

背靠背。

我发现的另一个问题是 SomeList.Clear() 实际上抛出了一个 NotSupportedException,它实际上并没有出现,因此跳过了一些代码。

这是因为 SomeList 是一个 ObservableCollection。将其更改为通用列表,我现在可以清除它。 如果您需要清除 ObservableCollection,一个简单的 Collection = null;也有效。

感谢所有帮助过我的人。