在我的应用中,我允许用户出于各种原因去市场。在加载市场时,如果用户非常快地点击后退按钮,它将尝试返回我保存的应用程序。来自iso-storage等的所有数据都加载得很好,但是屏幕被冻结了。我为各种枢轴项目设置了不同的应用程序栏,当我进行滑动动作时,我看到应用程序栏发生了变化,所以我知道应用程序是响应式的。
主要问题是屏幕卡在用户最初启动市场任务的位置。我理解在这个边缘情况下,我的App和Page构造函数没有触发,并且触发的事件是从导航,应用程序停用,应用程序激活和导航到。
我以为我可以使用布尔来基本涵盖市场任务被解雇时的情况,这样我就可以在on导航到方法中重新加载数据上下文并将其设置为我的视图模型。然而屏幕仍然冻结。
非常感谢有关此问题的任何帮助, 感谢
编辑:这是一些相关的代码
private void Application_Activated(object sender, ActivatedEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
DetermineIsTrial();
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
if (playerController.chapterPlayer != null)
{
var store = new PersistentDataStorage();
store.Backup(StringResource.ChapterPosition, playerController.chapterPlayer.Position);
store.Backup(StringResource.ChapterUriString, playerController.chapterPlayer.Source.OriginalString);
store.Backup(StringResource.NaturalDuration, playerController.chapterPlayer.NaturalDuration.TimeSpan);
}
}
主页XAML:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
App.viewIdentifier = StringResource.MainPageView;
if (App.firstTimeLoading == false && PivotBackground.SelectedItem != SuggestedPivotItem)
{
BuildApplicationBar();
}
else if (PivotBackground.SelectedItem == SuggestedPivotItem)
{
BuildMarketPlaceApplicationBar();
}
if (App.firstTimeLoading == true)
{
BuildApplicationBar(); //builds the application bar
//Restore the state from tombstone and set the audioplayer.
App.playerController = new PlayerButtonsController();
App.playerController.SetMediaPlayer(App.MainAudioPlayer);
RestoreState();
ResourceDictionary appResourceList = App.Current.Resources;
App.firstTimeLoading = false;
//default source for chapter position
App.AudioMgr.SetChapterSource(0);
}
}
更多方法:
private void RestoreState()
{
var store = new PersistentDataStorage();
playerWasWhere = store.Restore<TimeSpan>(StringResource.ChapterPosition);
naturalDuration = store.Restore<TimeSpan>(StringResource.NaturalDuration);
currentAudioFile = store.Restore<String>(StringResource.ChapterUriString);
SetAudioListScrollPosition();
App.playerController.SetPositionFromIsoStorage(currentAudioFile, playerWasWhere, naturalDuration);
}
public void LoadData()
{
CreateAudioPlayerGUIfromChapterList();
CreateAboutMenuGUIfromExtrasData();
CreateQuotesMenuGUIfromExtrasData();
this.IsDataLoaded = true;
}
private void CreateAudioPlayerGUIfromChapterList()
{
int numberOfChapters = 0;
for (int i = 0; i < App.AudioMgr.Parts.Count; i++)
{
ObservableCollection<ItemViewModel> tempObservableCollection = new ObservableCollection<ItemViewModel>();
for (int j = 0; j < App.AudioMgr.Parts[i].NumberOfChapters; j++)
{
tempObservableCollection.Add(new ItemViewModel()
{
LineOne = ProcessTitle(App.AudioMgr.Chapters[numberOfChapters + j].Title),
LineTwo = App.AudioMgr.Chapters[numberOfChapters + j].StatusMessage,
ItemAlpha = 0.0,
ChapterForeground = ChapterInfo.StatusColor[(int)App.AudioMgr.Chapters[numberOfChapters + j].Status],
Progress = 0,
Width = 0,
UserColorTheme = App.accentBrush,
PlayIconVisible = Visibility.Collapsed,
ChapterDurationProgressBarAdjacent = StringResource.Space,
ContainingPart = i,
MediaStateImageSource = StringResource.KJIcons + App.themeDir + StringResource.AppBarSpeaker
});
}
numberOfChapters += App.AudioMgr.Parts[i].NumberOfChapters;
//no parts header doesn't need spacing or border since its the first header.
if (i == 0 && App.AudioMgr.Parts[i].Title == "")
{
Parts.Add(new PartsViewModel()
{
PartsHeader = StringResource.Space,
ChapterForeground = App.defaultForeground,
ChaptersInPart = tempObservableCollection,
PartsBackgroundBrush = App.partsBackgroundBrush,
PartsHeaderHeight = 0,
PartsBorderThickness = new Thickness(0)
});
}
//parts header needs spacing and border
else if (App.AudioMgr.Parts[i].Title != "")
{
Parts.Add(new PartsViewModel()
{
PartsHeader = App.AudioMgr.Parts[i].Title,
ChapterForeground = App.defaultForeground,
ChaptersInPart = tempObservableCollection,
PartsBackgroundBrush = App.partsBackgroundBrush,
PartsHeaderHeight = double.NaN,
PartsBorderThickness = new Thickness(0,0,0,2)
});
}
else
{
Parts.Add(new PartsViewModel()
{
PartsHeader = StringResource.Space,
ChapterForeground = App.defaultForeground,
ChaptersInPart = tempObservableCollection,
PartsBackgroundBrush = App.partsBackgroundBrush,
PartsHeaderHeight = 0,
PartsBorderThickness = new Thickness(0)
});
}
}
}
private void CreateAboutMenuGUIfromExtrasData()
{
int list_count = 0;
for (int i = 0; i < 3; ++i)
{
switch (i)
{
//Evaluate number of Authors
case 0:
list_count = DictionaryIterator(App.Parser.AboutAuthorsArrayList);
if (list_count == 1)
{
this.About.Add(new ItemViewModel() { LineOne = StringResource.AboutAuthor }); //for one author
}
else if (list_count > 1)
{
this.About.Add(new ItemViewModel() { LineOne = StringResource.AboutAuthors }); //for more than one author
}
break;
//Evaluate number of books (should only be one)
case 1:
list_count = DictionaryIterator(App.Parser.AboutBookArrayList);
if (list_count > 0)
this.About.Add(new ItemViewModel() { LineOne = StringResource.AboutBook });
break;
//Evaluate number of Readers
case 2:
list_count = DictionaryIterator(App.Parser.AboutNarratorsArrayList);
if (list_count == 1)
{
this.About.Add(new ItemViewModel() { LineOne = StringResource.AboutReader }); //for one reader
}
else if (list_count > 1)
{
this.About.Add(new ItemViewModel() { LineOne = StringResource.AboutReaders}); //for more than one reader
}
break;
}
}
}
private void CreateQuotesMenuGUIfromExtrasData()
{
int list_count = 0;
for( int i = 0; i < 6; ++i )
{
switch( i )
{
case 0:
list_count = DictionaryIterator(App.Parser.QuotesAuthorAboutArrayList);
if (list_count == 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesAboutAuthor});
else if(list_count > 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesAboutAuthors });
break;
case 1:
list_count = DictionaryIterator(App.Parser.QuotesAuthorFromArrayList);
if (list_count == 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesFromAuthor });
else if (list_count > 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesFromAuthors});
break;
case 2:
list_count = DictionaryIterator(App.Parser.QuotesBookAboutArrayList);
if (list_count > 0)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesAboutBook });
break;
case 3:
list_count = DictionaryIterator(App.Parser.QuotesBookFromArrayList);
if (list_count > 0)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesFromBook });
break;
case 4:
list_count = DictionaryIterator(App.Parser.QuotesReaderAboutArrayList);
if (list_count == 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesAboutReader });
else if (list_count > 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesAboutReaders });
break;
case 5:
list_count = DictionaryIterator(App.Parser.QuotesReaderFromArrayList);
if (list_count == 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesFromReader });
else if (list_count > 1)
this.Quotes.Add(new ItemViewModel() { LineOne = StringResource.QuotesFromReaders });
break;
}
}
}
答案 0 :(得分:2)
基本上这是因为您的代码锁定了UI线程。它锁定它的原因是因为它方式减慢。
现在查看您的代码,这是一项疯狂的工作量,您应该从隔离存储中加载一个简单的数据。您需要将所有这些UI工作移至View,并在创建实际视图时首先处理它,而不是之前的,就像您现在正在做的那样。
我个人不喜欢将viewmodel与你的App类耦合的想法,我也认为使用Application_Activated/Deactivated
进行墓碑化是没有意义的,而不是在OnNavigatedFrom
和OnNavigatedTo
处理持久性
我认为很难对导致问题的原因给出一个精确的答案,但我现在的猜测在于你正在使用墓碑化的过程来重新创建UI,而不是让它UIThread自己做的工作。
关于你在C#中生成UI的整个部分是非常错误的。 XAML就是为此而制作的,并且非常擅长制作它。
答案 1 :(得分:1)
如果代码真的被逻辑删除,你确定你只是恢复状态吗?
我怀疑你是在恢复状态之前回到你的应用程序,但仍在尝试恢复状态。您正在保存的内容以及如何恢复它将决定如何检查是否需要恢复它。检查null或不是defautl值可能是最简单的方法 如果您只保存您必须拥有的任何状态,您也可以获得更好的性能。您还应该尝试在OnNavigatingFrom事件中保存State,而不是OnNavigatedFrom事件。
您保存给IS的是什么以及如何保存? 为什么不使用Page.State对象?