加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使滚动查看器中的所选项居中

发布时间:2020-12-16 02:00:56 所属栏目:百科 来源:网络整理
导读:我试图将一个选定的项目放在ScrollViewer内的ListView中心,并努力计算我应该相对于ListView设置ScrollViewer的垂直偏移量. 以下链接为我设置了正确的轨道,但由于WinRT API的限制,无法使用它们: Make ListView.ScrollIntoView Scroll the Item into the Cent
我试图将一个选定的项目放在ScrollViewer内的ListView中心,并努力计算我应该相对于ListView设置ScrollViewer的垂直偏移量.

以下链接为我设置了正确的轨道,但由于WinRT API的限制,无法使用它们:

> Make ListView.ScrollIntoView Scroll the Item into the Center of the ListView (C#)
> http://blogs.msdn.com/b/delay/archive/2009/04/19/fewer-gotchas-to-getcha-enhancing-the-scrollintoviewcentered-method-for-wpf-s-listbox.aspx

期望的效果如下:

这是我的XAML中的示例设置:

<ScrollViewer x:Name="MyScrollViewer">
    <ListView x:Name="MyView" VerticalAlignment="Center"
                      SelectionChanged="Selector_OnSelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Width="80" Height="80" Margin="0">
                    <TextBlock Text="{Binding}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.Items>
            <x:String>1</x:String>
            <x:String>2</x:String>
            <x:String>3</x:String>
            <x:String>4</x:String>
            <x:String>5</x:String>
            <x:String>6</x:String>
            <x:String>7</x:String>
            <x:String>8</x:String>
            <x:String>9</x:String>
        </ListView.Items>
    </ListView>
</ScrollViewer>

知道所选项目的索引,如何计算我可以在我的方法中使用的垂直偏移量:

private void Selector_OnSelectionChanged(object sender,SelectionChangedEventArgs e)
{
    double maxVerticalOffset = MyScrollViewer.ExtentHeight - MyScrollViewer.ViewportHeight;

    int selectedItemIndex = MyView.SelectedIndex;

    double verticalOffset = ...

    MyScrollViewer.ChangeView(null,verticalOffset,null);
}

解决方法

首先尝试 ListView.ScrollIntoView()ListView.MakeVisible将项目的容器滚动到视图中并解决它可能从UI虚拟化.然后用
ListView.ItemContainerGenerator. ContainerFromIndex()获取项目的容器,然后获取VisualTreeHelper以获取其相对于ScrollViewer的位置.然后按计算的偏移滚动滚动查看器.

*编辑 – 示例定位逻辑:

从WinRT XAML Toolkit获取VisualTreeHelperExtensions,使用GetFirstDescendantOfType()扩展方法轻松访问ScrollViewer,该方法包含对VisualTreeHelper的一些调用.

XAML

<Page
    x:Class="ListViewItemCentering.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ListViewItemCentering"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView
            x:Name="listView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border
                        Width="400"
                        Height="100">
                        <ContentControl
                            Content="{Binding}"
                            FontSize="48"
                            Padding="20,10"/>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button
            Content="Skip"
            Width="200"
            Height="100"
            HorizontalAlignment="Right"
            VerticalAlignment="Bottom"
            Click="ButtonBase_OnClick"/>
    </Grid>
</Page>

C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using WinRTXamlToolkit.Controls.Extensions;

namespace ListViewItemCentering
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Random random = new Random();
        public MainPage()
        {
            this.InitializeComponent();
            this.listView.ItemsSource = Enumerable.Range(1,1000);
            this.listView.SelectionChanged += OnListViewSelectionChanged;
        }

        private async void OnListViewSelectionChanged(object sender,SelectionChangedEventArgs selectionChangedEventArgs)
        {
            if (listView.SelectedItem == null)
            {
                return;
            }

            var item = listView.SelectedItem;

            // Calculations relative to screen or ListView
            var listViewItem = (FrameworkElement)listView.ContainerFromItem(item);

            if (listViewItem == null)
            {
                listView.ScrollIntoView(item);
            }

            while (listViewItem == null)
            {
                await Task.Delay(1); // wait for scrolling to complete - it takes a moment
                listViewItem = (FrameworkElement)listView.ContainerFromItem(item);
            }

            var topLeft =
                listViewItem
                    .TransformToVisual(listView)
                    .TransformPoint(new Point()).Y;
            var lvih = listViewItem.ActualHeight;
            var lvh = listView.ActualHeight;
            var desiredTopLeft = (lvh - lvih) / 2.0;
            var desiredDelta = topLeft - desiredTopLeft;

            // Calculations relative to the ScrollViewer within the ListView
            var scrollViewer = listView.GetFirstDescendantOfType<ScrollViewer>();
            var currentOffset = scrollViewer.VerticalOffset;
            var desiredOffset = currentOffset + desiredDelta;
            scrollViewer.ScrollToVerticalOffset(desiredOffset);

            // better yet if building for Windows 8.1 to make the scrolling smoother use:
            // scrollViewer.ChangeView(null,desiredOffset,null);
        }

        private async void ButtonBase_OnClick(object sender,RoutedEventArgs e)
        {
            this.listView.SelectedIndex = random.Next(0,((IEnumerable<int>)this.listView.ItemsSource).Count());
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读