因为System.Windows.Point / System.Drawing.PointF的差异,WPF / Silverlight和GDI+之间共享库的问题分享

4
在我目前正在工作的项目中 http://sourcecodecloud.codeplex.com/,我有一个包含非平凡的几何和布局算法的库,它们完全独立于图形引擎。
此应用最初是为GDI+编写的,现在我打算实现它的Silverlight和/或WPF移植版。问题是我的所有算法都使用System.Drawing.PointFSizeFRectangleF结构体,它们都是基于float的。相应的WPF / Silverlight类是double
问题是,有没有人有这方面的经验?最好的方法是什么?
  1. 创建自己的封装器,用于封装大小、点、矩形等,可以同时包装两种变量。
  2. 坚持使用System.Drawing或System.Windows,并将其强制转换为另一种。负面影响是不需要对“外部”程序集进行引用。
  3. 其他魔术?
4个回答

4

一个适用的方法是使用名称空间别名。您可以使用别名而不是实际类型,并使用编译器指令在它们之间切换。由于命名空间别名是每个文件的,所以如果代码分布在很多文件中可能不太合适。

#if GDI
using Point=System.Drawing.Point;
#else
using Point=System.Windows.Point;
#endif

如果您使用 var ,您可以消除许多检查和转换,并保持性能。但是,您仍然需要查看接受和返回特定类型的函数,例如 Math.Sin 等。


也许对我来说不是一个选项,但这是非常有趣和实用的方法。以前没有想过这个方向,可以帮助别人。有点调整 :D。 +1。 - George Mamaladze

1
我会使用WPF类型,并使用一些全局(扩展?)方法来转换为GDI。它们比Gdi更完整、更合理。缺点是它们是双倍的,所以它们更大。但是,随着我们现在拥有的所有内存,你不太可能遇到这样的问题。

所以你的意思是2。如果没有人提出更好的想法,我会接受你的答案。内存并不是真正的问题,我知道在GDI+绘制操作期间会发生许多数千次转换的问题。 - George Mamaladze

1

我建议您以Portable Library Tools为基础开始。其中的任何类型都适用于您所有的项目。对于其中不存在的任何类型,我建议您创建自己的抽象类型,并实现派生类型,分别包装每个框架中相关的类型。尽可能多地从您自己的代码中使用您创建的抽象类型。


由于进行了许多千次计算,我对转换和强制类型转换存在疑虑。采用这种方法会在两端都产生性能缺陷,因此您应该为Win.Point和Draw.Point进行包装和解包装。无论如何,感谢您的建议 - 我会查看库。 - George Mamaladze
这个答案让我朝着最适合我的应用程序方向前进。我创建了自己的结构和适当的平台特定扩展方法进行转换。性能损失微不足道。 - George Mamaladze

1

我正在开发一个地图/GIS应用程序,其中有大量的几何和图形计算。最初,我在渲染代码中直接使用GDI+的类,如PointPointF,但这越来越成为问题,因为我想支持Cairo、SVG、Direct2D和其他图形引擎。因此,最后我自己制作了基于接口的层次结构,例如IPointF2IPointD2IPointD3等。当涉及到性能时,它肯定不是完美的,但我没有看到更好的方法来保持你的算法代码与图形引擎分离。

我之前写过关于这个主题的文章


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接