【问题标题】:WPF ScrollViewer and PanningWPF ScrollViewer 和平移
【发布时间】:2019-06-04 08:52:41
【问题描述】:

我有一个Window 和一个ScrollViewer,在ScrollViewer 里面有一个Rectangle。现在我添加了代码来拖动Rectangle,它工作正常。但是当Rectangle 移出视图时,我不知道如何显示Scrollbars。我以为这会自动发生,但事实并非如此?

这是我的 XAML:

<Window x:Class="WpfApp4.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:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <ScrollViewer Name="_scrollViewer" CanContentScroll="True" 
                  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
        <Rectangle Name="_myRect" Width="100" Height="100" Fill="Blue"/>
    </ScrollViewer>
</Window>

以及背后的代码:

public partial class MainWindow : Window
{
    private Point _origin;
    private Point _start;
    private ScaleTransform _scaleTransform = new ScaleTransform();
    private TranslateTransform _translateTransform = new TranslateTransform();

    public MainWindow()
    {
        InitializeComponent();

        var group = new TransformGroup();
        group.Children.Add(_scaleTransform);
        group.Children.Add(_translateTransform);  
        _myRect.RenderTransform = group;

        // Hook up events
        _myRect.MouseLeftButtonDown += _myRect_MouseLeftButtonDown;
        _myRect.MouseLeftButtonUp += _myRect_MouseLeftButtonUp;
        _myRect.MouseMove += _myRect_MouseMove;
    }

    private void _myRect_MouseMove(object sender, MouseEventArgs e)
    {
        if (_myRect.IsMouseCaptured)
        {
            Vector v = _start - e.GetPosition(this);
            _translateTransform.X = _origin.X - v.X;
            _translateTransform.Y = _origin.Y - v.Y;
        }
    }

    private void _myRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        _myRect.ReleaseMouseCapture();
        this.Cursor = Cursors.Arrow;
    }

    private void _myRect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _start = e.GetPosition(this);
        _origin = new Point(_translateTransform.X, _translateTransform.Y);
        Cursor = Cursors.Hand;
        _myRect.CaptureMouse();
    }
}

[更新]: 因此,根据我得到的输入,我将 XAML 和后面的代码更改为以下内容 - 但仍然没有滚动条?

<Window x:Class="WpfApp4.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:WpfApp4"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <ScrollViewer Name="_scrollViewer" CanContentScroll="True" 
                  HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
        <Canvas Name="_myCanvas">
            <Rectangle Name="_myRect" Width="100" Height="100" Fill="Blue" Canvas.Left="305" Canvas.Top="129"/>
        </Canvas>
    </ScrollViewer>
</Window>

代码背后:

public partial class MainWindow : Window
{
    private Point _start;

    public MainWindow()
    {
        InitializeComponent();
        // Hook up events
        _myRect.MouseLeftButtonDown += _myRect_MouseLeftButtonDown;
        _myRect.MouseLeftButtonUp += _myRect_MouseLeftButtonUp;
        _myRect.MouseMove += _myRect_MouseMove;
    }

    private void _myRect_MouseMove(object sender, MouseEventArgs e)
    {
        if (_myRect.IsMouseCaptured)
        {
            var canvasRelativePosition = e.GetPosition(_myCanvas);
            Debug.WriteLine($"New Position: {canvasRelativePosition}");
            Canvas.SetTop(_myRect, canvasRelativePosition.Y - _start.Y);
            Canvas.SetLeft(_myRect, canvasRelativePosition.X - _start.X);
        }
    }

    private void _myRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        _myRect.ReleaseMouseCapture();
        this.Cursor = Cursors.Arrow;
    }

    private void _myRect_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _start = e.GetPosition(_myRect);
        Debug.WriteLine($"Start Position: {_start}");
        Cursor = Cursors.Hand;
        _myRect.CaptureMouse();
    }
}

【问题讨论】:

  • 将 Canvas 放入 ScrollViewer 并将 Rectangle 添加到 Canvas。然后通过设置 Canvas.Left 和 Canvas.Top 属性来移动 Rectangle。通过设置它的宽度和高度来缩放它。
  • @Clemens:更新了我上面的代码,但仍然看不到滚动条
  • 您可能还想设置画布的宽度和高度。

标签: c# wpf wpf-controls


【解决方案1】:

如果你想让你的变换影响布局,你必须使用LayoutTransofrmRenderTransform 只改变外观。

与元素 LayoutTransform 关联的任何转换 财产将对后续的Measure and Arrange产生影响 脚步。而 RenderTransform 不会对 布局过程,只会影响渲染。

阅读更多here

但是,LayoutTransform 会忽略 TranslateTransform

LayoutTransform 忽略 TranslateTransform 操作。这是因为 FrameworkElement 的子元素的布局系统行为 自动更正任何偏移到缩放或旋转的位置 元素加入到父元素的布局和坐标系中。

阅读更多here

也就是说,要实现元素的移动,你不能使用Transforms。您可以尝试手动更改元素的位置(MarginCanvas.Left/Right 或其他想法)。

【讨论】:

  • 首先感谢您的回答。你能给我举个例子,你所说的“手动改变元素的位置”是什么意思?
  • 您可以像这里一样使用画布:stackoverflow.com/questions/1123101/… 在这种情况下,您还必须记住更改画布大小,当矩形即将被移出边界时。
  • 有 2 个问题需要处理。 1. 首先是移动您的对象 - 我们管理它。 2. 第二个是画布的大小。即使移动矩形,画布大小仍然相同。滚动外观取决于画布大小(在这种情况下)。您可以通过编程方式更改它或使用 Grid 查看此解决方案:stackoverflow.com/questions/855334/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多