概述 UWP Community Toolkit 中有一個開發者工具集 DeveloperTools,可以幫助開發者在開發過程中進行 UI 和功能的調試,本篇我們結合代碼詳細講解 DeveloperTools 的實現。 DeveloperTools 中目前包括了兩個工具: AlignmentGrid ...
概述
UWP Community Toolkit 中有一個開發者工具集 DeveloperTools,可以幫助開發者在開發過程中進行 UI 和功能的調試,本篇我們結合代碼詳細講解 DeveloperTools 的實現。
DeveloperTools 中目前包括了兩個工具:
- AlignmentGrid - 提供了 Grid 中的網格,開發者可以根據網格來檢查控制項對齊;除了開發過程中的輔助作用,開發者還可以使用它作為畫板輔助線,日記應用的網格等 UI 顯示;
- FocusTracker - 可以顯示當前聚焦的 XAML 元素信息,包括 name,type,AutomationProperties.Name 和 first parent name;
來看一下官方示例中的截圖:
Source: https://github.com/Microsoft/UWPCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.DeveloperTools
Doc: https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/developer-tools/alignmentgrid
https://docs.microsoft.com/zh-cn/windows/uwpcommunitytoolkit/developer-tools/focustracker
Namespace: Microsoft.Toolkit.Uwp.DeveloperTools; Nuget: Microsoft.Toolkit.Uwp.DeveloperTools;
開發過程
代碼分析
1. AlignmentGrid
AlignmentGrid 類繼承自 ContentControl,定義的依賴屬性如下:
- LineBrush - 網格線的顏色畫刷
- HorizontalStep - 網格橫向的步長,預設為 20.0
- VerticalStep - 網格縱向的步長,預設為 20.0,橫向和縱向步長可以不相等
以上三個屬性變化時,會觸發 OnPropertyChanged(d, e),和 AlignmentGrid_SizeChanged(s, e) 一樣,主要處理邏輯在 Rebuild() 方法中,下麵我們看看 Rebuild() 方法實現:
- 清空 containerCanvas,獲取當前橫向和縱向步長,如果 lineBrush 無效,則初始化為 ApplicationForegroundThemeBrush;
- 橫向迴圈繪製矩形,迴圈步長是橫向步長,總長度是控制項實際寬度;繪製矩形寬度為 1,高度為控制項實際高度,位置居左為當前總步長;
- 縱向迴圈繪製矩形,迴圈步長是縱向步長,總長度是控制項實際高度;繪製矩形高度為 1,寬度為控制項實際寬度,位置居上為當前總步長;
private void Rebuild() { containerCanvas.Children.Clear(); var horizontalStep = HorizontalStep; var verticalStep = VerticalStep; var brush = LineBrush ?? (Brush)Application.Current.Resources["ApplicationForegroundThemeBrush"]; for (double x = 0; x < ActualWidth; x += horizontalStep) { var line = new Rectangle { Width = 1, Height = ActualHeight, Fill = brush }; Canvas.SetLeft(line, x); containerCanvas.Children.Add(line); } for (double y = 0; y < ActualHeight; y += verticalStep) { var line = new Rectangle { Width = ActualWidth, Height = 1, Fill = brush }; Canvas.SetTop(line, y); containerCanvas.Children.Add(line); } }
2. FocusTracker
FocusTracker 包含了兩個文件:
- FocusTracker.xaml - FocusTracker 的樣式文件,主要定義了 FocusTracker 的顯示信息,如上面控制項介紹中所說的;
- FocusTracker.cs - 定義處理文件, 定義了 FocusTracker 的主要處理邏輯;
FocusTracker.cs
FocusTracker 類中定義了一個依賴屬性 IsActive,屬性變化時會觸發 OnIsActiveChanged(d, e) 處理方法,IsActive == true 時,調用 Start() 方法;IsActive == false 時,調用 Stop() 方法;
我們看到,類中的主要處理是定義一個 DispatcherTimer,在 Start() 方法中實例化並啟用它,Stop() 方法中停止它,並清空內容顯示;
private void Start() { if (updateTimer == null) { updateTimer = new DispatcherTimer(); updateTimer.Tick += UpdateTimer_Tick; } updateTimer.Start(); } private void Stop() { updateTimer?.Stop(); ClearContent(); }
來看一下 updateTimer 的 Tick 處理方法:
- 使用 FocusManager 獲取當前獲得焦點的元素,清空上一次獲取焦點的控制項內容信息;
- 分別獲取 Name、Type、AutomationProperties.Name 和 First Parent 信息,這對於代碼調試和自動化測試很有幫助;
private void UpdateTimer_Tick(object sender, object e) { var focusedControl = FocusManager.GetFocusedElement() as FrameworkElement; if (focusedControl == null) { ClearContent(); return; } if (controlName != null) { controlName.Text = focusedControl.Name; } if (controlType != null) { controlType.Text = focusedControl.GetType().Name; } if (controlAutomationName != null) { controlAutomationName.Text = AutomationProperties.GetName(focusedControl); } if (controlFirstParentWithName != null) { var parentWithName = FindVisualAscendantWithName(focusedControl); controlFirstParentWithName.Text = parentWithName?.Name ?? string.Empty; } }
調用示例
1. AlignmentGrid
我們在 Grid 中放了一個 AlignmentGrid 控制項,還有一個 TextBlock,做對比顯示,效果如下圖;
引申一下,我們可以修改 AlignmentGrid 繪製矩形的代碼,AlignmentGrid 中定義了 AlignmentGrid 作為矩形的邊框畫刷,我們可以根據矩形的位置,繪製出左邊到右邊漸變的畫刷,或者虛線的畫刷;或者跨度更大一些,使用 ImageBrush 來作為父控制項的九宮格顯示等,相信大家會有更豐富的想象和應用場景;
<Grid> <tools:AlignmentGrid LineBrush="Gray" HorizontalStep="40" VerticalStep="30" Opacity="1.0"/> <TextBlock Text="Hello World" FontSize="40" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid>
2. FocusTracker
我們使用 FocusTracker 來跟蹤對 TextBox 的聚焦事件,XAML 中設置的屬性和下麵運行顯示中的信息一致;
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <tools:FocusTracker IsActive="True" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBox x:Name="testTB" Text="textblock for test" AutomationProperties.Name="textblock" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,50,0,0"/> </Grid>
總結
到這裡我們就把 UWP Community Toolkit 中的 DeveloperTools 的實現過程和簡單的調用示例講解完成了,希望這些工具對大家開發 UWP 應用有所幫助,如果大家有更好用的工具類,也歡迎大家給 UWPCommunityToolkit 做 PR,貢獻自己的代碼,歡迎大家多多交流,謝謝!
最後,再跟大家安利一下 UWPCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通過微博關註最新動態。
衷心感謝 UWPCommunityToolkit 的作者們傑出的工作,Thank you so much, UWPCommunityToolkit authors!!!