[英]How to load usercontrols into a stackpanel asynchronously whilst showing progress bar
I am developing a WPF appl using C#. 我正在使用C#开发WPF应用程序。
I am trying to get my head around the async threading and tasks etc. 我试图让我的头脑异步线程和任务等。
Basically I have a usercontrol, that i add to a stackpanel in my page. 基本上我有一个用户控件,我将其添加到页面的堆栈面板中。 There can be many iterations of this usercontrol added to the stackpanel.
此用户控件的许多迭代都可以添加到堆栈面板中。
i.txtItemDescription.Text = "Item description " + ii.ToString() + ". Put a description here";
i.txtItemTitle.Text = "Item title " + ii.ToString() + ". Put a title here";
MainStack.Children.Add(i);
This works fine. 这很好。 However, when i transfer this appl to my windows 8.1 tablet it slows the display of these usercontrols(UCs) down dramatically.
但是,当我将此应用程序转移到Windows 8.1平板电脑时,它们会大大降低这些usercontrols(UCs)的显示速度。
I have tried using virtulization which had no effect as the data access and generation of the UCs poses no performance impact. 我尝试过使用虚拟化,因为数据访问和UC的生成对性能没有影响,因此虚拟化没有效果。 It is the physical drawing of the controls on the screen.
它是屏幕上控件的物理图。
So my question is as follows: 所以我的问题如下:
Any thoughts on how to would be appreciated! 关于如何的任何想法将不胜感激!
Regds Regds
Paul 保罗
First, you cannot create UI elements on a different thread than the one they will ultimately be rendered on, so forget about that possibility. 首先,您不能在与最终呈现它们的线程不同的线程上创建UI元素,因此请不要考虑这种可能性。
If it is the physical drawing of the controls that is causing performance problems, then you are probably not using UI virtualization correctly. 如果是导致性能问题的控件的物理绘图,则可能是您没有正确使用UI虚拟化。 The whole point of UI virtualization is to only perform layout and rendering for those controls which are actually in view, which means letting some sort of items host (like an
ItemsControl
) generate the corresponding UI elements as needed. UI虚拟化的全部目的是仅对那些实际在视图中的控件执行布局和渲染,这意味着让某种项目宿主(如
ItemsControl
)根据需要生成相应的UI元素。 Pre-populating the entire panel defeats the purpose, and a regular StackPanel
does not support virtualization anyway. 预先填充整个面板无法达到目的,常规的
StackPanel
仍然不支持虚拟化。 I suggest the following: 我建议以下内容:
Instead of using a StackPanel
directly, use an ItemsControl
with a VirtualizingStackPanel
in its ItemsPanelTemplate
. 而不是使用的
StackPanel
直接使用ItemsControl
与VirtualizingStackPanel
在其ItemsPanelTemplate
。
Instead of adding the user controls manually, bind the ItemsSource
to the underlying list of items, and let the ItemsControl
generate containers for the items as they are brought into view. 与其手动添加用户控件,不如将
ItemsSource
绑定到项目的基础列表,并让ItemsControl
为项目生成容器,使它们进入视图。
Use an ItemTemplate
to define how the items are rendered, eg, the template content should be your user control with the appropriate bindings. 使用
ItemTemplate
定义项目的呈现方式,例如,模板内容应是具有适当绑定的用户控件。
You can experiment with enabling container recycling on the VirtualizingStackPanel
; 您可以尝试在
VirtualizingStackPanel
上启用容器回收; depending on your use case, it may help or hurt performance. 根据您的用例,它可能会帮助或损害性能。
Anyway, if you follow this advice, you should not need a progress indicator, as the UI elements for your items will be generated as they are are needed, ie, as they are scrolled into view. 无论如何,如果您遵循此建议,则不需要进度指示器,因为将根据需要生成项目的UI元素,即当它们滚动到视图中时。
If you've never used virtualization with a plain old ItemsControl
before (the default style does not support it), you can use the style below as a starting point. 如果您以前从未使用过带有简单的旧
ItemsControl
虚拟化(默认样式不支持它),则可以使用以下样式作为起点。 Note that it supports scrolling, unlike the default ItemsControl
style. 请注意,它支持滚动,这与默认的
ItemsControl
样式不同。
<Style TargetType="{x:Type ItemsControl}">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll"
Value="True" />
<Setter Property="ScrollViewer.PanningMode"
Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled"
Value="False" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="VirtualizingStackPanel.IsVirtualizing"
Value="True" />
<Setter Property="VirtualizingStackPanel.VirtualizationMode"
Value="Recycling" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border x:Name="OuterBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="True">
<ScrollViewer Padding="{TemplateBinding Padding}"
Focusable="False">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter TargetName="OuterBorder"
Property="Background"
Value="{DynamicResource {x:Static apthemes:AssetResourceKeys.ListBackgroundDisabledBrushKey}}" />
</Trigger>
<Trigger Property="IsGrouping"
Value="True">
<Setter Property="ScrollViewer.CanContentScroll"
Value="False" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing"
Value="True">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.