2016-02-18 91 views
4

時,會丟失我仍然認爲我是一個新手,當談到MVVM和我有一個TabControl的一個結合的問題。我的應用程序允許用戶創建國家和州,輸入一些信息,然後將它們保存到數據庫中。下面是我的應用程序是如何構成的描述:綁定使用的TabControl和MVVM

基礎視圖模型/視圖稱爲ApplicationViewModel/ApplicationView。 ApplicationViewModel有一個名爲Tabs的ObservableCollection,它由一個AllNationsViewModel和一個AllStatesViewModel組成。此Tabs屬性綁定到ApplicationView中的TabControl的ItemsSource。

AllNationsViewModel/AllNationsView用於顯示已被用戶輸入的所有國家。它還允許用戶創建新的國家並選擇一個特定的國家進行更仔細的檢查。 AllStatesViewModel/AllStatesView對狀態執行相同的操作。

最後我有NationViewModel/NationsView與特定國家的協議條款;在這裏也有StateViewModel/StateView對一個狀態做同樣的事情。

對於目前只輸入一個名字一個國家,你可以但對於一個國家,你可以輸入一個名字,以及它的一部分國家。這個國家是通過一個組合框來選擇的,在這個組合框中所有在這個國家標籤中創建的國家都出現

我使用了一個名爲DataFacade靜態類爲我的數據存儲的接口。可以使用此界面添加,刪除和檢索國家/州的列表;還會在添加或刪除某些內容時觸發事件。

我遇到的問題是,當在AllStatesViewModel(CurrentStateViewModel屬性)中選擇一個狀態時,我會轉到「國家」選項卡,然後回到「狀態」選項卡,當前所選狀態已失去其國家。所有其他州仍然堅韌。

我會嘗試下面顯示的相關代碼(我已經從一些方法去除不相關的代碼):

State類:

class State 
{ 
    public string Name { get; set; } 

    public Nation Nation { get; set; } 
} 

的TabControl在ApplicationView:

<TabControl ItemsSource="{Binding Tabs}" Margin="6"> 
    <TabControl.ItemTemplate> 
     <DataTemplate> 
     <ContentPresenter Content="{Binding DisplayName}" /> 
     </DataTemplate> 
    </TabControl.ItemTemplate> 
    <TabControl.ContentTemplate> 
     <DataTemplate> 
     <ContentPresenter Content="{Binding }" /> 
     </DataTemplate> 
    </TabControl.ContentTemplate> 
</TabControl> 

當用戶創建一個國家時,觸發AllNationsViewModel的AddCommand:

private void Add(NationViewModel vm) 
{ 
    DataFacade.AddNation(vm.Nation); 
} 

的AllStatesViewModel當一個國家被添加到數據存儲得到通知:

private void OnDataStoreNationsChanged(object sender, DataFacadeEventArgs e) 
{ 
    Nations.Add(new NationViewModel(e.Context as Nation)); 
} 

的民族屬性上面是NationViewModels的一個ObservableCollection。現在,這個屬性被使用在StateView組合框來填充它的項目,以便可以在創建時,可以選擇/編輯狀態的國家:

<ComboBox Grid.Row="1" Grid.Column="1" SelectedValue="{Binding Nation}" SelectedValuePath="Nation" ItemsSource="{Binding DataContext.Nations, RelativeSource={RelativeSource AncestorType={x:Type local:AllStatesView}}}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
     <TextBlock Text="{Binding Name}" /> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

我相信問題與上面的結合做。因爲如果我不綁定到AllStatesViewModel中的Nations屬性,而是綁定到ApplicationViewModel中的臨時屬性,則一切正常。當我轉到另一個選項卡時,是否可以通過TabControl將AllStatesView扔掉?上面的綁定將StateViewModel的Nation屬性設置爲null?當我調試時,我看到我退出狀態選項卡時得到一個空值。

不像我這樣的初學者會如何解決這種情況?我發現我的臨時解決方案相當難看。我不完全確定我應該如何處理數據存儲訪問,因爲我發現的所有MVVM示例都不關注這部分。

編輯:Addded一些圖片的要求:

大氣壓我只是最簡單的測試GUI設置:

這裏你可以看到的AllNationsView,ATM的NationView只有「名稱」的TextBlock和文本框在頂部。

Nations

這裏是AllStatesView,在頂部爲當前選擇的狀態(使用StateView顯示)。如果你現在看到美國被選爲蒙大拿州的國家,如果我去國家選項卡,然後回到國家選項卡,蒙大拿州的國家現在是空白的。如果我選擇佛羅里達州,它仍然有美國作爲其國家。

States

+0

我很難想象你正在描述的設置。你可以張貼一些截圖嗎? –

+0

@BradleyUffner我已經添加了兩張照片。我希望現在更清楚我正在努力做什麼。 – dbostream

+0

謝謝,現在更清楚了。 –

回答

2

WPF只保存在存儲器中的活動選項卡的用戶界面。當您更改UI被銷燬的標籤並且新標籤的UI被創建並反彈時。

有幾種解決問題的方法。您可以使用存儲庫模式來存儲和訪問獨立於視圖模型的數據源。基本上,外部對象包含您的數據源,例如州和國家列表。這樣,當活動選項卡更改時,它們不會被破壞。

另一種選擇是將數據源存儲在您的ApplicationViewModel上,並通過對每個單個選項卡視圖模型上的ApplicationViewModel的引用來訪問它們。你不應該在任何地方使用一個RelativeSource綁定。

+0

感謝您的建議。關於存儲庫模式,似乎我在DataFacade類中有類似的東西。它是存儲我所有模型(國家和州)的外部對象,我可以將它們全部作爲列表檢索。我嘗試將Nation屬性從AllStatesViewModel移動到StateViewModel,從而消除了對ComboBox的RelativeSource綁定的需求,現在它似乎可以工作。無論如何,AllStatesViewModel並沒有使用Nations屬性來完成其他任何事情。 – dbostream