2010-01-08 25 views
1

我目前正在创建一个类似MSPaint的WPF应用程序,并且正在努力实现可捕捉网格。WPF:创建可变间距的可捕捉网格线

网格的绘制对于VisualBrush和Rectangle来说没有问题,但问题在于这些线条纯粹是为了外观而不能轻易改变(例如,当对齐到特定线条时突出显示) 。

我的另一个想法是有一个2 Canvas解决方案,其中1个Canvas用于元素,一个Canvas(位于另一个之上)包含所有网格线。不过,我有这样的感觉,这意味着相当的性能打击。

是否有其他可能的方法来实现这种功能?

回答

2

两板的方法VS的DrawingContext

的效率考虑我有一个好消息要告诉你:你错了有关显著的性能影响。即使将单个对象用于网格线,您的双画布想法也几乎是最佳的。这是因为WPF使用保留模式呈现:当您创建画布时,其上的所有内容都将被序列化为本机级别的紧凑结构。这仅在您以某种方式更改网格线时发生变化,例如更改网格间距。在所有其他时间,性能将与可能最快的托管代码方法无法区分。

如Nicholas所述,使用DrawingContext可能会略微提升性能。

更简单和更有效的解决方案

也许更好的方法,则网格画布上绘制各条线是使用两个瓷砖视觉刷子(1个水平,一个垂直)来绘制所有unhilighted线,然后使用Rectangle(s)在代码隐藏中添加到您正在捕捉的行。

这种技术的主要优点是您的网格可以有效无限,因此不需要计算正确数量的网格线来绘制,然后每次窗口大小调整或缩放更改时更新此网格线。您也只有三个UIElements参与,再加上一个当前高光的每个网格线。对于我来说,跟踪网格线集合似乎也比较清晰。

你想使用两个视觉画笔的原因是绘图更有效率:绘制垂直线的画笔被拉伸到一个巨大的距离(例如双倍。MaxValue/2),因此GPU每个垂直线只能获取一个绘图调用,而水平线则相同。做双向平铺的效率要低得多。

装饰器层

既然你问到的替代品,另一种可能是上面而使用AdornerAdornerLayer与任何解决方案,比使用例如网格叠加画布或包含画布。对于类似Paint的应用程序,这很好,因为装饰图层可以位于图形图层上方,但装饰者仍然可以附加到正在显示的单个项目。

+0

我真的不明白你的想法与2视觉刷。你可以说得更详细点吗?我甚至不知道有一种方法可以在一个窗格上使用2种不同的视觉画笔。 – chrischu 2010-01-08 22:09:55

+0

如果您使用''',您可以用''绘制两个矩形,每个都有自己的可视化画笔。除了顶部的网格线宽度区域以外,HorizBrush将是透明的,除了左边的网格线宽度区域外,VertBrush将是透明的。视口/视图框和平铺将被设置,以便每个画笔在给定方向上以适当的网格线间隔重复,从而创建网格。 – 2010-01-11 22:45:37

+0

请注意,与使用单独的''相比,可能会有更有效的布局方式。例如,您可以共享现有的'',或者可以有''。 – 2010-01-11 22:46:41

1

您可以考虑使用OnRender内部的DrawingContext绘制网格。通过这种方式不会在视觉树中引入新的UIElement,这有助于保持性能。在某些方面,它与您目前使用VisualBrush进行的操作相似,后者也不会为每个副本创建新的UI元素。

但是,由于您实际上将单独绘制每条线而不是复制单条线的外观,因此您将能够突出显示参与对齐的网格线,而不会更改那些可以做到的颜色不。

如果您要走这条路线,请务必查看GuidelineSet s的定位指引线(更多详细信息here),因为您可能希望将指引线对齐设备的像素以便它们大幅度吸引。