Я пытаюсь изучить WPF, таким образом, вот простой вопрос, я надеюсь:
У меня есть окно, которое содержит Элемент изображения, связанный с отдельным объектом данных с настраиваемым пользователем Stretch
свойство
<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="{Binding ImageStretch}" />
Когда пользователь перемещает мышь через изображение, я хотел бы определить координаты мыши относительно исходного изображения (прежде чем протяжение/обрезка, которое происходит, когда это отображено в управлении), и затем сделают что-то с теми координатами (обновите изображение).
Я знаю, что могу добавить обработчик событий к Событию mouseMove по управлению Изображением, но я не уверен, как лучше всего преобразовать координаты:
void imageCtrl_MouseMove(object sender, MouseEventArgs e)
{
Point locationInControl = e.GetPosition(imageCtrl);
Point locationInImage = ???
updateImage(locationInImage);
}
Теперь я знаю, что мог сравнить размер Source
к ActualSize
из управления, и затем включают imageCtrl.Stretch
вычислить скаляры и смещения на X и Y, и сделать преобразование самостоятельно. Но WPF уже имеет всю информацию, и это походит на функциональность, которая могла бы быть встроена к библиотекам WPF где-нибудь. Таким образом, я задаюсь вопросом: существует ли короткое и сладкое решение? Или я должен записать это сам?
РЕДАКТИРОВАНИЕ я добавляю свой ток, not-so-short-and-sweet решение. Не, что плохо, но я был бы несколько удивлен, не обеспечил ли WPF эту функциональность автоматически:
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);
}
Вероятно, было бы проще, если бы вы использовали ViewBox. Например:
<Viewbox Stretch="{Binding ImageStretch}">
<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="None"/>
</Viewbox>
Затем, когда вы вызываете GetPosition (..), WPF автоматически учитывает масштабирование.
void imageCtrl_MouseMove(object sender, MouseEventArgs e)
{
Point locationInControl = e.GetPosition(imageCtrl);
}