Ich versuche WPF zu lernen, so ist hier eine einfache Frage, ich hoffe:Transforming-Koordinaten von einer Bildsteuerung auf der Bildquelle in WPF
ich ein Fenster haben, die ein Bildelement enthält auf einem separaten Daten gebunden Objekt mit vom Benutzer konfigurierbare Stretch
Eigenschaft
<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="{Binding ImageStretch}" />
wenn der Benutzer die Maus über das Bild bewegt, Ich mag würde die Koordinaten der Maus in Bezug auf die Originalbild (vor dem Recken/Zuschneiden bestimmen, die auftritt, wenn es wird in der Steuerung angezeigt) und dann etwas mit t tun Schlauchkoordinaten (Bild aktualisieren).
Ich weiß, dass ich einen Event-Handler an das Mousemove-Ereignis über die Bildsteuerung hinzuzufügen, aber ich bin nicht sicher, wie man am besten die Koordinaten zu transformieren:
void imageCtrl_MouseMove(object sender, MouseEventArgs e)
{
Point locationInControl = e.GetPosition(imageCtrl);
Point locationInImage = ???
updateImage(locationInImage);
}
Jetzt weiß ich, dass ich die Größe vergleichen könnte von Source
an die ActualSize
des Steuerelements, und schalten Sie dann imageCtrl.Stretch
ein, um die Skalare und Offsets für X und Y zu berechnen und die Transformation selbst vorzunehmen. Aber WPF hat alle Informationen bereits, und das scheint wie Funktionalität, die irgendwo in die WPF-Bibliotheken eingebaut werden könnte. Ich frage mich also: Gibt es eine kurze und süße Lösung? Oder muss ich das selbst schreiben?
EDIT ich meine aktuelle, nicht-so-Kurz und süße Lösung anhängen. Es ist nicht so schlecht, aber ich etwas überrascht sein würde, wenn WPF diese Funktionalität nicht automatisch vorsah:
Point ImgControlCoordsToPixelCoords(Point locInCtrl,
double imgCtrlActualWidth, double imgCtrlActualHeight)
{
if (ImageStretch == Stretch.None)
return locInCtrl;
Size renderSize = new Size(imgCtrlActualWidth, imgCtrlActualHeight);
Size sourceSize = bitmap.Size;
double xZoom = renderSize.Width/sourceSize.Width;
double yZoom = renderSize.Height/sourceSize.Height;
if (ImageStretch == Stretch.Fill)
return new Point(locInCtrl.X/xZoom, locInCtrl.Y/yZoom);
double zoom;
if (ImageStretch == Stretch.Uniform)
zoom = Math.Min(xZoom, yZoom);
else // (imageCtrl.Stretch == Stretch.UniformToFill)
zoom = Math.Max(xZoom, yZoom);
return new Point(locInCtrl.X/zoom, locInCtrl.Y/zoom);
}
Ich persönlich würde es wahrscheinlich genau so machen, wie Sie es in Ihrer "nicht so-kurz-und-süß" -Lösung haben. Ich bin nicht in eine eingebaute Bibliothek gelaufen, die das tun würde. –