问题描述
我在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所必需的。