WPF - Zoom avant sur une image à l'intérieur d'un visualiseur de défilement, et ajustement des barres de défilement en conséquence
J'ai mis en place une simple application WPF pour illustrer le problème que j'ai. Mon XAML est ci-dessous:
<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>
Le code-behind est ci-dessous:
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;
}
}
}
J'ai ajouté WriteableBitmapEx à l'aide de Nuget. Si vous exécutez ce code, et de le remplacer myImage.png avec l'emplacement d'une image réelle sur votre ordinateur, vous trouverez une application qui ressemble à quelque chose comme ceci:
Vous pouvez dessiner une zone sur l'image en cliquant sur en haut à gauche de l'endroit où vous souhaitez que la boîte à aller et en la faisant glisser vers le bas à droite de l'endroit où vous souhaitez que la boîte de à aller, vous obtenez un rectangle rouge. Vous pouvez même zoomer avec le milieu de la souris et dessinez un rectangle de près pour plus de précision, cela fonctionne comme prévu.
Le problème est que, lorsque vous faites défiler avec le bouton central de la souris, les barres de défilement ne pas re-régler, ce qui est une exigence du programme que je suis en train de créer. Ma question est comment puis-je forcer les barres de défilement sur le scrollviewer à re-régler lorsque l'image est agrandie?
Je suis convaincu qu'il a quelque chose à voir avec la propriété RenderTransform du ScrollViewer, et que j'ai besoin de le mettre à jour en même temps je mettre à jour la propriété RenderTransform de l'image (sur UIElement_OnMouseWheel) mais je suis pas sûr exactement comment aller à ce sujet.
source d'informationauteur JMK
Vous devez vous connecter pour publier un commentaire.
Vous devriez être en utilisant
LayoutTransform
au lieu deRenderTransform
sur votre Image.RenderTransform
qui se passe après la mise en page est terminée et que le visuel uniquement.LayoutTransform
est fait avant que la passe de mise en page et donc de l'informer duScrollViewer
de la nouvelle taille.Voir ici pour plus d'infos: http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.layouttransform.aspx
Pour pure de défilement, je préfère utiliser un ScaleTransform, il doit ajuster les barres de défilement en conséquence.
Vous pouvez essayer de code ci-dessous si cela résout votre problème.
Supposons que vous avez un Canvas_Main à l'intérieur d'un ViewBox_CanvasMain, qui à son tour à l'intérieur d'un ScrollViewer_CanvasMain. Vous voulez faire un zoom en tournant la molette de la souris, et le ScrollViewer permettra de régler l'offset automatiquement de sorte que la fonctionnalité (pointé par la souris dans le Canvas_Main) séjours pendant le zoom in/out. Il est complexe, mais voici le code appelé par la molette de la souris gestionnaire: