WPF - 调用 ScrollToHorizo​​ntalOffset() 时 ScrollViewer 将不会滚动

发布于 2024-07-30 14:17:46 字数 4038 浏览 10 评论 0原文

我在 TabControl 内有一个 Scrollviewer,由于某种原因,当您更改选项卡时,我的 ScrollViewer 会跳转到 Horizo​​ntalOffset 12。除其他外,我的 ScrollViewer 内部有一个高度不受限制的 ListView。 这是一个奇怪的布局,但滚动条内的所有内容都必须是可打印的,所以我不能轻易地让 ListView 自行滚动。

因此,我在 TabControl 的 SelectionChanged 事件中尝试了以下几行:

Console.WriteLine(Scroller.HorizontalOffset);
Scroller.ScrollToHorizontalOffset(0);
Console.WriteLine(Scroller.HorizontalOffset);

对于对 WriteLine() 的两次调用,它们都打印出 12...它也不会移动,但您可以从实际 UI 滚动。

有谁知道什么会导致这种奇怪的行为?

我将尝试找到合适的代码来发布,但这是一个大型项目,可能很难在示例解决方案中重新创建。

其他信息:

  • 仅当内容足够大且可以水平滚动时才会出现此问题。
  • 我的水平和垂直滚动条可见性是“自动”,但如果将它们设置为“隐藏”或“可见”,问题仍然会发生。

更新:

如果您单击 ScrollViewer 内的 ListView 并选择一个项目,ScrollViewer 会滚动到相同的 12 像素偏移。 我的问题可能与我的 ListView 获得焦点有关吗? 当 ListView 获得焦点时,它会调用 BringIntoView() 吗?

此 Xaml 重现了该问题:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window11" Height="300" Width="300">
<TabControl>
    <TabItem Header="Tab One">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ListBox Margin="25,0,0,0" Width="2000">
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>          
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            </ListBox>
        </ScrollViewer>
    </TabItem>
    <TabItem Header="Tab Two">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ListBox Margin="25,0,0,0" Width="2000">
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>          
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            </ListBox>
        </ScrollViewer>
    </TabItem>
</TabControl>
</Window>

将其放入 XamlPad 中,运行它。 单击选项卡标题并注意 ScrollViewer 自行滚动,尝试一下并注意 ListBox 上的边距如何滚动到屏幕外。 如何防止或解决此行为? 在我的例子中,它使我的布局看起来相当简陋。

I have a Scrollviewer inside a TabControl, and for some reason when you change tabs my ScrollViewer jumps to HorizontalOffset of 12. My ScrollViewer, among other things has a ListView inside it with an unrestricted height. It's a strange layout, but everything inside the scroller had to be printable so I couldn't easily allow the ListView to scroll on its own.

So I tried the following lines in the SelectionChanged event of the TabControl:

Console.WriteLine(Scroller.HorizontalOffset);
Scroller.ScrollToHorizontalOffset(0);
Console.WriteLine(Scroller.HorizontalOffset);

And they print out 12 for both calls to WriteLine()... It also does not move, but you can scroll from the actual UI.

Does anyone know what would cause this strange behavior?

I will try to find suitable code to post, but it's a large project and might be difficult to recreate in a sample solution.

Other info:

  • The issue only happens if the content is large enough where it can horizontally scroll.
  • My horizontal and vertical scrollbar visibility is Auto, but the issue still happens if they are set to Hidden or Visible.

UPDATE:

If you click my ListView that's inside the ScrollViewer and select an item, the ScrollViewer scrolls to this same 12 pixel offset. Could my issue be related to my ListView getting focus? Does a ListView call BringIntoView() on itself when it receives focus?

This Xaml reproduces the issue:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window11" Height="300" Width="300">
<TabControl>
    <TabItem Header="Tab One">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ListBox Margin="25,0,0,0" Width="2000">
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>          
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            </ListBox>
        </ScrollViewer>
    </TabItem>
    <TabItem Header="Tab Two">
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ListBox Margin="25,0,0,0" Width="2000">
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>          
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            <ListBoxItem>WOOT WOOT WOOT WOOT</ListBoxItem>
            </ListBox>
        </ScrollViewer>
    </TabItem>
</TabControl>
</Window>

Slap this in XamlPad, run it. Click a Tab header and notice the ScrollViewer scroll on its own, play around with it and notice how my margin on the ListBox is scrolled off screen. How do I prevent or workaround this behavior? It makes my layout look pretty janky in my case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不在是我 2024-08-06 14:17:46

看起来您必须连接到 RequestBringIntoView:

private void ListView_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
    e.Handled = true;
}

似乎是一个非常简单的解决方案。

Looks like you have to hook into RequestBringIntoView:

private void ListView_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
    e.Handled = true;
}

Seems like a pretty simple solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文