概述
在上面一篇 Windows Community Toolkit 4.0 - DataGrid - Part01 中,我们针对 DataGrid 控件的 CollectionView 部分做了详细分享。而在本篇,我们会对 Utilities 文件夹中的类做详细的分享。
下面是 Windows Community Toolkit Sample App 的示例截图和 code/doc 地址:
Windows Community Toolkit Doc - DataGrid
Windows Community Toolkit Source Code - DataGrid
Namespace: Microsoft.Toolkit.Uwp.UI.Controls; Nuget: Microsoft.Toolkit.Uwp.UI.Controls.DataGrid;
开发过程
首先再来看一下 Utilities 文件夹的代码结构:
可以看到 Utilities 文件夹中的类主要是一些基础和帮助类,下面我们来看一些重要的类代码:
1. DoubleUtil
该类的功能主要是判断两个 double 类型的值之间是否接近,大小关系等;这些方法中用到了一个 AreClose(v1, v2) 的方法,这个方法主要判断两个数值是否相近,计算方法是,当两个值的差,除以两个值的绝对值和加10.0 的值小于 double epsilon 时,认为两个数值是接近的。而 double epsilon 表示大于零的最小 double 数值。
internal const double DBL_EPSILON = 1.1102230246251567e-016;
public static bool AreClose(double value1, double value2) { // in case they are Infinities (then epsilon check does not work) if (value1 == value2) { return true; } // This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON; double delta = value1 - value2; return -eps < delta && eps > delta; }
2. Extensions
该类的功能是 DataGrid 控件的扩展,主要有以下扩展方法:
- IsHandlerSuspended - 处理器暂停的标识;
- ContainsChild - 遍历可视化树,判断当前控件是否包含某个 child 元素,该方法在 WPF UWP 的很多控件中都有过体现;
- ContainsFocusedElement - 遍历可视化树,判断当前控件是否包含获得焦点的元素;
- GetIsReadOnly - 获取控件的只读属性;
- GetItemType - 获取元素类型,分为枚举和集合两种分类来判断;
- SetStyleWithType - 设置元素的样式;
- SetValueNoCallback - 设置值并中断回调;
- Translate - 计算起始和终止元素间的坐标移动;
- EnsureMeasured - 在控件被置于背景层时,需要计算尺寸;
- SuspendHandler - 暂停处理器的处理;
3. IndexToValueTable
该类的功能是 DataGrid 控件的索引和值表之间的处理,我们看几个重要的方法:
1) ContainsAll()
该方法的作用是判断给定的 startIndex 和 endIndex 间的索引范围,是否全部包含在表中;判断过程主要是根据 startIndex 和 endIndex 的值,以及 list 中的每个 range 的 UpperBound 和 LowerBound 的值,判断 startIndex 和 endIndex 是否包含在某个 range 中;
public bool ContainsAll(int startIndex, int endIndex) { int start = -1; int end = -1; foreach (Range<T> range in _list) { if (start == -1 && range.UpperBound >= startIndex) { if (startIndex < range.LowerBound) { return false; } start = startIndex; end = range.UpperBound; if (end >= endIndex) { return true; } } else if (start != -1) { if (range.LowerBound > end + 1) { return false; } end = range.UpperBound; if (end >= endIndex) { return true; } } } return false; }
2) FindRangeIndex()
获取当前 range 的索引,计算过程是:遍历 list 中的 range 集合,计算 front 和 end,每次获取中间值,如果 range 的上下限包含该 index,返回该 index;否则,根据 front 和 end 的对比,计算值作为索引返回;
private int FindRangeIndex(int index) { if (_list.Count == 0) { return -1; } int front = 0; int end = _list.Count - 1; Range<T> range = null; while (end > front) { int median = (front + end) / 2; range = _list[median]; if (range.UpperBound < index) { front = median + 1; } else if (range.LowerBound > index) { end = median - 1; } else { return median; } } if (front == end) { range = _list[front]; if (range.ContainsIndex(index) || (range.UpperBound < index)) { return front; } else { return front - 1; } } else { return end; } }
4. TypeHelper
该类是 DataGrid 控件的类型帮助类,主要功能是获取类型,属性信息,显示名等信息。这些方法都是较通用的方法,大家如果有兴趣,可以去详细查看代码,这里不做赘述。
5. ValidationUtil
该类的主要功能是 dataGrid 控件的校验,我们来看看 FindEqualValidationResult 方法:
public static ValidationResult FindEqualValidationResult(this ICollection<ValidationResult> collection, ValidationResult target) { foreach (ValidationResult oldValidationResult in collection) { if (oldValidationResult.ErrorMessage == target.ErrorMessage) { bool movedOld = true; bool movedTarget = true; IEnumerator<string> oldEnumerator = oldValidationResult.MemberNames.GetEnumerator(); IEnumerator<string> targetEnumerator = target.MemberNames.GetEnumerator(); while (movedOld && movedTarget) { movedOld = oldEnumerator.MoveNext(); movedTarget = targetEnumerator.MoveNext(); if (!movedOld && !movedTarget) { return oldValidationResult; } if (movedOld != movedTarget || oldEnumerator.Current != targetEnumerator.Current) { break; } } } } return null; }
6. VisualStates
该类是 DataGrid 控件的可视化状态类,主要分类一下几种状态组:
- Common - Normal,PointerOver,Pressed,Disabled
- Expanded - Expanded,Collapsed,Empty
- Focus - Unfocused,Focused
- Selection - Selected,Unselected
- Active - Active,Inactive
- Current - Regular,Current,CurrentWithFocus
- Interaction - Display,Editing
- Sort - Unsorted,SortAscending,SortDescending
- Validation - Invalid,RowInvalid,RowValid,Valid
- ScrollBarsSeparator - SeparatorExpanded,SeparatorCollapsed,SeparatorExpandedWithoutAnimation,SeparatorCollapsedWithoutAnimation
- ScrollBars - TouchIndicator,MouseIndicator,MouseIndicatorFull,NoIndicator
总结
这里我们把 DataGrid 的 Utilities 相关类介绍完成了,作为 DataGrid 相关分享的第二篇,后面我们会继续分享最重要的 DataGrid 的相关重点。
最后,再跟大家安利一下 WindowsCommunityToolkit 的官方微博:https://weibo.com/u/6506046490, 大家可以通过微博关注最新动态。
衷心感谢 WindowsCommunityToolkit 的作者们杰出的工作,感谢每一位贡献者,Thank you so much, ALL WindowsCommunityToolkit AUTHORS !!!