我有一个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>