我正在尝试学习WPF,所以这是一个简单的问题,我希望:
我有一个窗口,其中包含一个Image元素,该元素绑定到一个具有用户可配置的Stretch
属性的单独数据对象
<Image Name="imageCtrl" Source="{Binding MyImage}" Stretch="{Binding ImageStretch}" />
当用户将鼠标移动到图像上时,我想确定鼠标相对于原始图像的坐标(在控件中显示时进行拉伸/裁剪之前) ),然后用这些坐标做一些事情(更新图像)。
我知道我可以通过Image控件向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库的功能。所以我想知道:有一个短暂而甜蜜的解决方案吗?或者我自己需要写这个?
编辑我正在追加我目前的,不那么短而且甜蜜的解决方案。它并没有那么糟糕,但如果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);
}
答案 0 :(得分:8)
如果使用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);
}