2017-02-24 89 views
0

我有一个简单的MVVM WPF应用程序与数据库优先EF dbContext(这是Global.Database在我的应用程序),这是长期居住在我的应用程序。 我有一个窗口与列表框ItemsSource绑定到视图模型属性Clients这是我的dbmodel ClientObservableCollectionWPF实体框架刷新一个上下文实体

该列表框的SelectedItem被绑定到名为SelectedClient的视图模型属性。

Client实体类有一个字段叫last_status这是一个简单的int从我的数据库。

所以,在我看来,当我从列表框中选择客户端时,绑定到SelectedClient的last_status的标签应该显示值last_status

我在viewmodel中添加了一个按钮和一个刷新命令。我想要的是:当我手动更改我的数据库中客户端的last_status,并在我的视图中按刷新按钮时,标签的内容应该改变。但我绝对不知道如何实现这一目标。这里是我的视图模型代码的部分(我使用Catel,但不要紧,这种情况下):

public ClientManagerWindowViewModel() 
    { 

     RefreshClientInfoCommand = new Command(OnRefreshClientInfoCommandExecute); 

     Clients = new ObservableCollection<Client>(); 
     RefreshClients(); 
    } 

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

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

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

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


//here is my refresh button command handler: 

public Command RefreshClientInfoCommand { get; private set; } 

private void OnRefreshClientInfoCommandExecute() 
{ 
    RefreshClientInfo(SelectedClient); 
} 

//and here is my "logic" for working with dbcontext: 

private void RefreshClients() 
    { 
     var qry = (from c in Global.Database.Clients where c.client_id != 1 select c).ToList(); 
     Clients = new ObservableCollection<Client>(qry); 
    } 

private void RefreshClientInfo(Client client) 
    { 
     Global.Database.Entry(client).Reload(); 
    } 

我的XAML的列表框:

<ListBox 
        x:Name="ClientsListBox" 
        Grid.Row="1" 
        Margin="5" 
        DisplayMemberPath="fullDomainName" 
        IsSynchronizedWithCurrentItem="True" 
        ItemsSource="{Binding Clients}" 
        SelectedItem="{Binding SelectedClient}" /> 

我的XAML一个标签:

<Label Margin="5" Content="{Binding SelectedClient.last_status}" /> 

而对于一个按钮:

<Button Command="{Binding RefreshClientInfoCommand}" Content="↻"/> 

现在,当我在数据库中手动更改客户端的last_status值并按刷新按钮时,什么都不会发生。但是,当我在列表框中选择另一个客户端,然后返回到所需的客户端 - 标签内容正确更新。我知道,也许我错过了一些非常愚蠢和简单的事情,但我无法弄清楚究竟是什么。也许我需要在我的按钮命令处理程序中强制更改SelectedClient,或者以某种方式致电SelectedClient的设置程序... 请帮助我。非常感谢。

+0

你也应该刷新绑定。 –

回答

1

好吧,我想通了,什么是错我的代码。

我的数据绑定被设置为SelectedClient.last_status。由于某种原因,它没有按我的预期工作。所以,我创建了一个名为LastStatus一个新视图模型属性和修改我的RefreshClientInfo:

private void RefreshClientInfo(Client client) 
    { 
     Global.Database.Entry(client).Reload(); 
     LastStatus = client.last_status; 
     SetValue(SelectedClientProperty, client); 
    } 

和绑定标签,这个新属性。现在一切正常。

0

您需要将SelectedClient属性设置为从EF查询中返回的新对象Client

您可以通过在查询数据库之前存储当前所选客户端的client_id来完成此操作,然后选择具有此特定的新对象Client

试试这个:

private void RefreshClients() 
{ 
    int? currentlySelectedClientId = (SelectedClient != null) ? SelectedClient.client_id : default(int?); 
    var qry = (from c in Global.Database.Clients where c.client_id != 1 select c).ToList(); 
    Clients = new ObservableCollection<Client>(qry); 
    if (currentlySelectedClientId.HasValue) 
     SelectedClient = Clients.FirstOrDefault(x => x.client_id = currentlySelectedClientId.Value); 
} 

编辑:确保您从数据库中获取更新的记录:

private void RefreshClientInfo(Client client) 
{ 
    var newClient = (from c in Global.Database.Clients where c.client_id == client.client_id select c).ToList(); 
    SetValue(SelectedClientProperty, newClient[0]); 
} 
+0

对不起,我看不出它是如何帮助我的 - 我不想刷新所有客户端,我只想刷新一个。我通常要求的函数是'RefreshClientInfo(客户端客户端)',而不是'RefreshClients()'。但也许我不明白的东西。 –

+0

更新完成后,您需要从数据库中重新获取客户端。看我的编辑。 – mm8

+0

当我按下按钮时仍不会刷新:(当我更改列表框中的选定客户端并返回时刷新。 –