【问题标题】:How can I refresh a combobox after modifying its ItemsSource ObservableCollection修改 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 中。

【问题讨论】:

    标签: wpf xaml data-binding mvvm observablecollection


    【解决方案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);
          }
      }
      

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

      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
      猜你喜欢
      • 1970-01-01
      • 2013-03-09
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2013-06-19
      • 2017-02-23
      • 1970-01-01
      • 2020-10-31
      相关资源
      最近更新 更多