1、Task 和Async 和 Await
.net4.0 与.net4.5 及以上有了差异
.net4.0版本:
只能使用Task异步:
1、var loadingTask = new System.Threading.Tasks.Task(delegate
{
//执行代码
});
loadingTask.Start();
2、System.Threading.Tasks.Task.Factory.StartNew(delegate
{
//执行代码
});
.net 4.5 有了Async 和 Await 关键字
可使用这种方式做异步编程
2、WPF 加载大数据界面卡死— UI 虚拟化
当界面需要绑定大数据的数据源时,会出现界面卡顿卡死的体验,
这时就可以用UI 虚拟化技术,WPF自带的
使用ItemsControl 控件时默认没有虚拟化,需要自定Template 和ItemsPanel
.net4.0 版本:
1、Template
(1)必须添加ScrollViewer(必要的)
(2)必须将 CanContentScroll="True" 置为True,也可以在ItemsControl通过依赖属性设置ScrollViewer.CanContentScroll="True"。(必要的)
(3)可以在ItemsControl通过依赖属性设置VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"(非必要)
<ItemsControl.Template> <ControlTemplate> <Border CornerRadius="10" BorderThickness="1" BorderBrush="LightGray"> <ScrollViewer VerticalScrollBarVisibility="Auto" CanContentScroll="True"> <ItemsPresenter/> </ScrollViewer> </Border> </ControlTemplate> </ItemsControl.Template>
2、ItemsPanel
(1)必须使用虚拟化面板。
官网介绍:
标准虚拟化面板包括WrapGrid和VirtualizingStackPanel。
如果将ItemsControl中的默认面板替换为非虚拟化面板(如VariableSizedWrapGrid或StackPanel),则会为该控件禁用 UI 虚拟化。
官网:Using virtualization with a list or grid (XAML) (Windows) | Microsoft Docs
<ItemsControl.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel>
3、关于路由事件执行时顺序的问题
WPF 基础 - 点击事件的执行顺序及 Button 点击事件的特殊性 - 鑫茂 - 博客园 (cnblogs.com)
关于隧道路由事件和冒泡路由事件,这个大佬说的很清楚。
我这里说的是直接路由事件
以自己亲自做的实验MouseDoubleClick和PreviewMouseDoubleClick为例:
触发顺序依然遵循隧道路由事件和冒泡路由事件的触发顺序
依次是:先隧道,后冒泡
父PreviewMouseDoubleClick
子PreviewMouseDoubleClick
子MouseDoubleClick
父MouseDoubleClick
但是直接路由事件PreviewMouseDoubleClick有一个问题(当然结合了官方的解释)
Control.PreviewMouseDoubleClick Event (System.Windows.Controls) | Microsoft Docs
官方的解释:
Although this routed event seems to follow a tunneling route through an element tree, it actually is a direct routed event that is raised along the element tree by each UIElement. If you set the Handled property to true
in a PreviewMouseDoubleClick event handler, subsequent PreviewMouseDoubleClick events along the route will occur with Handled set to false
, but the MouseDoubleClick event will occur with Handled set to true
. This is a higher-level event for control consumers who want to be notified when the user double-clicks the control and to handle the event in an application.
翻译(直接用软件翻译可能会造成理解有误):
尽管此路由事件看起来是(和隧道路由事件很像)遵循通过元素树的隧道路由,但它实际上是由每个 UIElement 沿元素树引发的直接路由事件。如果在 PreviewMouseDoubleClick 事件处理程序中将 Handled 属性设置为 true,沿着元素树隧道的后续的(后续的意思是子控件的) PreviewMouseDoubleClick 事件将以 Handled 为 false 的状态发生(Handled为True不能被触发,为false能被触发,但是这里却是以false的状态发生,就是说在这里仍然会被触发,前边Handled设置为True在这里不管用),但是 MouseDoubleClick 事件将以 Handled 为 True的状态发生(这里是以True的状态发生,就是说到这里不会被触发了,前边Handled设置为True在这里管用)。
例:
情况1:如果在父PreviewMouseDoubleClick中将Handled置为True
(1)双击父控件,执行顺序:
父PreviewMouseDoubleClick
结论:只执行PreviewMouseDoubleClick不执行MouseDoubleClick。
(2)双击子控件,执行顺序:
父PreviewMouseDoubleClick
子PreviewMouseDoubleClick
结论:虽然在父的PreviewMouseDoubleClick中将Handled置为True,但是依然会执行子的PreviewMouseDoubleClick,无论父的还是子的MouseDoubleClick都不会执行。
情况二:如果在父MouseDoubleClick中将Handled置为True
(1)双击父控件,执行顺序:
父PreviewMouseDoubleClick
父MouseDoubleClick
结论:父的PreviewMouseDoubleClick和MouseDoubleClick都会执行
(2)双击子控件,执行顺序:
父PreviewMouseDoubleClick
子PreviewMouseDoubleClick
子MouseDoubleClick
父MouseDoubleClick
结论:父子的PreviewMouseDoubleClick和MouseDoubleClick都会执行。
大结论:在PreviewMouseDoubleClick中将Handled置为True则只会阻止以后的MouseDoubleClick的触发,不会阻止元素树中的PreviewMouseDoubleClick触发,
而在MouseDoubleClick中将Handled置为True,也不会阻止元素树中以后的MouseDoubleClick触发。