【发布时间】:2020-02-04 20:23:40
【问题描述】:
我正在使用 Caliburn.Micro 为 MVVM 构建 WPF 应用程序。我正在尝试在应用程序运行时添加客户端,但无法让 ComboBox 更新/刷新。通过打印到控制台,我已确认 BindableCollection 已添加了一个项目,但即使我已包含以下行:
NotifyOfPropertyChange(() => Clients);
在属性定义中,组合框没有被更新/刷新。
代码如下:
ShellView.xaml 中的 ComboBox 控件
<ComboBox Grid.Column="2" Grid.Row="1" MinWidth="200" Margin="0,0,0,5"
x:Name="Clients" SelectedItem="{Binding SelectedClient}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ClientName}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
NewClientView.xaml中的按钮控件
<Button x:Name="AddClient" Content="Add Client" Width="100" Margin="5"/>
ShellViewModel.cs 中的属性:
public BindableCollection<ClientModel> Clients
{
get
{
return _clients;
}
set
{
_clients = value;
NotifyOfPropertyChange(() => Clients);
}
}
NewClientViewModel.cs(用于添加新客户端的用户控件)中按钮的返回代码:
public void AddClient(BindableCollection<ClientModel> Clients)
{
DataAccess.Clients.Add(new ClientModel
{
ClientName = ClientNameInput,
ClientProducts = null
});
Clients = new BindableCollection<ClientModel>(DataAccess.Clients);
TryClose(true);
}
有什么想法吗? 谢谢。
*编辑 1
当我尝试使用此代码直接添加客户端时:
public void AddClient(BindableCollection<ClientModel> Clients)
{
Clients.Add(new ClientModel
{
ClientName = ClientNameInput,
ClientProducts = null
});
TryClose(true);
}
它会引发“System.Reflection.TargetInvocationException” - 内部异常 1:NullReferenceException:对象引用未设置为对象的实例。
*编辑 2
我的 ShellViewModel 的构造函数:
public ShellViewModel()
{
Clients = new BindableCollection<ClientModel>(GenerateTestData());
}
GenerateTestData() 返回一个 ClientModel 类型的列表。
调用打开UserControl添加新客户端:
public void LoadNewClient()
{
ActivateItem(new NewClientViewModel());
}
【问题讨论】:
-
没有像
ItemSource="{Binding Clients}"这样的东西,那么Clients = new ...应该如何更新任何东西呢?请注意,当您只创建新的集合实例,但从不向现有实例添加或删除项目时,使用 BindableCollection 毫无意义。 -
您也许可以直接放弃
DataAccess.Clients并致电Clients.Add(...)。那么 Clients 属性也可以被声明为只读。 -
我发布了我最初尝试但出现错误的代码。我会尝试添加为只读。
-
Clients当然要初始化。声明为public BindableCollection<ClientModel> Clients { get; } = new BindableCollection<ClientModel>(); -
我在 ShellViewModel 的构造函数中对其进行了初始化。我不认为我将它传递给 NewClientViewModel(UserControl/Screen) 所以我假设这就是它没有被更新的原因。在 ViewModel 之间传递变量的最佳方式是什么?
标签: c# wpf data-binding combobox caliburn.micro