修改 ItemsSource ObservableCollection 后如何刷新组合框

Posted

技术标签:

【中文标题】修改 ItemsSource ObservableCollection 后如何刷新组合框【英文标题】:How can I refresh a combobox after modifying its ItemsSource ObservableCollection 【发布时间】:2011-12-16 09:43:28 【问题描述】:

问题很简单:当ItemsSource 更新时,组合框不会“刷新”,例如新项目似乎没有添加到组合框中的项目列表中。

我已经尝试了这个问题的已接受答案的解决方案:WPF - Auto refresh combobox content,但没有运气。

这是我的代码, XAML:

<ComboBox Name="LeadTypeComboBox" ItemsSource="Binding LeadTypeCollection" />

视图模型:

public ObservableCollection<XmlNode> LeadTypeCollection  get; set; 

我更新这个集合的方式是在单独的方法中,它从更新的 XML 文件中加载数据:this.LeadTypeCollection = GetLeadTypesDataSource();

我也尝试使用Add 进行测试:

this.LeadTypeCollection = GetLeadTypesDataSource();
ItemToAdd = LeadTypeCollection[LeadTypeCollection.Count - 1];
this.LeadTypeCollection.Add(ItemToAdd);

代码更新集合肯定开始了,调试时我可以在这个集合中看到新项目,但我在组合框中看不到它们。

在 xaml 代码隐藏中执行此操作:LeadTypeComboBox.ItemsSource = MyViewModel.GetLeadTypesDataSource(); 但我想使用 MVVM 来实现这一点,即代码必须位于不知道 LeadTypeComboBox 控件的 ViewModel 中。

【问题讨论】:

【参考方案1】:

Firedragons 的回答会起作用,但我更愿意只初始化一次 LeadTypeCollection 并使用 clear,添加 remove 以更新您的集合。

var update = GetLeadTypesDataSource();     
this.LeadTypeCollection.Clear();

foreach(var item in update)

   this.LeadTypeCollection.Add(item);

如果数据上下文正确,您的 xaml 绑定应该可以工作

<ComboBox Name="LeadTypeComboBox" ItemsSource="Binding LeadTypeCollection" />

【讨论】:

我也倾向于这样做。财产筹集中内置的 ObservableCollections 效果很好。我展示的情况是您更改整个列表,我猜这不会引起更改 np 您的解决方案运行良好:) 但我更喜欢我的方法。并且就您使用 ICollectionView 进行排序和过滤而言 - 以我的方式更容易做到。【参考方案2】:

一个简单的方法是使用空列表更改 ItemsSource,然后将其更改回更新后的源。我的项目中的一个 sn-p 正在运行:

        RulesTable.ItemsSource = Rules.rulesEmpty;
        RulesTable.ItemsSource = Rules.Get();

【讨论】:

【参考方案3】:

我想我以前见过这种情况,解决方案是更新集合属性以引发更改。

public class MyViewModel : INotifyPropertyChanged

    private ObservableCollection<XmlNode> leadTypeCollection;

    public string LeadTypeCollection
     
        get  return leadTypeCollection; 
        set
        
            if (value != leadTypeCollection)
            
                leadTypeCollection = value;
                NotifyPropertyChanged("LeadTypeCollection");
            
        

    public MyViewModel()
    
        leadTypeCollection = new ObservableCollection<XmlNode>();
    

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String info)
    
        PropertyChanged.Raise(this, info);
    

我有一个提升属性的扩展方法(在 *** 的其他地方可以找到):

public static void Raise(this PropertyChangedEventHandler handler, object sender, string propertyName)

    if (null != handler)
    
        handler(sender, new PropertyChangedEventArgs(propertyName));
    

【讨论】:

啊,好的,ViewModel 应该继承INotifyPropertyChanged 接口,并且您的解决方案适用于已实现的PropertyChangedEventHandler 是的,没错。不过我会稍微整理一下代码:-) 不应该 LeadTypeCollection 的类型是 ObservableCollection&lt;XmlNode&gt; 而不是 string

以上是关于修改 ItemsSource ObservableCollection 后如何刷新组合框的主要内容,如果未能解决你的问题,请参考以下文章

修改 ItemsSource ObservableCollection 后如何刷新组合框

WPF ObservableCollection 异步调用问题

rxjs Observable 两大类操作符简介

重新绑定ItemsSource先设置ItemsSource = null;的原因

Rxjs toPromise 行为不同于 observable

如何在 Swift 上同步或使 Observable 等待?