Skip to main content
 首页 » 编程设计

c#之如何旋转放置在 map 控件上的图像

2024年01月31日37lonelyxmas

问题

我有一个在 map 上跟踪车辆的应用程序。但是我无法让小 bug 按照它们的运动方向旋转。基本上都是横着走!啊!

代码

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); 

放置在 map 上的图像似乎完全忽略了我尝试应用的任何角度。

请您参考如下方法:

要理解旋转不生效的原因,我们先来看看下图,它是从 Visual Studio 中的 Live Visual Tree 中截取的 -

我使用的是 Rectangle,但在您的情况下,您会在那里看到 Image 控件。当您将它插入 MapControl.Children 集合时,它将被一个名为 MapOverlayPresenter 的特殊元素包裹(如图所示)。

这个 MapOverlayPresenter 是 MapControl 中的一个内部元素,令人惊讶的是,Internet 上没有关于它究竟做什么的官方文档。我的猜测是,当您缩放或旋转 map 时,此叠加层只是通过沿相反方向缩放或旋转来响应,以保持子元素的原始大小和旋转,这会导致内部 Image 以某种方式迷路。

(P.S. RotationAngle 和 RotationAngleInDegrees 来自 Composition 在这里也没有效果。)


解决方案

解决这个问题的方法很简单——不是直接在 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); 

结果

希望这对您有所帮助!