创建一个允许缩放和平移的WPF窗口

12
我想创建一个窗口,用于容纳多个控件。但我希望用户能够平移、缩放以便查看这些控件的更大版本。
我不知道从哪里开始寻找。
我本来可以从 ScaleTransform 开始,响应鼠标滚轮的使用,但我不确定这是否是最好的想法。
只需要指导一下方向。
谢谢!
3个回答

14

这可能是使用 Viewbox 的一个好选择。

请参见这里:http://msdn.microsoft.com/en-us/library/system.windows.controls.viewbox(v=vs.110).aspx

基本上,您可以像这样将窗口的所有内容包装到一个 Viewbox 中:

<Window>
   <Viewbox>
       <!-- content here -->
   </Viewbox>
</Window>

然后将Viewbox控件的宽度和高度绑定起来以模拟缩放。对于快速测试,您可以通过代码后台监听滚轮事件,为Viewbox控件命名,并直接访问Viewbox以更改其中的值。

编辑:这里有一个场景可供参考。他们正在使用一张图片,但它与我上面描述的概念完全相同。

http://www.c-sharpcorner.com/uploadfile/yougerthen/working-with-wpf-viewbox-control/

编辑2:使用鼠标滚轮的快速工作示例

Xaml:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        MouseWheel="MainWindow_OnMouseWheel">
    <Grid>
        <Viewbox x:Name="ZoomViewbox" Stretch="Fill">
            <StackPanel>
                <Label Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top"/>
                <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" />
            </StackPanel>
        </Viewbox>
    </Grid>
</Window>

C#:

using System.Windows;
using System.Windows.Input;

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ZoomViewbox.Width = 100;
            ZoomViewbox.Height = 100;
        }

        private void MainWindow_OnMouseWheel(object sender, MouseWheelEventArgs e)
        {
            UpdateViewBox((e.Delta > 0) ? 5 : -5);
        }

        private void UpdateViewBox(int newValue)
        {
            if ((ZoomViewbox.Width >= 0) && ZoomViewbox.Height >= 0)
            {
                ZoomViewbox.Width += newValue;
                ZoomViewbox.Height += newValue;   
            }
        }
    }
}

谢谢!这个视图框是否响应中间鼠标按钮事件,还是我需要自己构建? - hendersondayton
这是你必须要构建的功能。您将为整个窗口设置这些事件(而不是视图框),然后当这些事件发生时,您会修改视图框属性。您说的是仅鼠标滚动事件吗? - d.moncada
谢谢!我不确定如何接受多个答案。 - hendersondayton
1
这对于缩放效果非常好。我如何将其中的“平移”部分绑定起来呢?使用滚轮的单击和按住功能在窗口中拖动? - hendersondayton
这并没有解释如何进行平移操作。没有平移,缩放就没什么用了。 - FinnTheHuman

13

你可以通过使用ScrollViewer和ScaleTransform来获得功能性。这里是一个例子:

<Window x:Class="CSharpWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <!-- This ScrollViewer enables the panning -->
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">

            <!-- This StackPanel is the container for the zoomable/pannable content. -->
            <!-- Any container control (StackPanel, DockPanel, Grid, etc) may be used here. -->
            <StackPanel HorizontalAlignment="Left" VerticalAlignment="Top">

                <!-- This ScaleTransform implements the zooming and is bound the Value of the ZoomSlider -->
                <StackPanel.LayoutTransform>
                    <ScaleTransform ScaleX="{Binding ElementName=ZoomSlider, Path=Value}" ScaleY="{Binding ElementName=ZoomSlider, Path=Value}" />
                </StackPanel.LayoutTransform>

                <!-- Here is your custom content -->
                <Button>Foo</Button>
                <Button>Bar</Button>

            </StackPanel>

        </ScrollViewer>

        <!-- This Slider controls the zoom level -->
        <Slider x:Name="ZoomSlider" Orientation="Horizontal" Grid.Row="1" Minimum="0.0" Maximum="8.0" LargeChange="0.25" SmallChange="0.01"  Value="1.0" />

    </Grid>


</Window>

这是我找到的最好的没有代码后台的答案。非常优雅的解决方案。谢谢分享。 - omostan

0

简单的解决方案:

    private void Window_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (Keyboard.Modifiers != ModifierKeys.Control)
            return;

        if (e.Delta < 0 && _scale > 0.7)
        {
            _scale -= 0.1;
            MainGrid.LayoutTransform = new ScaleTransform(_scale, _scale);
        }               
        else if (e.Delta > 0 && _scale < 1.5)
        {
            _scale += 0.1;
            MainGrid.LayoutTransform = new ScaleTransform(_scale, _scale);
        }
            
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接