如何旋转放置在地图控件上的图像
How to rotate image placed on a Mapcontrol
问题
我有一个在地图上跟踪车辆的应用程序。但是我无法让小虫子按照它们的运动方向旋转。基本上都是横着走!啊!
密码
Image vehicleImage = new Image
{
//Set image size and source
};
RenderTransform rotation= new RotateTransform{Angle = X};
vehicleImage.RenderTransfrom = rotation;
_mainMap.Children.Add(vehicleImage);
MapControl.SetLocation(vehicleImage, _position);
放置在地图上的图像似乎完全忽略了我尝试应用的任何角度。
要理解旋转不生效的原因,我们先来看看下图,这张图取自Visual Studio中的Live Visual Tree -
我使用 Rectangle
,但在您的情况下,您会在那里看到 Image
控件。当您将它插入 MapControl.Children
集合时,它将被一个名为 MapOverlayPresenter
的特殊元素包裹(如图所示)。
这个 MapOverlayPresenter
是 MapControl
中的一个内部元素,令人惊讶的是,Internet 上没有关于它究竟做什么的官方文档。我的猜测是,当您缩放或旋转地图时,此叠加层只是通过沿相反方向缩放或旋转来响应,以保持子元素的原始大小和旋转,这会导致内部 Image
以某种方式迷路。
(P.S. Composition 中的 RotationAngle
and RotationAngleInDegrees
在这里也没有效果。)
解决方案
解决这个问题的方法很简单 - 不要直接在 Image
上公开旋转变换,而是创建一个名为 ImageControl
的 UserControl
来封装这个 Image
及其转换,具有 UriPath
和 Angle
等依赖属性,负责将信息向下传递到内部 Image
及其 CompositeTransform
属性.
ImageControl
XAML
<UserControl x:Class="App1.ImageControl" ...>
<Image RenderTransformOrigin="0.5,0.5"
Source="{x:Bind ConvertToBitmapImage(UriPath), Mode=OneWay}"
Stretch="UniformToFill">
<Image.RenderTransform>
<CompositeTransform Rotation="{x:Bind Angle, Mode=OneWay}" />
</Image.RenderTransform>
</Image>
</UserControl>
ImageControl
代码隐藏
public string UriPath
{
get => (string)GetValue(UriPathProperty);
set => SetValue(UriPathProperty, value);
}
public static readonly DependencyProperty UriPathProperty = DependencyProperty.Register(
"UriPath", typeof(string), typeof(ImageControl), new PropertyMetadata(default(string)));
public double Angle
{
get => (double)GetValue(AngleProperty);
set => SetValue(AngleProperty, value);
}
public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
"Angle", typeof(double), typeof(ImageControl), new PropertyMetadata(default(double)));
public BitmapImage ConvertToBitmapImage(string path) => new BitmapImage(new Uri(BaseUri, path));
如何使用这个ImageControl
var vehicleImage = new ImageControl
{
Width = 80,
UriPath = "/Assets/car.png",
Angle = 45
};
_mainMap.Children.Add(vehicleImage);
结果
希望对您有所帮助!
问题
我有一个在地图上跟踪车辆的应用程序。但是我无法让小虫子按照它们的运动方向旋转。基本上都是横着走!啊!
密码
Image vehicleImage = new Image
{
//Set image size and source
};
RenderTransform rotation= new RotateTransform{Angle = X};
vehicleImage.RenderTransfrom = rotation;
_mainMap.Children.Add(vehicleImage);
MapControl.SetLocation(vehicleImage, _position);
放置在地图上的图像似乎完全忽略了我尝试应用的任何角度。
要理解旋转不生效的原因,我们先来看看下图,这张图取自Visual Studio中的Live Visual Tree -
我使用 Rectangle
,但在您的情况下,您会在那里看到 Image
控件。当您将它插入 MapControl.Children
集合时,它将被一个名为 MapOverlayPresenter
的特殊元素包裹(如图所示)。
这个 MapOverlayPresenter
是 MapControl
中的一个内部元素,令人惊讶的是,Internet 上没有关于它究竟做什么的官方文档。我的猜测是,当您缩放或旋转地图时,此叠加层只是通过沿相反方向缩放或旋转来响应,以保持子元素的原始大小和旋转,这会导致内部 Image
以某种方式迷路。
(P.S. Composition 中的 RotationAngle
and RotationAngleInDegrees
在这里也没有效果。)
解决方案
解决这个问题的方法很简单 - 不要直接在 Image
上公开旋转变换,而是创建一个名为 ImageControl
的 UserControl
来封装这个 Image
及其转换,具有 UriPath
和 Angle
等依赖属性,负责将信息向下传递到内部 Image
及其 CompositeTransform
属性.
ImageControl
XAML
<UserControl x:Class="App1.ImageControl" ...>
<Image RenderTransformOrigin="0.5,0.5"
Source="{x:Bind ConvertToBitmapImage(UriPath), Mode=OneWay}"
Stretch="UniformToFill">
<Image.RenderTransform>
<CompositeTransform Rotation="{x:Bind Angle, Mode=OneWay}" />
</Image.RenderTransform>
</Image>
</UserControl>
ImageControl
代码隐藏
public string UriPath
{
get => (string)GetValue(UriPathProperty);
set => SetValue(UriPathProperty, value);
}
public static readonly DependencyProperty UriPathProperty = DependencyProperty.Register(
"UriPath", typeof(string), typeof(ImageControl), new PropertyMetadata(default(string)));
public double Angle
{
get => (double)GetValue(AngleProperty);
set => SetValue(AngleProperty, value);
}
public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
"Angle", typeof(double), typeof(ImageControl), new PropertyMetadata(default(double)));
public BitmapImage ConvertToBitmapImage(string path) => new BitmapImage(new Uri(BaseUri, path));
如何使用这个ImageControl
var vehicleImage = new ImageControl
{
Width = 80,
UriPath = "/Assets/car.png",
Angle = 45
};
_mainMap.Children.Add(vehicleImage);
结果
希望对您有所帮助!