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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7914549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 23:09:07  来源:igfitidea点击:

How can I refresh a combobox after modifying its ItemsSource ObservableCollection

wpfxamldata-bindingmvvmobservablecollection

提问by Грозный

The problems is simple: when ItemsSourceis updated Combobox doesn't "refresh" e.g. new items don't appear to be added to the list of items in the combobox.

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

I've tried the solution from aceepted answer to this question: WPF - Auto refresh combobox contentwith no luck.

我已经尝试过这个问题的回答中的解决方案:WPF -没有运气自动刷新组合框内容

here's my code, XAML:

这是我的代码,XAML:

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

ViewModel:

视图模型:

public ObservableCollection<XmlNode> LeadTypeCollection { get; set; }

the way I update this collection is in the separate method, which loads data from updated XML file: this.LeadTypeCollection = GetLeadTypesDataSource();

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

I've also tried using Addfor testing purposes:

我也试过Add用于测试目的:

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

the code updating collection definitely kicks off, I can see new items in this collection when debugging, but I don't see them in the combobox.

代码更新集合肯定会启动,调试时我可以在此集合中看到新项目,但在组合框中看不到它们。

Doing this in the xaml code-behind works: LeadTypeComboBox.ItemsSource = MyViewModel.GetLeadTypesDataSource();but I'd like to achieve this with MVVM, i.e. the code must be in ViewModel which isn't aware of LeadTypeComboBox control.

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

采纳答案by Firedragon

I think I have seen this before and the solution was to update the collection property to raise the change.

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

i.e.

IE

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);
    }
}

I have an extension method for raising the property (as found elsewhere on stackoverflow):

我有一个提高属性的扩展方法(如在 stackoverflow 上的其他地方找到的):

public static void Raise(this PropertyChangedEventHandler handler, object sender, string propertyName)
{
    if (null != handler)
    {
        handler(sender, new PropertyChangedEventArgs(propertyName));
    }
}

回答by blindmeis

Firedragons answer would work, but i would prefer to initialize the LeadTypeCollection just once and use clear, add remove to update your collection.

Firedragons 的答案会起作用,但我更愿意只初始化 LeadTypeCollection 一次并使用 clear, add remove 来更新您的收藏。

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

foreach(var item in update)
{
   this.LeadTypeCollection.Add(item);
}

your xaml binding should work if the datacontext is right

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

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

回答by vinsa

A simple method is to change ItemsSource with empty list and then change it back to your updated source. A snippet from my project which is working:

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

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