【问题标题】:WPF MVVM How can i bind a property to comboBox which changes context query?WPF MVVM 如何将属性绑定到更改上下文查询的组合框?
【发布时间】:2017-02-15 19:22:41
【问题描述】:

我有一个带有一个 Combobox 和一个 DataGrid 的 WPF 视图。我在我的应用程序中使用 Entity Framework 数据库第一个上下文作为日志项上下文。 假设,这个上下文是Global.DbContext。 我由 EF 创建的实体是:LogClient。 在我的 XAML 中,我有这样的绑定:

<DataGrid ItemsSource = {Binding LogEntries} />
<ComboBox ItemsSource="{Binding Clients}" SelectedItem = {Binding SelectedClient} DisplayMemberPath="fullDomainName"
            IsSynchronizedWithCurrentItem="True"/>

在我的视图模型中,我有这些属性(我使用的是 Catel 框架,所以这些属性看起来有点奇怪):

public ObservableCollection<Log> LogEntries
    {
        get { return GetValue<ObservableCollection<Log>>(LogEntriesProperty); }
        set { SetValue(LogEntriesProperty, value); }
    }

    public static readonly PropertyData LogEntriesProperty = RegisterProperty("LogEntries", typeof(ObservableCollection<Log>), null);

 public ObservableCollection<Client> Clients
    {
        get { return GetValue<ObservableCollection<Client>>(ClientsProperty); }
        set { SetValue(ClientsProperty, value); }
    }

    public static readonly PropertyData ClientsProperty = RegisterProperty("Clients", typeof(ObservableCollection<Client>), null);



    public Client SelectedClient
    {
        get { return GetValue<Client>(SelectedClientProperty); }
        set { SetValue(SelectedClientProperty, value); }
    }

    public static readonly PropertyData SelectedClientProperty = RegisterProperty("SelectedClient", typeof(Client), null);

还有一个构造函数:

public LogWindowViewModel()
    {


        Global.DbContext.Clients.Load();
        Clients = Global.DbContext.Clients.Local;

        var qry = Global.DbContext.Logs.Where(c => c.client_id == SelectedClient.client_id);
        qry.Load();
        LogEntries = new ObservableCollection<Log>(qry);
    }

这不起作用,因为在构造函数执行时SelectedClient 为空。我希望我的 dbset 仅包含选定客户端的 LogEntries(db 中的客户端和日志表都有一个 client_id 字段)。我怎样才能做到这一点? 我不明白我的构造函数代码是完全错误的,但我无法弄清楚在“纯 MVVM”方法的上下文中该怎么做。如果可以,请帮助我。

【问题讨论】:

    标签: c# wpf entity-framework mvvm


    【解决方案1】:

    如果我说对了,我会这样做:

    1) 在构造函数中创建 ObserableCollections 的新实例,以便建立绑定。

    2)将填充LogEntry List的代码移动到SelectedClient的Setter中

     public Client SelectedClient
    {
        get { return GetValue<Client>(SelectedClientProperty); }
        set { 
                 SetValue(SelectedClientProperty, value);
                 if(value == null)
                 {
                     return;
                 }
                 var qry = Global.DbContext.Logs.Where(c => c.client_id ==   value.client_id);
                qry.Load();
                LogEntries.Clear();
                foreach(var entry in qry)
                {
                    LogEntries.Add(entry);
                }
            }
    }
    

    【讨论】:

    • 仍然出现空引用异常,因为 SelectedClient 为空。(顺便说一句,不是我否决了你的答案=))
    • 如果在 setter 中得到 null 异常,只需添加一个 if(value != null)。 WPF 可能会将 SelectedItem 设置为 null,因为没有选择任何项目
    • 对不起,我的错误,我的示例代码应该在SelectedClient的setter中。我已经用文本写了这个,但是示例代码在客户端的设置器中。刚刚修好了...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2015-09-15
    • 1970-01-01
    • 2018-01-12
    • 2021-10-11
    • 2015-07-11
    • 2015-04-27
    相关资源
    最近更新 更多