UWP Composition API, uwpcompositionapi

Source: Internet
Author: User

UWP Composition API, uwpcompositionapi

The requirement is that the first column is locked. How can I keep the lock column from moving with the scroll bar?

In fact, it is very easy to move the lock column and scrollviewer in the opposite direction.

Let's take a look at the template of this control. Well, it's actually very simple. It's the ListView template. The difference is that ScrollViewer adds TopHeader as the Column header.

 <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>                                <Grid>                                    <ListView x:Name="ColumnHeader" SelectionMode="None" IsItemClickEnabled="True" Style="{StaticResource NoScrollViewerListViewStyle}" ItemsSource="{TemplateBinding ColumnsHeaderItemsSource}" ItemTemplate="{TemplateBinding ColumnsHeaderItemTemplate}">                                        <ListView.ItemsPanel>                                            <ItemsPanelTemplate>                                                <StackPanel Orientation="Horizontal"/>                                            </ItemsPanelTemplate>                                        </ListView.ItemsPanel>                                    </ListView>                                    <ListView x:Name="FrozenColumnsHeader" Visibility="{TemplateBinding FrozenColumnsVisibility}" HorizontalAlignment="Left" VerticalAlignment="Stretch" SelectionMode="None" IsItemClickEnabled="True" Style="{StaticResource NoScrollViewerListViewStyle}" ItemsSource="{TemplateBinding FrozenColumnsHeaderItemsSource}" ItemTemplate="{TemplateBinding FrozenColumnsHeaderItemTemplate}">                                        <ListView.ItemsPanel>                                            <ItemsPanelTemplate>                                                <StackPanel Orientation="Horizontal"/>                                            </ItemsPanelTemplate>                                        </ListView.ItemsPanel>                                    </ListView>                                </Grid>                            </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>

The ItemContainer of the custom ListView needs to be rewritten.

        protected override bool IsItemItsOwnContainerOverride(object item)        {            return item is FlexGridItem;            return base.IsItemItsOwnContainerOverride(item);        }        protected override DependencyObject GetContainerForItemOverride()        {            return new FlexGridItem();            return base.GetContainerForItemOverride();        }

This FlexGridItem is inherited from ListVIewItem, And the template of ListViewItem has to be rewritten. The key changes are as follows:

                            <Border x:Name="ContentContainer">                                <Grid x:Name="InnerDragContent">                                    <Border x:Name="ContentBorder"                                        Background="{TemplateBinding Background}"                                        BorderBrush="{TemplateBinding BorderBrush}"                                        BorderThickness="{TemplateBinding BorderThickness}"                                        Margin="0">                                        <Grid>                                            <ContentPresenter x:Name="contentPresenter"                                                          ContentTransitions="{TemplateBinding ContentTransitions}"                                                          ContentTemplate="{TemplateBinding ContentTemplate}"                                                          Content="{TemplateBinding Content}"                                                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"                                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"                                                           />                                            <!-- The 'Xg' text simulates the amount of space one line of text will occupy.                                             In the DataPlaceholder state, the Content is not loaded yet so we                                             approximate the size of the item using placeholder text. -->                                            <Rectangle x:Name="pressedHider" Width="15" Opacity="0" Visibility="{TemplateBinding FrozenColumnsVisibility}" Margin="-10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Stretch" Fill="{ThemeResource ApplicationPageBackgroundThemeBrush}"/>                                            <ContentPresenter x:Name="frozenContent" Visibility="{TemplateBinding FrozenColumnsVisibility}"                                                          ContentTransitions="{TemplateBinding ContentTransitions}"                                                          HorizontalAlignment="Left"                                                          ContentTemplate="{TemplateBinding FrozenColumnsItemTemplate}"                                                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"                                                          />
FrozenContent is the column to be locked.
In FlexGridItem, let frozenContent slide horizontally with Scrollviewer.
        internal void StartAnimation(ScrollViewer sv)        {            _sv = sv;            if (_frozenContent == null || _sv == null || _pressedHider == null || _frozenContentVisual != null)            {                return;            }            _scrollerViewerManipulation = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(sv);            _compositor = _scrollerViewerManipulation.Compositor;            _offsetAnimation = _compositor.CreateExpressionAnimation("-min(0,ScrollManipulation.Translation.X)");            _offsetAnimation.SetReferenceParameter("ScrollManipulation", _scrollerViewerManipulation);            _frozenContentVisual = ElementCompositionPreview.GetElementVisual(_frozenContent);            _pressedHiderVisual = ElementCompositionPreview.GetElementVisual(_pressedHider);            _frozenContentVisual.StartAnimation("Offset.X", _offsetAnimation);            _pressedHiderVisual.StartAnimation("Offset.X", _offsetAnimation);        }

I have read this code well before using the UWP Composition API. ScrollViewer moves 100 to the right, and the locked content also moves 100 to the right, so that the locked content looks like it does not move.

However, there are many limitations on the Grid continued by ListView, so you cannot operate ScrollViewer with your own ideas. For more features, see the DataGrid.

Benefits of Open Source: FlexGrid

Note: The Composition API only supports versions 10586 and later. The judgment conditions are as follows:

Usage conditions:

    // Windows build 10240 and later.     if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 1))    {        ...    }    // Windows build10586 and later.    if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 2))    {        ...    }    // Windows build14332 and later.    if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 3))    {        ...    }
Debugged
1. Windows build14332 and later: 1, 2, 3 are true.
2. Windows build10586 and later: 1 and 2 are true.
3. Windows build 10240 and later: 1 is true.

Because versions earlier than 10586 do not support the Composition API. So remember to judge when using it:

    // Windows build10586 and later.    if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 2))    {        ...    }
 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.