2016-05-26 152 views
1

我想從多個ComboBoxes填充特定記錄的數據。我可以讓他們中的一個正常工作,但我認爲一個概念錯誤阻止了我獲得第二個正確的工作。我已經搜索了SelectedItem,SelectedValue和SelectedIndex的各種線程,並在提供指導後嘗試了我的代碼。顯然我做錯了什麼,但不知道是什麼。我非常瞭解我從互聯網上學到的所有東西。MVVM組合框SelectedIndex與SelectedItem

我正在使用實體框架6數據庫第一個數據模型。我有一個表(主),它有一個外鍵鏈接到Shift和另一個人事表。 Shift表具有ShiftId(PK)字段,其Identity設置爲true,Shift僅是一個字符串。人事表具有Identity設置爲false的PersonnelId(PK)(我從別處手動填充ID)以及名字和姓氏字段。

我的項目需要的流程是:1)獲取當前記錄,2)填充Shift組合框,3)顯示與當前記錄相關聯的班次,4)填充人員組合框,5)顯示關聯的人員與當前記錄,6)保存對記錄的任何更改(通過爲任一組合框選擇不同的值而建立的更改)。

我的ViewModel正在使用INotifyPropertyChanged,我想我已經實現了這個,因爲Shift ComboBox是有效的。

1)獲取所需的記錄正常工作。然後將其存儲爲「CurrentRecord」

2)填充Shift組合框工作正常。
在我型號我:

private ICollection<Gen_All_Shift> shiftList; 
    public ICollection<Gen_All_Shift> GetShiftList() 
    { 
     shiftList = context.Gen_All_Shift.OrderBy(p => p.ShiftId) 
              .ToArray(); 
     return shiftList; 
    } 

在我視圖模型我有:

public ICollection<Gen_All_Shift> ShiftList 
    { 
     get { return context.GetShiftList(); } 
    } 

    private Gen_All_Shift selectedShift; 
    public Gen_All_Shift SelectedShift 
    { 
     get { return selectedShift; } 
     set 
     { 
      if (value != selectedShift) 
      { 
       selectedShift = value; 
       NotifyPropertyChanged("SelectedShift"); 
      } 
     } 
    } 

然後XAML是:

 <ComboBox x:Name="cboShift" 
      ItemsSource="{Binding ShiftList}" 
      DisplayMemberPath="Shift" 
      SelectedIndex="{Binding CurrentRecord.ShiftIdFk, 
          UpdateSourceTrigger=PropertyChanged}" /> 

3)顯示目前輪班工作只要我具有綁定到SelectedIndex。如果我使用SelectedItem或SelectedValue,則在加載屏幕時組合框爲空。 (我也嘗試綁定到SelectedShift.ShiftId,但沒有給我想要的結果。)SelectedIndex將允許我改變選擇,並允許我正確地保存對實際數據庫的更改。我不知道我在做什麼錯誤,防止SelectedItem或SelectedValue工作。不理解這是什麼導致我有問題與我相信人員組合框。

4)填充人員組合框的作品。

在我型號我:

private ICollection<Personnel_All_PersonnelList> personnelList; 
    public ICollection<Personnel_All_PersonnelList> GetPersonnelList() 
    {    
      personnelList = context.Personnel_All_PersonnelList.Where(p=>p.Active == true) 
                   .OrderBy(p => p.LastName) 
                   .ThenBy(p => p.FirstName) 
                   .ToArray(); 
      return personnelList; 
    } 

在我視圖模型我:

public ICollection<Personnel_All_PersonnelList> PersonnelList 
    { 
     get 
     { 
       return context.GetPersonnelList(); 
     } 
    } 

    private Personnel_All_PersonnelList selectedPerson; 
    public Personnel_All_PersonnelList SelectedPerson 
    { 
     get { return selectedPerson; } 
     set 
     { 
      if (value != selectedPerson) 
      { 
       selectedPerson = value; 
       NotifyPropertyChanged("SelectedPerson"); 
      } 
     } 
    } 

然後在我的XAML我:

<ComboBox x:Name="cboTechnician" 
      ItemsSource="{Binding PersonnelList}" 
      DisplayMemberPath="LastName" 
      SelectedIndex="{Binding CurrentRecord.PersonnelIdFk, 
          UpdateSourceTrigger=PropertyChanged}" /> 

5)無論我嘗試哪種方式(SelectedIndex,SelectedItem,SelectedValue),顯示當前人員都不起作用。我猜這是因爲SelectedIndex不能正常工作,原因是索引號與PersonnelId沒有正確對齊,所以系統不知道哪一個被選中。

6)如果我只更改了Shift,保存對記錄的更改將有效。如果我在Personnel ComboBox中選擇一個人並嘗試保存,則會收到系統空例外。我認爲這是由於阻止SelectedIndex與人員組合框一起工作的相同問題引起的。

我想如果有人可以指出我正確的方向,爲什麼我無法獲得對SelectedItem工作正常的綁定,我將能夠弄清楚如何修復Personnel組合框。

回答

1

您嘗試的第一件事實際上是正確的,但有幾件事讓您失望。

例如:

get { return context.GetShiftList(); } 

通常,這是不是一個好主意。任何人調用此屬性將調用數據庫調用每次這將傷害性能,並不需要。

一個更好的想法是不是調用一個方法來負載ShiftList財產,像這樣的:

public void ReloadShiftList() 
{ 
    //TODO: Your logic here 

    ShiftList = ... 
} 

注:一定要在你的ShiftList財產實施INotifyPropertyChanged以更新每當此屬性發生更改時查看。

至於你的ComboBox,與SelectedItem綁定肯定是首選的方法。在第一次加載時,所選項目爲空白的原因是因爲SelectedShift被設置爲空。要解決這個問題,只需在加載ShiftList後設置SelectedShift即可。

ShiftList = ... 
SelectedShift = ShiftList.FirstOrDefault(); 

通過設置SelectedShiftShiftList.FirstOrDefault(),你將保證會有總是ComboBox選擇的東西(除非有在ShiftList沒有任何項目)。

最後,你的綁定是這樣的:

<ComboBox ItemsSource="{Binding ShiftList}" 
      SelectedItem="{Binding SelectedShift}" 
      ... /> 
0

@Mike Eason - 謝謝你,給了我我需要的東西!

視圖模型的轉變,現在看起來是這樣的:

private ICollection<Gen_All_Shift> shiftList; 
    public ICollection<Gen_All_Shift> ShiftList 
    { 
     get { return shiftList; } 
     set { shiftList = value; NotifyPropertyChanged("ShiftList"); } 
    } 

    private Gen_All_Shift selectedShift; 
    public Gen_All_Shift SelectedShift 
    { 
     get { return selectedShift; } 
     set { selectedShift = value; NotifyPropertyChanged("SelectedShift"); } 
    } 

    public void LoadShiftList() 
    { 
     ShiftList = context.GetShiftList(); 
     SelectedShift = ShiftList.Where(p => p.ShiftId == CurrentRecord.ShiftIdFk) 
           .FirstOrDefault(); 
    } 

隨着到LoadShiftList()的調用在視圖模型構造。

然後XAML現在作爲目標的綁定集到的SelectedItem:

 <ComboBox x:Name="cboShift" 
      ItemsSource="{Binding ShiftList}" 
      DisplayMemberPath="Shift" 
      SelectedItem="{Binding SelectedShift}" /> 

此前我一直試圖設置SelectedShift.ShiftId == CurrentRecord.ShiftIdfk。這一直給我一個空例外。指出使用.FirstOrDefault()讓我回到正確的道路上。再次感謝。