首页 > 解决方案 > 从 ViewModel WPF 更新 XAML 中的 ComboBox ObservableCollection 绑定

问题描述

我在 WPF 中工作,并且有一个用于 XAML 视图的视图ModifiedReasonViewModel模型DataContextComboBox不显示调试时我可以在数据上下文中看到的 4 个项目中的任何一个。我认为这肯定与我异步提取原因标签的事实有关。有想法该怎么解决这个吗?

当我仅使用在构造函数中初始化的测试字符串列表来测试此代码时,它会按预期工作。

这是RadComboBox我目前在 XAML 中使用的内容:

d:DataContext="{d:DesignInstance Type=vm:ATMModifiedReasonViewModel, IsDesignTimeCreatable=True}">
<telerik:RadComboBox Name="ReasonCmbo"
                     ItemsSource="{Binding ReasonLabels}" 
                     DisplayMemberPath="Name"
                     IsEditable="False"
                     Margin="2" 
                     Grid.Column="1"
                     Grid.Row="1"
                     Grid.ColumnSpan="2">            
</telerik:RadComboBox>

这是我正在使用的 ViewModel 代码:

public class ATMModifiedReasonViewModel : INotifyPropertyChanged
{
   private List<LabelFileModel> _reasonLabels;

   public List<LabelFileModel> ReasonLabels { get { return _reasonLabels; } set { _reasonLabels = value; } }

   public ATMModifiedReasonViewModel(){
      GetReasonLabels();
   }

   public void GetReasonLabels()
   {
      LabelFileProvider lfProvider = new LabelFileProvider();
      LabelFileModelFilter filter = new LabelFileModelFilter() {LabelDefinition = "ModifiedReason"};
      lfProvider.GetFiltered(filter,10, getResult => GetReasonLabelsCallback(getResult));
   }

   private void GetReasonLabelsCallback(Func<IEnumerable<LabelFileModel>> getResult)
   {
       try
       {
            _reasonLabels = (List<LabelFileModel>) getResult();                
       }   
       catch (Exception ex)
       {
            Messenger.Default.Send(new UnhandledExceptionMessage(this, ex));
       }
   }
}

非常感谢您的帮助!

标签: c#wpfxamlsilverlighttelerik

解决方案


如果ReasonLabels在运行时重新分配集合,则必须实现INotifyPropertyChanged并引发PropertyChanged事件,否则绑定不会注意到更改。

同样,如果您修改集合本身,例如添加或删除项目,则集合需要实现INotifyCollectionChanged,它提供事件以触发用户界面中的更新。该List<T>类型实现此接口,请ObservableCollection<T>改用。CollectionChanged如果集合被修改并因此触发绑定更新,它会自动引发事件。

public class ATMModifiedReasonViewModel : INotifyPropertyChanged
{
   private ObservableCollection<LabelFileModel> _reasonLabels;

   public ObservableCollection<LabelFileModel> ReasonLabels
   {
      get => _reasonLabels;
      set
      {
         if (_reasonLabels = value)
            return;

         _reasonLabels = value;
         OnPropertyChanged();
      } 
   }

   // ...your code here.

   public event PropertyChangedEventHandler PropertyChanged;

   protected virtual void OnPropertyChanged(string propertyName = null)
   {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
}

您还必须分配ReasonLabels属性而不是支持字段_reasonLabels,否则触发PropertyChanged事件的属性设置器将不会被执行。

private void GetReasonLabelsCallback(Func<IEnumerable<LabelFileModel>> getResult)
{
   try
   {
      ReasonLabels = (List<LabelFileModel>) getResult();                
   }   
   catch (Exception ex)
   {
      Messenger.Default.Send(new UnhandledExceptionMessage(this, ex));
   }
}

推荐阅读