c# – 当ViewingMode设置为滚动时调整FlowDocumentReader的滚动增量?

前端之家收集整理的这篇文章主要介绍了c# – 当ViewingMode设置为滚动时调整FlowDocumentReader的滚动增量?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在FlowDocumentReader中使用ViewingMode =“Scroll”显示FlowDocument.如果我在鼠标上使用滚轮,则文档滚动速度非常慢.我想增加滚动步骤.

>我试图在控制面板中更改鼠标的滚动设置,但这没有任何效果.我认为WPF忽略了FlowDocumentScrollViewer的设置.
>我在FlowDocument和FlowDocumentReader上添加了一个Scroll事件,但是当我使用鼠标滚轮时,它不会触发.
>我在FlowDocumentReader上添加了一个Loaded事件,得到了ScrollViewer后代,
从滚动查看器的模板中找到了ScrollBar(“PART_VerticalScrollBar”)并调整了SmallChange& LargeChange属性.这也没有任何影响.

有人有主意吗?

解决方法

我们可以在Control的MouseWheel事件中修改它,比如Sohnee sugested,但是它只是针对一个特定的情况解决了,你必须能够访问FlowDocumentReader,如果你使用类似MVVM的东西,你就不会.相反,我们可以创建一个附加属性,然后我们可以使用ScrollViewer在任何元素上设置它.在定义附加属性时,我们还需要一个PropertyChanged回调函数,我们将对滚动速度执行实际修改.我还给了我的属性一个默认值1,我将要使用的速度范围是.1x到3x,尽管你可以轻松地做1-10之类的事情.
public static double GetScrollSpeed(DependencyObject obj)
{
    return (double)obj.GetValue(ScrollSpeedProperty);
}

public static void SetScrollSpeed(DependencyObject obj,double value)
{
    obj.SetValue(ScrollSpeedProperty,value);
}

public static readonly DependencyProperty ScrollSpeedProperty =
    DependencyProperty.RegisterAttached(
    "ScrollSpeed",typeof(double),typeof(ScrollHelper),new FrameworkPropertyMetadata(
        1.0,FrameworkPropertyMetadataOptions.Inherits & FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,new PropertyChangedCallback(OnScrollSpeedChanged)));

private static void OnScrollSpeedChanged(DependencyObject o,DependencyPropertyChangedEventArgs e)
{
}

现在我们有了附加属性,我们需要处理滚动,为此,在OnScrollSpeedChanged中我们可以处理PreviewMouseWheel事件.我们想要挂钩到PreviewMouseWheel,因为它是在ScrollViewer可以处理标准MouseWheel事件之前发生的隧道事件.

目前,PreviewMouseWheel处理程序正在接收FlowDocumentReader或我们绑定它的其他东西,但我们需要的是ScrollViewer.因为它可能是很多东西:ListBox,FlowDocumentReader,WPF Toolkit Grid,ScrollViewer等,我们可以创建一个使用VisualTreeHelper执行此操作的简短方法.我们已经知道通过的项目将是某种形式的DependancyObject,因此我们可以使用一些递归来查找ScrollViewer(如果存在).

public static DependencyObject GetScrollViewer(DependencyObject o)
{
    // Return the DependencyObject if it is a ScrollViewer
    if (o is ScrollViewer)
    { return o; }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
    {
        var child = VisualTreeHelper.GetChild(o,i);

        var result = GetScrollViewer(child);
        if (result == null)
        {
            continue;
        }
        else
        {
            return result;
        }
    }

    return null;
}

private static void OnScrollSpeedChanged(DependencyObject o,DependencyPropertyChangedEventArgs e)
{
    var host = o as UIElement;
    host.PreviewMouseWheel += new MouseWheelEventHandler(OnPreviewMouseWheelScrolled);
}

现在我们可以获得ScrollViwer,我们最终可以修改滚动速度.我们需要从正在发送的DependancyObject中获取ScrollSpeed属性.此外,我们可以使用我们的辅助方法获取元素中包含的ScrollViewer.一旦我们有了这两件事,我们就可以获得并修改ScrollViewer的VerticalOffset.我发现将MouseWheelEventArgs.Delta(鼠标滚轮改变的数量)除以6得到大约默认的滚动速度.因此,如果我们将它乘以ScrollSpeed修改器,我们就可以得到新的偏移值.然后我们可以使用它公开的ScrollToVerticalOffset方法设置ScrollViewer的VerticalOffset.

private static void OnPreviewMouseWheelScrolled(object sender,MouseWheelEventArgs e)
{
    DependencyObject scrollHost = sender as DependencyObject;

    double scrollSpeed = (double)(scrollHost).GetValue(Demo.ScrollSpeedProperty);

    ScrollViewer scrollViewer = GetScrollViewer(scrollHost) as ScrollViewer;

    if (scrollViewer != null)
    {
        double offset = scrollViewer.VerticalOffset - (e.Delta * scrollSpeed / 6);
        if (offset < 0)
        {
            scrollViewer.ScrollToVerticalOffset(0);
        }
        else if (offset > scrollViewer.ExtentHeight)
        {
            scrollViewer.ScrollToVerticalOffset(scrollViewer.ExtentHeight);
        }
        else
        {
            scrollViewer.ScrollToVerticalOffset(offset);
        }

        e.Handled = true;
    }
    else
    {
        throw new NotSupportedException("ScrollSpeed Attached Property is not attached to an element containing a ScrollViewer.");
    }
}

现在我们已经设置了Attached Property,我们可以创建一个简单的UI来演示它.我将创建一个ListBox和一个FlowDocumentReaders,以便我们可以看到ScrollSpeed如何在多个控件中受到影响.

<UniformGrid Columns="2">
    <DockPanel>
        <Slider DockPanel.Dock="Top"
            Minimum=".1"
            Maximum="3"
            SmallChange=".1"
            Value="{Binding ElementName=uiListBox,Path=(ScrollHelper:Demo.ScrollSpeed)}" />
        <ListBox x:Name="uiListBox">
            <!-- Items -->
        </ListBox>
    </DockPanel>
    <DockPanel>
        <Slider DockPanel.Dock="Top"
            Minimum=".1"
            Maximum="3"
            SmallChange=".1"
            Value="{Binding ElementName=uiListBox,Path=(ScrollHelper:Demo.ScrollSpeed)}" />
        <FlowDocumentReader x:Name="uiReader"
            ViewingMode="Scroll">
            <!-- Flow Document Content -->
        </FlowDocumentReader>
    </DockPanel>
</UniformGrid>

现在,在运行时,我们可以使用滑块修改每个列中的滚动速度,有趣的东西.

猜你在找的C#相关文章