首页 > 解决方案 > UWP IScrollSnapPointsInfo

问题描述

在此处输入图像描述我想使用 IScrollSnapPointsInfo 的实现创建一个自定义面板,我将 snapoffset 设置为 500px,我想为每 500px 的变化监听一个事件,目前我正在监听“Horizo​​ntalSnapPointsChanged”事件,但不知道如何在每 500 像素更改时调用它。请帮我。

标签: windowsuwpmicrosoft-metrowinrt-xaml

解决方案


我有一个宽度为 1*10^6 的面板,在我有 21 个网格(一天)中,我需要在面板中安排 21 天,当我向左滚动时,第一个网格应该移到最后一个网格,所以它提供了无限滚动效果。滚动时我需要捕捉视图,例如,如果一天的宽度是 500 像素,那么单个滚动应该会移动一整天。希望这能解释清楚,请就此提出建议。

使用 IScrollSnapPointsInfo 是自定义面板的方法。当面板直接放置在 ScrollViewer 中(scrollViewer.Content == 面板)或当它是 ItemsControl 的 ItemsPanel 时,将使用该实现。

我为您制作了一个代码示例。这对你来说应该是一个很好的起点。

<ScrollViewer HorizontalScrollMode="Enabled" HorizontalScrollBarVisibility="Hidden" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" VerticalScrollMode="Disabled">
        <local:CustomPanel HorizontalSnapPointsChanged="CustomPanel_HorizontalSnapPointsChanged">
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                <TextBlock Text="1" FontSize="100" Foreground="Yellow"></TextBlock>
            </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="2" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="3" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="4" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="5" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="6" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="7" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="8" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="9" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="10" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="11" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="12" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="13" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="14" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="15" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="16" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="17" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="18" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="19" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="20" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
            <Grid  Height="200" Width="500" Background="Black" BorderBrush="Red" BorderThickness="1 1 1 1">
                        <TextBlock Text="21" FontSize="100" Foreground="Yellow"></TextBlock>
                    </Grid>
        </local:CustomPanel>
    </ScrollViewer>
public class CustomPanel:Panel, IScrollSnapPointsInfo
{
    private float horizontalRegularSnapPointsInterval;
    private float verticalRegularSnapPointsInterval;



    public CustomPanel()
    {
        horizontalRegularSnapPointsInterval = 500f;
        verticalRegularSnapPointsInterval = 35f;
    }

    double x = 0;
    double y = 0;

    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (UIElement child in Children)
        {
            child.Arrange(new Rect(x, y, child.DesiredSize.Width, child.DesiredSize.Height));
            x = x + child.DesiredSize.Width;

        }
        x = 0;
        return finalSize;
    }

    protected override Size MeasureOverride(Size availableSize)
    {
        Size size = new Size(0, 0);

        foreach (UIElement child in Children)
        {
            child.Measure(availableSize);

        }

        size.Width = double.IsPositiveInfinity(availableSize.Width) ?
           500*21 : availableSize.Width;

        size.Height = double.IsPositiveInfinity(availableSize.Height) ?
           200 : availableSize.Height;

        return size;
    }



    public IReadOnlyList<float> GetIrregularSnapPoints(Orientation orientation, SnapPointsAlignment alignment)
    {
        // Returning null because the exposed snap points are regular instead of irregular. 
        return null;
    }

    public float GetRegularSnapPoints(Orientation orientation, SnapPointsAlignment alignment, out float offset)
    {
        offset = 0f;

        if (orientation == Orientation.Horizontal)
        {
            switch (alignment)
            {
                case SnapPointsAlignment.Near:
                    offset = (float)Margin.Left;
                    break;
                case SnapPointsAlignment.Center:
                    offset = horizontalRegularSnapPointsInterval / 2f + (float)Margin.Left;
                    break;
                case SnapPointsAlignment.Far:
                    offset = (float)Margin.Right;
                    break;
            }
            return horizontalRegularSnapPointsInterval;
        }
        else
        {
            switch (alignment)
            {
                case SnapPointsAlignment.Near:
                    offset = (float)Margin.Top;
                    break;
                case SnapPointsAlignment.Center:
                    offset = verticalRegularSnapPointsInterval / 2f + (float)Margin.Top;
                    break;
                case SnapPointsAlignment.Far:
                    offset = (float)Margin.Bottom;
                    break;
            }
            return verticalRegularSnapPointsInterval;
        }
    }

    public bool AreHorizontalSnapPointsRegular
    {
        get
        {
            return true;
        }
    }

    public bool AreVerticalSnapPointsRegular
    {
        get
        {
            return true;
        }
    }

    public event EventHandler<object> HorizontalSnapPointsChanged;
    public event EventHandler<object> VerticalSnapPointsChanged;

    // Invoke when the regular interval for the horizontal snap points changes
    private void UpdateHorizontalRegularSnapPointsInterval(float interval)
    {
        if (interval != horizontalRegularSnapPointsInterval)
        {
            horizontalRegularSnapPointsInterval = interval;
            RaiseHorizontalSnapPointsChanged();
        }
    }

    // Invoke when the regular interval for the vertical snap points changes
    private void UpdateVerticalRegularSnapPointsInterval(float interval)
    {
        if (interval != verticalRegularSnapPointsInterval)
        {
            verticalRegularSnapPointsInterval = interval;
            RaiseVerticalSnapPointsChanged();
        }
    }

    private void RaiseHorizontalSnapPointsChanged()
    {
        HorizontalSnapPointsChanged?.Invoke(this, null);
    }

    private void RaiseVerticalSnapPointsChanged()
    {
        VerticalSnapPointsChanged?.Invoke(this, null);
    }
}

推荐阅读