2017-02-24 86 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

當我按下按鈕時仍不會刷新:(當我更改列表框中的選定客戶端並返回時刷新。 –