Louis S. Berman
Louis S. Berman

Reputation: 994

WPF Image Panning Constraints

I'm trying to figure out how to constrain a pan so that the image remains entirely within the bounds of it's containing border. Any help this regard would be greatly appreciated. Thanks....

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="MapTest.Window1"
    Title="PanTest"
    Width="484"
    Height="400"
    WindowStartupLocation="CenterScreen">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBlock Margin="8,8,8,0"
               TextWrapping="Wrap">
        To pan the image, simply click on it then drag.  I'd like to 
        constrain the pan so that the image remains entirely within 
        the border, but without resorting to ClipToBounds.  Any help 
        in this regard would be greatly appreciated.  Thanks....</TextBlock>
    <Border x:Name="border"
            Margin="8"
            BorderBrush="Black"
            BorderThickness="1"
            Grid.Row="1">
        <Image x:Name="image"
               Source="Penguins.jpg"
               Opacity="1"
               Width="300"
               Height="300"
               Stretch="Uniform"
               RenderTransformOrigin="0.5,0.5" />
    </Border>
</Grid>

using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace MapTest
{
    public partial class Window1 : Window
    {
        private Point origin;
        private Point start;

        public Window1()
        {
            InitializeComponent();

            var group = new TransformGroup();

            group.Children.Add(new TranslateTransform());

            image.RenderTransform = group;

            image.MouseLeftButtonDown += image_MouseLeftButtonDown;
            image.MouseMove += image_MouseMove;
            image.MouseLeftButtonUp += image_MouseLeftButtonUp;
        }

        private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            image.ReleaseMouseCapture();
        }

        private void image_MouseMove(object sender, MouseEventArgs e)
        {
            if (!image.IsMouseCaptured) 
                return;

            var tt = (TranslateTransform)((TransformGroup)image.RenderTransform).
                Children.First(tr => tr is TranslateTransform);

            var vector = start - e.GetPosition(border);

            tt.X = origin.X - vector.X;
            tt.Y = origin.Y - vector.Y;
        }

        private void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            image.CaptureMouse();

            var tt = (TranslateTransform)((TransformGroup)image.RenderTransform).
                Children.First(tr => tr is TranslateTransform);

            start = e.GetPosition(border);

            origin = new Point(tt.X, tt.Y);
        }
    }
}

Upvotes: 2

Views: 1171

Answers (1)

Clemens
Clemens

Reputation: 128077

The following code gives you the bounds of the transformed Image control in coordinates relative to the Border control. You could easily check if the bounds are located inside the Border control.

var rect = new Rect(image.RenderSize);
var bounds = image.TransformToAncestor(border).TransformBounds(rect);

Upvotes: 3

Related Questions