在WPF中更改Canvas的坐标系
我正在编写一个使用Canvas定位元素的地图应用程序。 对于每个元素,我必须以编程方式将元素的Lat / Long转换为canvas的坐标,然后设置Canvas.Top和Canvas.Left属性。
如果我有一个360x180canvas,我可以将canvas上的坐标转换为从X轴上的-180到180而不是0到360以及Y轴上的90到-90而不是0到180?
扩展要求:
这是一个全XAML解决方案。 好吧,主要是XAML,因为你必须在代码中使用IValueConverter。 所以:创建一个新的WPF项目并为其添加一个类。 该类是MultiplyConverter:
namespace YourProject { public class MultiplyConverter : System.Windows.Data.IValueConverter { public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return AsDouble(value)* AsDouble(parameter); } double AsDouble(object value) { var valueText = value as string; if (valueText != null) return double.Parse(valueText); else return (double)value; } public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new System.NotSupportedException(); } } }
然后将此XAML用于您的Window。 现在,您应该在XAML预览窗口中看到结果。
编辑 :您可以通过将您的canvas放在另一个canvas中来解决背景问题。 有点奇怪,但它的工作原理。 另外,我添加了一个ScaleTransform,它翻转Y轴,使正Y向上,负向向下。 请注意哪些名称去哪里:
至于你需要不同范围的新要求,更复杂的ValueConverter可能会做到这一点。
我能够通过创建自己的自定义canvas并覆盖ArrangeOverride函数来实现它:
public class CustomCanvas : Canvas { protected override Size ArrangeOverride(Size arrangeSize) { foreach (UIElement child in InternalChildren) { double left = Canvas.GetLeft(child); double top = Canvas.GetTop(child); Point canvasPoint = ToCanvas(top, left); child.Arrange(new Rect(canvasPoint, child.DesiredSize)); } return arrangeSize; } Point ToCanvas(double lat, double lon) { double x = this.Width / 360; x *= (lon - -180); double y = this.Height / 180; y *= -(lat + -90); return new Point(x, y); } }
这适用于我描述的问题,但它可能不适用于我的另一个需求,即PathGeometry。 它不起作用,因为这些点没有被定义为Top和Left,而是作为实际点。
我很确定你不能完全这样做,但是有一个从lat / long转换为Canvas坐标的方法会非常简单。
Point ToCanvas(double lat, double lon) { double x = ((lon * myCanvas.ActualWidth) / 360.0) - 180.0; double y = ((lat * myCanvas.ActualHeight) / 180.0) - 90.0; return new Point(x,y); }
(或类似的规定)
我想另一个选择是扩展canvas并覆盖度量/安排,使其表现得如你所愿。
您可以使用变换在坐标系之间进行平移,可以使用TranslateTranform的TransformGroup将(0,0)移动到canvas的中心,使用ScaleTransform将坐标移动到正确的范围。
使用数据绑定和可能是一个或两个值转换器,您可以根据canvas大小自动更新转换。
这样做的好处是它适用于任何元素(包括PathGeometry),可能的缺点是它会扩展所有内容而不仅仅是点 – 所以它会改变地图上图标和文本的大小。
另一种可能的方案
在另一个canvas(背景canvas)中嵌入自定义canvas(绘图到canvas)并将绘图设置为canvas,使其透明且不会剪切到边界。 使用矩阵转换绘图到canvas,使y翻转(M22 = -1)并翻译/缩放父canvas内的canvas,以查看您正在查看的世界的延伸。
实际上,如果在绘图到canvas中绘制-115,42,则绘制的项目将“关闭”canvas,但无论如何都会显示,因为canvas没有剪切到边界。 然后,您可以将绘图转换为canvas,以便该点显示在背景canvas上的正确位置。
这是我很快就会尝试的事情。 希望能帮助到你。
这是一个答案 ,它描述了一个允许您应用笛卡尔坐标系的Canvas
扩展方法。 即:
canvas.SetCoordinateSystem(-10, 10, -10, 10)
将设置canvas
的坐标系,使x
从-10到10, y
从-10到10。
我有几乎相同的问题。 所以我上网了 而且这个家伙使用矩阵从“设备像素”转换为他所谓的“世界坐标”,并且他认为真实世界数字代替“设备像素”看到链接
https://csharphelper.com/blog/2014/09/use-transformations-draw-graph-wpf-c/
上述就是C#学习教程:在WPF中更改Canvas的坐标系分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1016067.html