I have put together a simple WPF application to demonstrate the issue I am having. My XAML is below:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="427" Width="467" Loaded="MainWindow_OnLoaded"> <Grid> <ScrollViewer Name="MyScrollViewer" CanContentScroll="True"> <Image Name="MyImage" HorizontalAlignment="Left" VerticalAlignment="Top" MouseWheel="UIElement_OnMouseWheel" MouseDown="MyImage_OnMouseDown" MouseUp="MyImage_OnMouseUp"/> </ScrollViewer> </Grid> </Window>
The code-behind is below:
using System; using System.Windows; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; namespace WpfApplication1 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void UIElement_OnMouseWheel(object sender, MouseWheelEventArgs e) { var matrix = MyImage.RenderTransform.Value; if (e.Delta > 0) { matrix.ScaleAt(1.5, 1.5, e.GetPosition(this).X, e.GetPosition(this).Y); } else { matrix.ScaleAt(1.0 / 1.5, 1.0 / 1.5, e.GetPosition(this).X, e.GetPosition(this).Y); } MyImage.RenderTransform = new MatrixTransform(matrix); } private WriteableBitmap writeableBitmap; private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { var image = new WriteableBitmap(new BitmapImage(new Uri(@"C:\myImage.png", UriKind.Absolute))); MyImage.Width = image.Width; MyImage.Height = image.Height; image = BitmapFactory.ConvertToPbgra32Format(image); writeableBitmap = image; MyImage.Source = image; } private Point downPoint; private Point upPoint; private void MyImage_OnMouseDown(object sender, MouseButtonEventArgs e) { downPoint = e.GetPosition(MyImage); } private void MyImage_OnMouseUp(object sender, MouseButtonEventArgs e) { upPoint = e.GetPosition(MyImage); writeableBitmap.DrawRectangle(Convert.ToInt32(downPoint.X), Convert.ToInt32(downPoint.Y), Convert.ToInt32(upPoint.X), Convert.ToInt32(upPoint.Y), Colors.Red); MyImage.Source = writeableBitmap; } } }
I have added WriteableBitmapEx using Nuget. If you run this, and replace myImage.png with the location of an actual image on your computer, you will find an application that looks something like this:
You can draw a box on the image by clicking on the top-left of where you want the box to go and dragging to the bottom right of where you want the box to go, you get a red rectangle. You can even zoom in with the middle-mouse, and draw a rectangle up close for more precision, this works as expected.
The problem is that, when you scroll in with the middle mouse, the scroll bars don't re-adjust, which is a requirement of the program I am creating. My question is how do I force the scrollbars on the scrollviewer to re-adjust when the image is zoomed in?
I am convinced it has something to do with the RenderTransform property of the ScrollViewer, and that I need to update it at the same time I update the RenderTransform property of the image (on UIElement_OnMouseWheel) but I am unsure of exactly how to go about this.
You should be using LayoutTransform
instead of RenderTransform
on your Image.
RenderTransform
happens after layout completes and is visual only. LayoutTransform
is done before the layout pass and so can notify the ScrollViewer
of the new size.
See here for more info: http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.layouttransform.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With