gpt4 book ai didi

c# - 在滚动查看器中将所选项目居中

转载 作者:太空狗 更新时间:2023-10-30 00:24:41 25 4
gpt4 key购买 nike

我试图将 ScrollViewer 内的 ListView 中的选定项目居中,并努力计算我应该设置 ScrollViewer 相对于 ListView 的垂直偏移量。

以下链接使我走上正轨,但由于 WinRT API 的限制,无法使用它们:

想要的效果如下:

centered selected item in scrollviewer

这是我的 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首先将项目的容器滚动到 View 中,并解决它可能被虚拟化到 UI 之外的问题。然后使用 ListView.ItemContainerGenerator ContainerFromIndex()获取项目的容器,然后 VisualTreeHelper 获取其相对于 ScrollViewer 的位置。然后按计算出的偏移量滚动滚动查看器。

*编辑 - 示例定位逻辑:

获取VisualTreeHelperExtensions从 WinRT XAML 工具包中使用 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());
}
}
}

关于c# - 在滚动查看器中将所选项目居中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22595675/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com