从ViewModel WPF更新XAML中的ComboBox ObservableCollection绑定

问题描述

我在WPF中工作,并且拥有一个视图模型return StreamBuilder<List<LobbyData>>( stream: DatabaseService(uid: user.uid).userData,builder: (context,snapshot) { if (snapshot.hasData) { userData = snapshot.data; } else { return Loading(); } }); ,它是我的ModifiedReasonViewModel用于XAML视图。 DataContext不显示调试时在数据上下文中可以看到的4个项目中的任何一个。我认为这肯定与我异步提取原因标签有关。有关如何解决此问题的任何想法?

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

这是我目前在XAML中使用的ComboBox

RadComboBox
d:DataContext="{d:DesignInstance Type=vm:ATMModifiedReasonViewModel,IsDesignTimeCreatable=True}">

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

<telerik:RadComboBox Name="ReasonCmbo"
                     ItemsSource="{Binding ReasonLabels}" 
                     DisplayMemberPath="Name"
                     IsEditable="False"
                     Margin="2" 
                     Grid.Column="1"
                     Grid.Row="1"
                     Grid.ColumnSpan="2">            
</telerik:RadComboBox>

非常感谢您的帮助!

解决方法

如果在运行时重新分配ReasonLabels集合,则必须实现https://docs.microsoft.com/en-us/ef/ef6/fundamentals/testing/mocking并引发INotifyPropertyChanged事件,否则绑定将不会注意到更改。

同样,如果您修改集合本身,例如添加或删除项目时,集合需要实现PropertyChanged,该集合提供事件以触发用户界面中的更新。 List<T>类型实现此接口,请改用INotifyCollectionChanged。如果对集合进行了修改,它将自动引发ObservableCollection<T>事件,从而触发绑定的更新。

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

在回调中设置属性并从设置者中引发PropertyChanged事件,或者在设置了背景后在回调中引发PropertyChanged事件字段:

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

引发事件是框架知道何时刷新UI所必需的。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...