如何获取 ScrollViewer 的 VerticalOffset 与开发无关的像素,用于 CanContentScroll true 的 ItemsControl



我有一个CanContentScroll为true的列表框,但其他列表框为false。

我正在编写一个行为,需要从中提取滚动查看器,并以设备无关的像素计算垂直滚动偏移。

由于CanContentScroll可以是true或false,我有时会得到逻辑项单位,而其他时候则是物理像素。

所以我需要计算像素值,以防CanContentScroll为真。

举个例子:当列表框滚动三项时,VerticalOffset将给出3。如何将此3转换为项目使用的垂直像素(大小可能不同)?

感谢

如果不有效地设置CanContentScroll="False",就无法计算像素值。

要知道像素大小,您需要创建所有项目的容器,并汇总所有容器的高度。要做到这一点,您需要首先生成所有容器。这意味着您实际上失去了虚拟化,有效地将CanContentScroll设置为"False"。在这种情况下,为什么首先使用CanContentScroll="True"?

Nikolay的代码试图做的是承担CanContentScroll="False"所做的事情,而不给你原本可以获得的平滑滚动。

更重要的是,如果您知道CanContentScroll="true"总是,那么物理偏移量解决了什么问题,而逻辑偏移量无法解决这些问题?

您可以将滚动项目的大小相加,如下所示:

private void Button_Click(object sender, RoutedEventArgs e)
{
  var scroller = GetScrollViewer();
  var listBox = GetListBox();
  double trueOffset;
  if (scroller.CanContentScroll)
  for (int i = 0; i < (int)scroller.VerticalOffset; i++)
  {
      var listBoxItem = (FrameworkElement)listBox.ItemContainerGenerator.ContainerFromIndex(i);
      trueOffset += listBoxItem.ActualHeight;        
  }
  else
      trueOffset = scroller.VerticalOffset;        
  this.Title = trueOffset.ToString();
}

这个简单的代码适用于具有可变大小项目的列表框

我会尝试不同的方法。

使用Scrollviewer嵌入您的列表框,并禁用列表框本身的滚动行为。

您可以测量列表框外的滚动查看器VerticalOffset。

<TextBlock Grid.Row="0" 
           Text="{Binding ElementName=scrollviewer, Path=VerticalOffset}"/>
<ScrollViewer x:Name="scrollviewer" VerticalScrollBarVisibility="Auto" Grid.Row="1">
    <ListBox ScrollViewer.CanContentScroll="False">
        <ListBox.Items>
            <ListBoxItem>A</ListBoxItem>
            <ListBoxItem>B</ListBoxItem>
            <ListBoxItem>C</ListBoxItem>

相关内容

最新更新