2016-11-24 148 views
1

我不知道如何更好地標題,所以我想到了解決方案。每當我打開一個頁面時使用新的ViewModel

這是問題所在。我有一個包含列表的頁面,列表中的每個項目都會打開一個詳細信息頁面(單擊)。但虛擬機被重用,這導致了幾個問題。

  • 以前的數據可以在打開的詳細信息頁面時可以看到的一瞬間

  • 我需要一定的屬性設置爲特定值時,該頁面打開,但由於虛擬機被重新使用它使所有從以前的細節中得到的價值和這使我的邏輯混亂起來。

這個UWP應用程序。我使用Template10框架的NavigationService在頁面之間移動。

主頁視圖模型

public class MainPageViewModel : ViewModelBase { 
    private List<MangaItem> _mangaList; 
    public List<MangaItem> mangaList { 
     get { return _mangaList; } 
     set { Set(ref _mangaList, value); } 
    } 

    private string _mainSearchText; 
    public string mainSearchText { 
     get { return _mainSearchText; } 
     set { Set(ref _mainSearchText, value); } 
    } 

    public MainPageViewModel() { 
     _mangaList = new List<MangaItem>(); 
     mangaList = new List<MangaItem>(); 

     Initialize(); 
    } 

    private async void Initialize() { 
     mangaList = await MangaListGet.GetListAsync(); 
    } 

    public async void MainSearchSubmitted() { 
     mangaList = await MangaListGet.GetListAsync(_mainSearchText); 
    } 

    public void MangaSelected(object sender, ItemClickEventArgs e) { 
     var mangaItem = (MangaItem)e.ClickedItem; 
     NavigationService.Navigate(typeof(Views.MangaDetail), mangaItem.id); 
    } 
} 

和細節頁面視圖模型

class MangaDetailViewModel : ViewModelBase { 

    private MangaItem _mangaDetail; 
    public MangaItem mangaDetail { 
     get { return _mangaDetail; } 
     set { Set(ref _mangaDetail, value); } 
    } 

    private string _mangaId; 

    public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState) { 
     _mangaId = parameter as string; 
     Initialize(); 

     await Task.CompletedTask; 
    } 

    private async void Initialize() { 
     mangaDetail = await MangaDetailGet.GetAsync(_mangaId); 
    } 

    public void ChapterSelected(object sender, ItemClickEventArgs e) { 
     var _chapterId = (ChapterListItem)e.ClickedItem; 
     NavigationService.Navigate(typeof(Views.ChapterPage), _chapterId.id); 
    } 
} 

此代碼僅示出了第一個問題是一秒鐘顯示先前加載的數據。如果需要,我會添加代碼來展示其他問題,但我不確定它現在是否真的相關。我在想,也許我的整個邏輯是有缺陷的或什麼的。

編輯:

<Page.DataContext> 
    <vm:ChapterPageViewModel x:Name="ViewModel" /> 
</Page.DataContext> 

其中VM被xmlns:vm="using:MangaReader.ViewModels"

+1

我在使用NavigationCacheMode時遇到同樣的問題。我刪除舊數據並在'OnNavigatedTo'中初始化頁面。只需在加載新數據之前刪除'DataContext = null;',然後在完成後重新附加它。 –

+0

你能更具體地告訴我如何在我的代碼中做到這一點?謝謝。 – rancor1223

+0

我不知道你如何將你的頁面綁定到你的視圖模型。如果將DataContext設置爲Viewmodel,則刪除綁定的'DataContext = null;'在ViewModel中設置新Data並使用'DataContext = mangaDetailViewModel'重新附加它。在你的DetailPage的'OnNavigatedTo'中做這件事。 –

回答

0

儘管Template10文檔聲明NavigationCacheMode默認情況下處於禁用狀態,但在示例模板(截至編寫本文時)情況並非如此。這是在View C#代碼(.xaml.cs文件)中設置的。

.xaml.cs文件

namespace MangaReader.Views { 
    public sealed partial class MangaDetail : Page { 
     public MangaDetail() { 
      InitializeComponent(); 
      //NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; //this was set by default 
      NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Disabled; 
     } 
    } 
} 

現在,新的視圖模型將每次訪問此頁時創建的。

1

另一種解決方案是使用Bootstrapper.ResolveforPage(),它旨在處理依賴注入,但很容易滿足您的需求。像這樣:

[Bindable] 
sealed partial class App : BootStrapper 
{ 
    static ViewModels.DetailPageViewModel _reusedDetailPageViewModel; 
    public override INavigable ResolveForPage(Page page, NavigationService navigationService) 
    { 
     if (page.GetType() == typeof(Views.DetailPage)) 
     { 
      if (_reusedDetailPageViewModel == null) 
      { 
       _reusedDetailPageViewModel = new ViewModels.DetailPageViewModel(); 
      } 
      return _reusedDetailPageViewModel; 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 

NavigationService將對待這與任何其他視圖模型相同。這意味着它會調用OnNavTo()並且其他導航覆蓋您包含的內容。

祝你好運。

+0

糟糕,我的解決方案字面上做了你所問的相反。 –

相關問題