首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wpf ScrollViewer滚动量

Wpf ScrollViewer滚动量
EN

Stack Overflow用户
提问于 2009-10-29 03:21:21
回答 4查看 16.4K关注 0票数 20

是否可以更改WPF ScrollViewer滚动的数量?我只是想知道是否有可能更改滚动查看器,以便在使用鼠标滚轮或滚动查看器箭头时,可以更改增量滚动的数量。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-10-29 10:43:37

简短的答案是:如果不写一些自定义的滚动代码,就不可能做到这一点,但不要让它吓到你,这并不难。

ScrollViewer的工作方式是使用物理单位(即像素)滚动,或者使用IScrollInfo实现来使用逻辑单位。这由设置the CanContentScroll property控制,其中false值表示“使用物理单位滚动内容”,true值表示“逻辑滚动内容”。

那么ScrollViewer如何在逻辑上滚动内容呢?通过与IScrollInfo实现进行通信。因此,这就是当有人执行逻辑操作时,您可以准确控制面板滚动内容的方式。Take a look at the documentation for IScrollInfo获取可以请求滚动的所有测量逻辑单元的列表,但是由于您提到了鼠标滚轮,所以您最感兴趣的是MouseWheelUp/Down/Left/Right方法。

票数 16
EN

Stack Overflow用户

发布于 2017-03-06 16:41:31

您可以在滚动查看器上实现一个行为。在我的例子中,CanContentScroll不起作用。下面的解决方案适用于使用鼠标滚轮滚动和拖动滚动条。

代码语言:javascript
复制
public class StepSizeBehavior : Behavior<ScrollViewer>
{
    public int StepSize { get; set; }

    #region Attach & Detach
    protected override void OnAttached()
    {
        CheckHeightModulesStepSize();
        AssociatedObject.ScrollChanged += AssociatedObject_ScrollChanged;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        AssociatedObject.ScrollChanged -= AssociatedObject_ScrollChanged;
        base.OnDetaching();
    }
    #endregion

    [Conditional("DEBUG")]
    private void CheckHeightModulesStepSize()
    {
        var height = AssociatedObject.Height;
        var remainder = height%StepSize;
        if (remainder > 0)
        {
            throw new ArgumentException($"{nameof(StepSize)} should be set to a value by which the height van be divised without a remainder.");
        }
    }

    private void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        const double stepSize = 62;
        var scrollViewer = (ScrollViewer)sender;
        var steps = Math.Round(scrollViewer.VerticalOffset / stepSize, 0);
        var scrollPosition = steps * stepSize;
        if (scrollPosition >= scrollViewer.ScrollableHeight)
        {
            scrollViewer.ScrollToBottom();
            return;
        }
        scrollViewer.ScrollToVerticalOffset(scrollPosition);
    }
}

您可以这样使用它:

代码语言:javascript
复制
<ScrollViewer MaxHeight="248"
              VerticalScrollBarVisibility="Auto">
    <i:Interaction.Behaviors>
        <behaviors:StepSizeBehavior StepSize="62" />
    </i:Interaction.Behaviors>
票数 1
EN

Stack Overflow用户

发布于 2021-02-12 02:10:10

我想添加到Drew Marsh accepted -而其他建议答案解决了它,在某些情况下,你不能覆盖PreviewMouseWheel事件并在不引起其他副作用的情况下处理它。也就是说,如果您的子控件应该在父控件之前获得滚动的优先级,则类似ScrollViewer的嵌套ListBoxComboBox弹出窗口。

在我的场景中,我的父控件是一个ItemsControl,它的ItemsPanel是一个VirtualizingStackPanel。我希望它的逻辑滚动是每项1个单元,而不是默认的3个,而不是摆弄附加的行为和拦截/处理鼠标滚轮事件,我只是实现了一个自定义的VirtualizingStackPanel来做这件事。

代码语言:javascript
复制
    public class VirtualizingScrollSingleItemAtATimeStackPanel : VirtualizingStackPanel
    {
        public override void MouseWheelDown()
        {
            PageDown();
        }

        public override void MouseWheelUp()
        {
            PageUp();
        }

        public override void PageDown()
        {
            LineDown();
        }

        public override void PageUp()
        {
            LineUp();
        }
    }

然后,我们像通常在xaml标记中一样使用该面板:

代码语言:javascript
复制
<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <controls:VirtualizingScrollSingleItemAtATimeStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

显然,我的场景是人为设计的,解决方案也非常简单,然而,这可能会为其他人提供一条更好地控制滚动行为的途径,而不会产生我遇到的副作用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1639505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档