XAML解析/布局呈现时间非常长
我遇到了一个问题,我创建了一个应用程序,将在WindowsPhone8.1和Windows10Mobile上运行。此应用程序是非UWP Windows应用商店应用程序。 我的问题是,我有一个自定义控件的列表,其中一个有另一个列表,该列表没有展开(=折叠)。看起来是这样的: 红色矩形是第一个XAML解析/布局呈现时间非常长,xaml,Xaml,我遇到了一个问题,我创建了一个应用程序,将在WindowsPhone8.1和Windows10Mobile上运行。此应用程序是非UWP Windows应用商店应用程序。 我的问题是,我有一个自定义控件的列表,其中一个有另一个列表,该列表没有展开(=折叠)。看起来是这样的: 红色矩形是第一个ItemControl的ContentPresenter项,绿色矩形是第一个列表项中ItemControl的ContentPresenter项,启动时不可见。单击展开按钮后,它将可见。两个ItemControl
ItemControl
的ContentPresenter
项,绿色矩形是第一个列表项中ItemControl
的ContentPresenter
项,启动时不可见。单击展开按钮后,它将可见。两个ItemControl
s都配置了一个DataTemplate
,以显示您在屏幕截图中看到的内容。(下面是XAML代码)
我的主要问题是,如果我将Pivot
更改为Pivot
,你会在上面的屏幕截图上看到,应用程序会冻结几秒钟。这取决于设备冻结的时间。在我个人电脑上的W10M模拟器中,我无法识别冻结,但在带有WP8.1的Lumia 620上,我的冻结时间为8.5秒。
在Visual Studio的探查器中,它看起来是这样的(我选择了我正在谈论的问题的范围):
我想知道的是带有“布局”的橙色大线条。如果我将其扩展到“大玩家”,则探查器中的每个不可见项都有60-70毫秒
我在问自己为什么会出现这种情况,即使项目不可见并且在virtualzingstackpanel
中。在本例中,第一个项目控制
(红色框)的项目源
的项目数为3,第二个项目控制
的项目数为17、59和1,只有第一个项目可见
我还想知道的是,关于时间线,所有项目都是同时处理的,因为它们的基线对于所有项目都是相同的。但是如果我向下滚动探查器的时间线细节,我会看到每个项目的另一个名为“解析”的事件。对于每个项目,该项不是并行处理,而是串行处理。最后一项的解析适合布局事件的结尾。此解析事件如下所示:
解析花费这么长时间的原因是什么?我不认为这些控件非常复杂,等等。除了一些字符串格式化之外,没有任何代码隐藏过程
最后是XAML代码:
应用程序“主页”上的我的数据透视项:
<PivotItem
Header="Echtzeit"
Margin="10,-20,10,0"
>
<Grid>
<ScrollViewer
VerticalScrollBarVisibility="Visible"
>
<ItemsControl
ItemsSource="{Binding RealtimeDepartures, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
HorizontalAlignment="Stretch"
Margin="0"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:RealtimeStation
StationName="{Binding StationName, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
Departures="{Binding DepartureList, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
FontSize="{Binding DataContext.ClientFontSize, ElementName=MainPg, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</PivotItem>
最后是realtimefeation
控件:
<UserControl
...
>
<Grid>
<control:DisruptionIcon
Height="24"
Width="50"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Icon="{Binding TrainIcon, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
Margin="3"
/>
<StackPanel
Orientation="Vertical"
Margin="56,9,0,0"
>
<StackPanel
Orientation="Horizontal"
Margin="3,0"
VerticalAlignment="Center"
>
<TextBlock
Text="{Binding DelayTimeText, ElementName=main, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding DelayColor, ElementName=main, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBlock
Text="{Binding DepartureDetailsText, ElementName=main, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Margin="3,0"
/>
</StackPanel>
<TextBlock
Text="{Binding InformationText, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, ElementName=main}"
Visibility="{Binding IsInformationVisible, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, ElementName=main}"
Margin="3"
FontStyle="Italic"
TextWrapping="Wrap"
/>
<TextBlock
Text="Zug fällt aus!"
Foreground="Red"
FontWeight="Bold"
Visibility="{Binding IsCanceledVisible, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, ElementName=main}"
Margin="3"
/>
</StackPanel>
</Grid>
</UserControl>
有人知道如何加快解析速度吗?它如此缓慢的原因是什么?我是否有一个设计问题,即禁用
VirtualizedStackPanel
的虚拟化功能?我已经尝试了很多,但没有找到速度如此之慢的原因。是的,关于这一点有很多要说的,但这是一个相当广泛的问题,需要一个广泛的答案,可能不是最适合这个网站的答案。您需要使用较少的面板进行适当的布局,例如使用日期模板选择器而不是这些嵌套的itemscontrol,并提供一个边界来调用虚拟化,itemscontrol没有内置scrollviewer。参考这里的wpf答案,但完整的答案将需要重写,对不起。您好@ChrisW.,我已经完成了您参考中的大部分操作。CanContentScroll
在Windows应用商店应用程序中没有可用的属性。。但是我也用ListView
s和ListBoxe
s代替了ItemsControl
,读了这篇文章却没有任何运气——感觉比以前更糟:附加信息:用当前数据检查:ListView vs ItemsControl(没有滚动查看器)=ListView
12秒vsItemsControl
7秒。因此,理论上“优化”的控件比未“优化”的控件慢得多(关于我的链接)Ya ListView/ListBox比ItemsControl要多得多,因为它们在默认的基本模板中内置了很多。ItemsControl实际上只是重复您作为项模板拥有的任何内容,而其他两个控件则包括每个项的操作、状态等,并以不同的方式呈现它们。然而,如果虚拟化实际上正在被调用,那么到目前为止,它应该会产生最大的不同。您的问题似乎是没有使用虚拟化b/c所有子项都嵌套在一起,因此需要为布局计算。正如Chris指出的,您应该用更平坦的东西来替换嵌套,即数据模板。你最终解决了吗?(四年后…)是的,关于这个问题有很多要说的,但这是一个相当广泛的问题,需要一个广泛的答案,可能不是最适合这个网站的。您需要使用较少的面板进行适当的布局,例如使用日期模板选择器而不是这些嵌套的itemscontrol,并提供一个边界来调用虚拟化,itemscontrol没有内置scrollviewer。参考这里的wpf答案,但完整的答案将需要重写,对不起。您好@ChrisW.,我已经完成了您参考中的大部分操作。CanContentScroll
在Windows应用商店应用程序中没有可用的属性。。但是我也用ListView
s和ListBoxe
s代替了ItemsControl
,读了这篇文章却没有任何运气——感觉比以前更糟:附加信息:用当前数据检查:ListView vs ItemsControl(没有滚动查看器)=ListView
12秒vsItemsControl
7秒。因此,理论上“优化”的控件比未“优化”的控件慢得多(关于我的链接)Ya ListView/ListBox比ItemsControl要多得多,因为它们在默认的基本温度中内置了很多
<UserControl
...
>
<Grid>
<control:DisruptionIcon
Height="24"
Width="50"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Icon="{Binding TrainIcon, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
Margin="3"
/>
<StackPanel
Orientation="Vertical"
Margin="56,9,0,0"
>
<StackPanel
Orientation="Horizontal"
Margin="3,0"
VerticalAlignment="Center"
>
<TextBlock
Text="{Binding DelayTimeText, ElementName=main, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding DelayColor, ElementName=main, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
/>
<TextBlock
Text="{Binding DepartureDetailsText, ElementName=main, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Margin="3,0"
/>
</StackPanel>
<TextBlock
Text="{Binding InformationText, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, ElementName=main}"
Visibility="{Binding IsInformationVisible, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, ElementName=main}"
Margin="3"
FontStyle="Italic"
TextWrapping="Wrap"
/>
<TextBlock
Text="Zug fällt aus!"
Foreground="Red"
FontWeight="Bold"
Visibility="{Binding IsCanceledVisible, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, ElementName=main}"
Margin="3"
/>
</StackPanel>
</Grid>
</UserControl>