wpf ScrollToVerticalOffset() 不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17872345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:17:10  来源:igfitidea点击:

ScrollToVerticalOffset() doesn't work?

c#wpf

提问by TTGroup

I'm using ScrollView in WPF, and my app allow user click on a button and then it will auto scroll the scrollview, I use ScrollToVerticalOffset() in button click event, but the scrollview not changed anything.

我在 WPF 中使用 ScrollView,我的应用程序允许用户单击按钮,然后它会自动滚动滚动视图,我在按钮单击事件中使用 ScrollToVerticalOffset(),但滚动视图没有改变任何内容。

I searched about this issue on internet, but so far I can't not solve it yet.

我在互联网上搜索了这个问题,但到目前为止我还没有解决它。

And one more question: ScrollToVerticalOffset() take a double as parameter, it may will scroll to the special pixels, there any way to scroll to n items (not pixel)?

还有一个问题:ScrollToVerticalOffset() 以double 作为参数,它可能会滚动到特殊像素,有什么方法可以滚动到n 个项目(不是像素)?

Here is my code

这是我的代码

<ScrollViewer x:Name="scrollViewerChannelBtns" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" 
              Background="Transparent" VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden"
              CanContentScroll="True" ScrollChanged="ScrollViewerChannelBtns_ScrollChanged">
    <StackPanel x:Name="channelBtns" Orientation="Vertical">
        <ItemsControl x:Name="channelBtnItems" ItemsSource="{Binding}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <ToggleButton x:Name="tgbChannelName" Width="{Binding Path=ChannelNameBtnWidth}" Height="{Binding Path=ChannelNameBtnHeight}" HorizontalAlignment="Left" VerticalAlignment="Center" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=ChannelName}" Tag="{Binding Path=Index}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</ScrollViewer>  

C# Code

C# 代码

//The button click event handled
private void BtnScrollDownClicked(object sender, RoutedEventArgs e)
{                        scrollViewerChannelBtns.ScrollToVerticalOffset(scrollViewerChannelBtns.VerticalOffset + 50);
}
private void BtnScrollUpClicked(object sender, RoutedEventArgs e)
{                        scrollViewerChannelBtns.ScrollToVerticalOffset(scrollViewerChannelBtns.VerticalOffset - 50);
}

Many thanks, T&T

非常感谢,T&T

采纳答案by Anatoliy Nikolaev

For me, this example works:

对我来说,这个例子有效:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

<Grid>
    <ScrollViewer x:Name="scrollViewerChannelBtns" HorizontalAlignment="Center" Height="100" CanContentScroll="False" VerticalAlignment="Center" 
          Background="Transparent" VerticalScrollBarVisibility="Auto">

        <StackPanel x:Name="channelBtns" Orientation="Vertical">
            <ItemsControl x:Name="channelBtnItems">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <ToggleButton x:Name="tgbChannelName" Width="40" Height="20" HorizontalAlignment="Left" VerticalAlignment="Center" IsChecked="{x:Null}" Content="Test" />
                    </DataTemplate>
                </ItemsControl.ItemTemplate>

                <sys:String>Item 1</sys:String>
                <sys:String>Item 2</sys:String>
                <sys:String>Item 3</sys:String>
                <sys:String>Item 4</sys:String>
                <sys:String>Item 5</sys:String>
                <sys:String>Item 6</sys:String>
                <sys:String>Item 7</sys:String>
                <sys:String>Item 8</sys:String>
                <sys:String>Item 9</sys:String>
                <sys:String>Item 10</sys:String>
            </ItemsControl>
        </StackPanel>
    </ScrollViewer>

    <Button Name="Up" Width="50" Height="30" VerticalAlignment="Top" Margin="110,0,0,0" Content="Up" Click="Up_Click" />

    <Button Name="Down" Width="50" Height="30" VerticalAlignment="Top" Margin="210,0,0,0" Content="Down" Click="Down_Click" />
</Grid>

In the example I set the height for the ScrollViewerand CanContentScrollset false. Quote from answer why setting ScrollViewer.CanContentScroll to false disable virtualization:

在示例中,我设置了ScrollViewerCanContentScrollset的高度false。引自回答为什么将 ScrollViewer.CanContentScroll 设置为 false 禁用虚拟化

ScrollViewer currently allows two scrolling modes: smooth pixel-by-pixel scrolling (CanContentScroll = false) or discrete item-by-item scrolling (CanContentScroll = true). Currently WPF supports UI virtualization only when scrolling by item. Pixel-based scrolling is also called “physical scrolling” and item-based scrolling is also called “logical scrolling”.

Virtualization requires item-based scrolling so it can keep track of logical units (items) currently in view... Setting the ScrollViewer to pixel-based scrolling their is no more concept of logic units but only pixels!

ScrollViewer 目前允许两种滚动模式:平滑逐像素滚动(CanContentScroll = false)或离散逐项滚动(CanContentScroll = true)。目前 WPF 仅在按项目滚动时支持 UI 虚拟化。基于像素的滚动也称为“物理滚动”,基于项目的滚动也称为“逻辑滚动”。

虚拟化需要基于项目的滚动,因此它可以跟踪当前视图中的逻辑单元(项目)......将 ScrollViewer 设置为基于像素的滚动它们不再是逻辑单元的概念,而只是像素!

Code behind

Code behind

private void Up_Click(object sender, RoutedEventArgs e)
{
    scrollViewerChannelBtns.ScrollToVerticalOffset(scrollViewerChannelBtns.VerticalOffset - 50);
}

private void Down_Click(object sender, RoutedEventArgs e)
{
    scrollViewerChannelBtns.ScrollToVerticalOffset(scrollViewerChannelBtns.VerticalOffset + 50);
}

Scrolling elements not supported by default, so you have to look at these links:

默认情况下不支持滚动元素,因此您必须查看这些链接:

Consolidated Scrolling - "Pixel by Pixel" + "Item by Item"

合并滚动 - “逐像素”+“逐项”

ScrollViewer's Viewport Height VS Actual Height

ScrollViewer 的视口高度 VS 实际高度

回答by Teoman shipahi

Mine is started work after;

我的开始工作之后;

  ScrollViewer.UpdateLayout();                              
  ScrollViewer.ScrollToVerticalOffset(outPoint.Y);