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觸發。