在FlowDocumentScrollViewer(WPF)中平移不起作用

yb3bgrhw  于 2023-02-10  发布在  其他
关注(0)|答案(1)|浏览(146)

我在FlowDocumentScrollViewer中有一个FlowDocument。我可以看到滚动条并使用它们滚动文本。要使用触摸手势启用平移,我设置了ScrollViewer.PanningMode="Both"。但只有当FlowDocument中有图像,并且我从图像开始触摸手势时,该设置才有效。换句话说,我可以通过按下、移动和释放来平移,但只有当我按下时,我的手指触摸到一个图像。如果我第一次按入文本,什么也不会发生(无法滚动)。
下面是XAML代码:

<Window x:Class="TestWPF.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TestWPF"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Grid>
    <FlowDocumentScrollViewer Height="350" IsSelectionEnabled="False" ScrollViewer.PanningMode="Both">
        <FlowDocument Background="Ivory" Foreground="Black" FontSize="20">
            <Section >
                <Paragraph>Paragraph 0</Paragraph>
                <Paragraph>Paragraph 1</Paragraph>
                <Paragraph>Paragraph 2</Paragraph>
                <Paragraph>Paragraph 3</Paragraph>
                <Paragraph>Paragraph 4</Paragraph>
                <Paragraph>Paragraph 5</Paragraph>
                <Paragraph>Paragraph 6</Paragraph>
                <Paragraph>Paragraph 7</Paragraph>
                <Paragraph>Paragraph 8</Paragraph>
                <Paragraph>Paragraph 9</Paragraph>
                <Paragraph>Paragraph 10</Paragraph>
                <Paragraph>Paragraph 11</Paragraph>
                <Paragraph>Paragraph 12</Paragraph>
                <Paragraph>Paragraph 13</Paragraph>
                <Paragraph>Paragraph 14</Paragraph>
                <Paragraph>Paragraph 15</Paragraph>
                <Paragraph>Paragraph 16</Paragraph>
                <Paragraph>Paragraph 17</Paragraph>
                <Paragraph>Paragraph 18</Paragraph>
                <Paragraph>Paragraph 19</Paragraph>
                <Paragraph>Paragraph 20</Paragraph>
                <Paragraph>Paragraph 21</Paragraph>
                <Paragraph>Paragraph 22</Paragraph>
                <Paragraph>Paragraph 23</Paragraph>
            </Section>
        </FlowDocument>
    </FlowDocumentScrollViewer>
</Grid>
</Window>

使用TextBlock并设置ScrollViewer。PanningMode工作正常,但我需要使用FlowDocumentScrollViewer。
你知道是什么问题吗?
谢谢

omqzjyyz

omqzjyyz1#

我认为段落抓取任何触摸事件。我没有任何触摸设备进行测试。但我无法在文档内使用鼠标滚动FlowDocumentScrollViewer。
一个可能的解决方案是处理预览事件,并根据移动的delta滚动相关的scrollviewer。
这里的处理程序同时处理鼠标和触摸。

bool IsScrolling = false; 
    Point LastPoint;
    private void FlowDocumentScrollViewer_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        HandleDown(sender);
    }

    private void HandleDown(object sender)
    {
        var sv = sender as FlowDocumentScrollViewer;
        if (sender != null)
        {
            IsScrolling = true;
            LastPoint = Mouse.GetPosition(sv);
        }
    }

    private void FlowDocumentScrollViewer_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        HandleMove(sender);
    }

    private void FlowDocumentScrollViewer_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        IsScrolling = false;
    }

    private void FlowDocumentScrollViewer_PreviewTouchDown(object sender, TouchEventArgs e)
    {
        HandleDown(sender);
    }

    private void FlowDocumentScrollViewer_PreviewTouchUp(object sender, TouchEventArgs e)
    {
        IsScrolling = false;
    }

    private void FlowDocumentScrollViewer_PreviewTouchMove(object sender, TouchEventArgs e)
    {
        HandleMove(sender);
    }

    private void HandleMove(object sender)
    {
        var fdsv = sender as FlowDocumentScrollViewer;
        if (fdsv == null || !IsScrolling)
        {
            return;
        }
        var ThisPoint = Mouse.GetPosition(fdsv);
        double dY = (ThisPoint.Y - LastPoint.Y);
        double dX = (ThisPoint.X - LastPoint.X);

        ScrollViewer sv = fdsv.GetChildOfType<ScrollViewer>();
        sv.ScrollToVerticalOffset(sv.VerticalOffset - dY);
        LastPoint = ThisPoint;
    }

在FlowDocumentScrollViewer上处理这些事件

<FlowDocumentScrollViewer Height="350" 
                              IsSelectionEnabled="False" 
                              ScrollViewer.PanningMode="Both"
                              PreviewMouseDown ="FlowDocumentScrollViewer_PreviewMouseDown"
                              PreviewTouchDown="FlowDocumentScrollViewer_PreviewTouchDown"
                              PreviewMouseUp="FlowDocumentScrollViewer_PreviewMouseUp"
                              PreviewTouchUp="FlowDocumentScrollViewer_PreviewTouchUp"
                              PreviewMouseMove="FlowDocumentScrollViewer_PreviewMouseMove"
                              PreviewTouchMove="FlowDocumentScrollViewer_PreviewTouchMove"
                              >

有了这些地方,我可以拖动和滚动鼠标。
获取子类型

public static class ExtensionMethods
{
    public static T GetChildOfType<T>(this DependencyObject depObj) where T : DependencyObject
    {
        if (depObj == null) return null;

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

            var result = (child as T) ?? GetChildOfType<T>(child);
            if (result != null) return result;
        }
        return null;
    }
}

相关问题