原文:UWP Composition API - New FlexGrid 锁定行列
如果之前看了 UWP Jenkins + NuGet + MSBuild 手把手教你做自动UWP Build 和 App store包
这篇的童鞋,针对VS2017,需要对应更新一下配置,需要的童鞋点击检察一下,在文章最后。
之前写过一篇 锁定列的FlexGrid,没看过的童鞋可以去先看一下那一篇。
先放上效果图
制作新控件的配景是SDK升级到了14393,Composition API 有了相应的转变。
对我们有较大的影响就是:
10586:
在 10586 版 SDK 中, ElementCompositionPreview.GetElementVisual 要领返回的 Visual 仅由挪用者控制。通过对应的 Visual 对一个 UIElement 进行的操纵纯粹只会对 XAML 施加增量影响。这是因为返回的 Visual (在底层)是 UIElement 的 Visual 作为根 Visual 的子项。
14393:
在 14332 版及后续版本中, ElementCompositionPreview.GetElementVisual 要领返回的 Visual与 XAML 构造操纵的 Visual 不异。这意味着差别于 11 月更新,此刻通过对应的 Visual 对一个 UIElement 元素进行的操纵会绝对地转变 XAML 构造。
因为挪用者和 XAML 都在操纵同一个 Visual,XAML 有可能会笼罩挪用者的赋值。以下是 XAML 可能设置的属性:
Offset
Size
Opacity
TransformMatrix
Clip
CompositeMode
XAML 对一个互操纵 Visual 属性进行更新的法则如下:
XAML 在构造过程中会覆写互操纵 Visual 的属性值。
XAML 不会读回由措施代码直接对互操纵 Visual 的属性赋的值。
XAML 只在新值不即是上次赋的旧值时,才会对互操纵 Visual 的属性赋值。亦即如果 XAML 一侧的属性值没有产生变革,则 XAML 不会去变动 Visual 一侧的属性值。
XAML 一侧的上次赋值的值默认与互操纵 Visual 属性的默认值一致。也就是说如果 XAML 一侧的属性值连结在默认值不乱,则 XAML 不会去更新 Visual 一侧的属性值(例如 XAML 构造中的 offset,对应 Visual 中的 Visual.Offset,默认值为 [0,0])。
Visual 一侧的属性值不会覆写到 XAML 一侧。
UI 元素最终泛起的效果取决于最后生效的值(Visual 一侧的取值或 XAML 覆写 Visual 的值)。
总的来讲就是以前Visual 是绝对由我来控制,而此刻XAML也会配合影响Visual 的最终值。
这样一搞,宝宝就不高兴了,直接把以前的项目升级到14393,FlexGrid各类问题。
秉着吐槽不如本身动手的表情,让我们本身创建New FlexGird。
首先,我们来看一下整个New FlexGird的组成,整个控件是一个ListView,头(Column Header 和 锁定的行)都放在ListView的ScrollViewer的TopHeader里面。
下面是整个New FlexGird的模板。
<ControlTemplate TargetType="local:NewFlexGrid"> <Border x:Name="RootBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> <ScrollViewer x:Name="ScrollViewer" Style="{StaticResource FlexGridScrollViewerStyle}" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"> <ScrollViewer.TopHeader> <StackPanel Orientation="Vertical" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <local:NewFlexGridColumnHeader x:Name="ColumnHeader" FrozenCount="{TemplateBinding ColumnHeaderFrozenCount}" SelectionMode="None" IsItemClickEnabled="True" Style="{StaticResource NoScrollViewerListViewStyle}" ItemsSource="{TemplateBinding ColumnsHeaderItemsSource}" ItemTemplate="{TemplateBinding ColumnsHeaderItemTemplate}"> <local:NewFlexGridColumnHeader.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </local:NewFlexGridColumnHeader.ItemsPanel> </local:NewFlexGridColumnHeader> <local:NewFlexGridFrozenRows x:Name="FrozenRows" ItemTemplate="{TemplateBinding ItemTemplate}" ItemsSource="{TemplateBinding FrozenRowsItemsSource}" IsItemClickEnabled="True" SelectionMode="None" Style="{StaticResource NoScrollViewerListViewStyle}" ItemContainerStyle="{TemplateBinding ItemContainerStyle}"> <local:NewFlexGridFrozenRows.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical"/> </ItemsPanelTemplate> </local:NewFlexGridFrozenRows.ItemsPanel> </local:NewFlexGridFrozenRows> </StackPanel> </ScrollViewer.TopHeader> <ItemsPresenter HorizontalAlignment="Left" VerticalAlignment="Top" FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" Padding="{TemplateBinding Padding}"/> <!--HeaderTemplate="{TemplateBinding HeaderTemplate}" Header="{TemplateBinding Header}" HeaderTransitions="{TemplateBinding HeaderTransitions}"--> </ScrollViewer> </Border> </ControlTemplate>
在获取到ScrollViewer元素以及New FlexGird Loaded的事件傍边,我们需要筹备Composition 的元素