【问题标题】:ComboBox is not updating when BindableCollection<T> is changed更改 BindableCollection<T> 时,ComboBox 不会更新
【发布时间】: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&lt;ClientModel&gt; Clients { get; } = new BindableCollection&lt;ClientModel&gt;();
  • 我在 ShellViewModel 的构造函数中对其进行了初始化。我不认为我将它传递给 NewClientViewModel(UserControl/Screen) 所以我假设这就是它没有被更新的原因。在 ViewModel 之间传递变量的最佳方式是什么?

标签: c# wpf data-binding combobox caliburn.micro


【解决方案1】:

使用 EventAggregator 在 ViewModel 之间传递变量。如果standard documentation 还不够,我可以更详细地解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    • 2021-09-26
    • 2013-07-01
    • 2018-09-15
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多