Windows商店应用程序在页面之间导航时会暂停
本文关键字:导航 之间 暂停 应用程序 Windows | 更新日期: 2023-09-27 18:08:55
我正在使用OOTB网格应用程序模板构建Windows商店应用程序。我注意到当我向前或向后从一个页面导航到另一个页面时,有500-1000毫秒的停顿。当我点击后退按钮时,这主要是显而易见的(后退箭头在500-1000毫秒内保持在"击中"状态)。往前看也没那么糟糕,因为通常屏幕上有动画和过渡来填充大部分加载时间。
我的第一个想法是,在LoadState
方法上有一些东西导致减速,但我唯一拥有的不是来自我在后台线程上运行的模板,并使用async
前言调用它。
我的第二个想法是,我是传递一个复杂的对象到每个页面的navigationParameter
,而不是仅仅传递一个简单的字符串。我不认为这可能是原因,因为对象应该通过引用传递,所以真的不应该有任何减速,因为我传递了一个非字符串到NavigateTo
方法。
(我没有读过任何关于这方面的指导,所以我不知道在页面之间传递非字符串时页面导航是否不那么灵活。如果有人对此有任何见解,那就太好了)
我的下一个想法是,我的Xaml太复杂了,暂停是Xaml加载所有的项目到列表和什么不是。这可能是问题,如果是这样,我不知道如何测试或修复它。加载完所有内容后,UI感觉很流畅(页面上的所有项目都流畅滚动)
如果是这种情况,是否有任何方法来显示一个加载圆圈与Xaml生成,然后一旦它完成生成,淡出内容和圆圈?
我想要修复的主要事情是我不希望后退按钮在点击中"冻结"。任何帮助或指导将是伟大的!
应用基本信息:
页面有列表和网格视图控件与不同的项目模板的组合。没有使用图像或图形,但我确实在一些项目模板上使用了渐变笔刷(不是超级复杂,类似于开始屏幕的项目渐变)。大多数列表只有20-30个项目,有些多一些,有些少。
平均页面有1个项目源和2个项目显示控件,一个列表和一个滚动查看器,用于保存所选项目的详细信息。
任何项目的详细信息大约是2-3段正常的详细信息文本和3-4段<</p>
编辑:项目代码:
第1页代码
protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
if (navigationParameter == null)
this.DefaultViewModel["Groups"] = GlobalData.Catalog.Catalog;
else
this.DefaultViewModel["Groups"] = navigationParameter;
await GlobalData.LibraryDownload.DiscoverActiveDownloadsAsync();
}
DiscoverActiveDownloadsAsync
方法与下面的示例代码
SaveState
, OnNavigateTo
和OnNavigateFrom
方法没有从LayoutAwarePage
基类修改。
第二页代码
protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
if (navigationParameter is CatalogBook)
{
var catBook = (CatalogBook)navigationParameter;
var book = catBook.Book;
await book.InitializeAsync();
this.DefaultViewModel["Group"] = catBook;
this.DefaultViewModel["Items"] = book.Items;
}
else if (navigationParameter is IBook)
{
var book = await Task.Run<IBook>(async () =>
{
var b = (IBook)navigationParameter;
await b.InitializeAsync();
return b;
});
this.DefaultViewModel["Group"] = book;
this.DefaultViewModel["Items"] = book.Chapters;
}
if (pageState == null)
{
// When this is a new page, select the first item automatically unless logical page
// navigation is being used (see the logical page navigation #region below.)
if (!this.UsingLogicalPageNavigation() && this.itemsViewSource.View != null)
{
this.itemsViewSource.View.MoveCurrentToFirst();
}
}
else
{
// Restore the previously saved state associated with this page
if (pageState.ContainsKey("SelectedItem") && this.itemsViewSource.View != null)
{
var number = 0;
if(!int.TryParse(pageState["SelectedItem"].ToString(), out number)) return;
var item = itemsViewSource.View.FirstOrDefault(i => i is ICanon && ((ICanon)i).Number == number);
if (item == null) return;
this.itemsViewSource.View.MoveCurrentTo(item);
itemListView.UpdateLayout();
itemListView.ScrollIntoView(item);
}
}
}
...
protected override void SaveState(Dictionary<String, Object> pageState)
{
if (this.itemsViewSource.View != null)
{
var selectedItem = this.itemsViewSource.View.CurrentItem;
pageState["SelectedItem"] = ((ICanon)selectedItem).Number;
}
}
InitializeAsync
方法从SQLite数据库中读取一本书的一些基本信息(章节,作者等),并且通常运行得非常快(<10 ms)
我通过使用SQLite-net Nuget包的异步方法查询SQLite数据库来获取数据。查询通常看起来像这样:
public async Task InitializeAsync()
{
var chapters = await _db.DbContext.Table<ChapterDb>().Where(c => c.BookId == Id).OrderBy(c => c.Number).ToListAsync();
Chapters = chapters
.Select(c => new Chapter(_db, c))
.ToArray();
HeaderText = string.Empty;
}
我使用以下Xaml填充网格:
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
IsSourceGrouped="true"
ItemsPath="Items"
d:Source="{Binding DisplayCatalog, Source={d:DesignInstance Type=data:DataCatalog, IsDesignTimeCreatable=True}}"/>
<common:CatalogItemTemplateSelector x:Key="CatalogItemTemplateSelector" />
...
<GridView
Background="{StaticResource ApplicationPageLightBackgroundThemeBrushGradient}"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
SelectionMode="Multiple"
Grid.Row="1"
ItemTemplateSelector="{StaticResource CatalogItemTemplateSelector}"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick" Margin="-40,0,0,0">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Height="628" Margin="120,10,0,0" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="1,10,0,6">
<Button
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextPrimaryButtonStyle}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Margin="0,0,80,0" ItemHeight="{StaticResource ItemHeight}" ItemWidth="{StaticResource ItemWidth}"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
CatalogItemTemplateSelector
类看起来像这样:
public class CatalogItemTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
// cast item to your custom item class
var customItem = item as ICatalogItem;
if (customItem == null)
return null;
string templateName = String.Empty;
if (customItem is CatalogFolder || customItem is CatalogMoreFolder)
{
templateName = "FolderItemDataTemplate";
}
else if (customItem is CatalogBook || customItem is CatalogMoreBook)
{
templateName = "BookItemDataTemplate";
}
object template = null;
// find template in App.xaml
Application.Current.Resources.TryGetValue(templateName, out template);
return template as DataTemplate;
}
}
两个模板都是20行Xaml,没什么特别的
如果还有其他没有包含的代码片段,请告诉我,我将添加它们。
您的内存使用情况如何?您是否正在分页到磁盘?
节选自http://paulstovell.com/blog/wpf-navigation
页面生命周期....
假设你的页面需要一些参数数据传递给它:…导航时,如果你点击"Back", WPF不可能知道要传递什么值给构造函数;因此,它必须保持页面的活力。
…如果你直接导航传递一个对象,WPF将使该对象保持活动状态。
我不知道答案,但是这个Channel 9 (Microsoft)视频在XAML性能方面非常好。也许它可以帮助你解决你的问题。
http://channel9.msdn.com/events/build/2012/4 - 103