Len*_*ijn 20 c# wpf graphics graph vector-graphics
我正在创建一个严重依赖图节点树的工具.当前的实现是用Java完成的,我将它移植到C#上的通用代码库中,因此它可以被各种渲染实现使用,也因为我想使用WPF的强大功能来实现用户友好的界面.
浏览了一天之后,我遇到了各种方法来通过WPF绘制矢量图形.
这个人讲的是WPF开发人员可以选择的不同层.因为我想首先使用WPF PURELY进行渲染,所以我想开发"Visual Layer".
然后我遇到了类似的东西: DrawingVisual, GeometryDrawing, FrameworkElement/UIElement/Shapes
所以,我对所有不同的实现有点不知所措,这些实现最终以完全不同的方式完成相同的操作.
Graph-Node库已经用它的所有逻辑(包括碰撞检测和用鼠标拖动)移植到C#.因为它是用图形渲染器(如XNA,SlimDX,OpenTK等)制作的,所以在性能方面实现WPF渲染器的最佳方式(如同,它将绘制图形库告诉它的任何东西)画画?
基本上,生成的WPF控件充当画布,但它必须是SUPER轻量级,除了为我提供绘制我的圆圈,线条和其他形状的方法之外,没有任何简洁的WPF功能:)
编辑:
我基本上想知道:要走的路是什么?我是否将Canvas扩展为我的图形的"主机",然后添加我的UIElement的自定义实现?或者我可以拥有一个可以绘制一切的课程(例如,一个超级超级超级图形).就像在GDI中覆盖OnPaint或在Java中覆盖Paint-method(它使Graphics对象可以完成所有操作).
Ree*_*sey 12
我建议阅读优化性能:2D图形和成像(死链接 - 可通过Internet Archive读取) -
基本上,Drawing物体的重量Shapes通常比较轻.这可能是你想要使用的.
通常,使用较低级别的服务可以获得更好的性能.在WPF,这意味着Drawing对象系列.所有你得到的是:Drawing,DrawingGroup,GeometryDrawing,GlyphRunDrawing,ImageDrawing,和VideoDrawing.但是,它们足以满足所有需求.使用这些类型对WPF非常友好,因为它Drawing是WPF与GPU加速器交换的概念单元,如果可能的话,可能会在那里保留和管理它.这是有效的,因为它Drawing是以便携式矢量绘图原语表示的.
一旦你开始重新架构在你的应用Drawings然而,你可能需要一些互操作与它仍然是基于你的更高级别的代码UIElement,FrameworkElement等等,我还没有发现内置于WPF的一件事是一个简单的方法包以尽可能低的开销方式绘制为FrameworkElement.DrawingVisual不是一个完整的解决方案,因为它只是源于 - Visual意味着它仍然需要一个托管元素.
以下类将Drawing直接托管任何WPF 而不使用中间件DrawingVisual.我添加了FrameworkElement对Margin属性的支持(如果未使用则不会造成性能损失),但很少.由于WPF的单个渲染线程,缓存单个TranslateTransform对象以实现边距是安全且容易的.我建议您只提供已冻结的图纸; 事实上,在我使用的版本中,我在构造函数中有一个断言.
public class DrawingElement : FrameworkElement
{
static readonly TranslateTransform tt_cache = new TranslateTransform();
public DrawingElement(Drawing drawing)
{
this.drawing = drawing;
}
readonly Drawing drawing;
TranslateTransform get_transform()
{
if (Margin.Left == 0 && Margin.Top == 0)
return null;
tt_cache.X = Margin.Left;
tt_cache.Y = Margin.Top;
return tt_cache;
}
protected override Size MeasureOverride(Size _)
{
var sz = drawing.Bounds.Size;
return new Size
{
Width = sz.Width + Margin.Left + Margin.Right,
Height = sz.Height + Margin.Top + Margin.Bottom,
};
}
protected override void OnRender(DrawingContext dc)
{
var tt = get_transform();
if (tt != null)
dc.PushTransform(tt);
dc.DrawDrawing(drawing);
if (tt != null)
dc.Pop();
}
};
Run Code Online (Sandbox Code Playgroud)
[edit:]这对于将WPF Drawing插入InlineUIContainer.Child属性(即使用TextBlock.InlinesCollection更丰富地格式化TextBlock的内容)也很有用.
| 归档时间: |
|
| 查看次数: |
21941 次 |
| 最近记录: |