Estoy tratando de aprender WPF, así que aquí está una pregunta simple, espero:Transformar las coordenadas de un control de imagen a la fuente de imagen en WPF
tengo una ventana que contiene un elemento de imagen con destino a una de datos independiente objeto con configurable por el usuario Stretch
propiedad
<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="{Binding ImageStretch}" />
cuando el usuario mueve el ratón sobre la imagen, me gustaría para determinar las coordenadas del ratón con respecto a la imagen original (antes del estiramiento/recorte que se produce cuando se muestra en el control) y luego hacer algo con t coordenadas de la manguera (actualizar la imagen).
Sé que puedo agregar un controlador de eventos para el evento MouseMove sobre el Control de la imagen, pero no estoy seguro de cuál es la mejor para transformar las coordenadas:
void imageCtrl_MouseMove(object sender, MouseEventArgs e)
{
Point locationInControl = e.GetPosition(imageCtrl);
Point locationInImage = ???
updateImage(locationInImage);
}
Ahora sé que podría comparar el tamaño de Source
al ActualSize
del control, y luego encienda imageCtrl.Stretch
para calcular los escalares y las compensaciones en X e Y, y haga la transformación yo mismo. Pero WPF ya tiene toda la información, y esto parece una funcionalidad que podría estar integrada en las bibliotecas de WPF en alguna parte. Entonces me pregunto: ¿hay una solución corta y dulce? ¿O necesito escribir esto yo mismo?
EDITAR estoy añadiendo mi solución actual, no tan corto y dulce. No está tan mal, pero estaría sorprendido si algo WPF no proporcionaba esta funcionalidad de forma automática:
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);
}
Personalmente, probablemente lo haga exactamente como en su solución "no tan corta y dulce". No me encontré con una biblioteca integrada que hiciera esto. –