什么是点到WPF装饰器? [英] What's the point to WPF adorners?

查看:396
本文介绍了什么是点到WPF装饰器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开发了一个绘图组件为我公司,采用了画布上,你可以借鉴使用单击并拖动某些形状。对于每一个的形状,我置于两装饰器上其AdornerLayer:一个用于增加点击检测(基本上是透明的矩形,将超过该形状的边界由几个像素),和另一调整大小(在转角处4拇指控制)

但是,我实现一些的成分的特性时,遇到了许多问题,所有装饰器相关

  • 他们捕获的所有preVIEW事件,因为他们是在另一可视化树比画布本身,那是意外,但我找到了一个解决办法,即使我不喜欢那么多。使用AdornerDecorator没有解决这个问题,因为我实现了一个选择装饰器是一个黑洞preVIEW事件。

  • 当我实现的z-index操作形状在画布的(发送到后,带来正面,等等),它工作得很好用Panel.SetZIndex,如你所期望。但是,在装饰器是另一种可视化树!所以他们并没有受到影响,并且选择装饰器仍然在所有其他形状的顶端,即使这些形状分别对一个选择装饰器被检测命中为顶部。 例如: Shape1,SelectionAdorner1。 Shape2,SelectionAdorner2。 Shape1是Shape2的顶部(后添加到画布),所以它的重叠它。因此,它的点击将由SelectionAdorner1被检测到。我操纵了zIndex的将其发送到后,现在Shape2是在顶部和重叠Shape1。我点击Shape2之上,但是点击由SelectionAdorner1而不是SelectionAdorner2检测。 这是特别烦人。所以,很明显,因为装饰器是在另一可视化树,他们不尊重ZIndexes。我试图通过该形状的zIndex的及其SelectionAdorner的zIndex的之间建立一个数据绑定(和也通过手动设置),以解决这个问题。但是,这并没有解决问题。改变装饰器的zIndex的影响并不大,他们在屏幕上显示的方式,也许我失去了一些东西,但它不应该是真的这很难,因为装饰器都应该是取得了令事情变得更容易。唯一的解决办法我能想出了手动删除所有的装饰器和手动逐个再次加入,增加了对最后一个应该是在上面。这是智障,但它的工作。

  • 接下来,装饰器不尊重ClipToBounds!我设置ClipToBounds =在画布中真实的我在做我的图纸上,它工作得很好,但该死的装饰器仍然工作!该解决方案,这是相对容易的,我只是增加了一个AdornerDecorator每个形状的顶部。不是一个理想的解决方案,国际海事组织,但是这就是一个很简单的。

  • 装饰器并不总是在他们的佐餐元素进行LayoutTransforms反应良好。我有一个实现缩放和平移功能画布上方的面板。它用于动画制作放大和缩小更加流畅。但是,使用动画使我的装饰器去猿!第一变焦他们将简单地忽略调整大小,并保持相同的大小和位置,对第二变焦他们将缩放到的 previous 的所述佐餐元件的大小。这并没有任何意义!唯一的解决办法我能找到的是禁用的动画,这令人欣慰的工作

我不太记得我有哪些其他的问题,但这是绰绰有余,MAME我想知道装饰器的用处,而且我认真考虑不使用他们在我的下一个项目,这是类似的一个我描述。

那么,谁能告诉我什么可能是用这些看似有用,但令人难以置信的烦人的事情的利弊?

感谢。

解决方案

我想你已经知道这个问题的答案。它们保存在一些方面中时间,并造成在其他问题。如果你要$ C C使用各种用户控件的此设计行为$,你会发现自己写了很多样板控件类的包装,你实际上想要编辑的元素。如果,另一方面,你试着写独立的编辑控件,智能包裹,你会写的样板code保持同步它们的位置和大小。你拿了,使用装饰器,这种方法产生了大量的(相当样板)code管理活动。

虽然装饰器可能不适合这个的尤其的任务的最佳工具,但它们仍然为其他,简单的任务的有用工具。我最近写了一个类似的一种设计图面和装饰器是一个天赐两部分:

  1. 的拖放行为。当我拖着不同的元素,他们需要有不同的视觉previews;这是非常容易实现使用自定义装饰器和数据模板。
  2. 选择矩形或套索。你可以看到类似的,当你把你的鼠标左键在Windows桌面上和周围拖动指针。它创建了一个半透明的框,可以选择多个元素。我能够与装饰器层几乎立即创建这个行为,而创建自己的自定义控制造成了很多不必要的簿记。

我觉得你在你的项目中发现了什么是你可以用装饰器已尝试完成太多。但不要把婴儿与他们仍然在某些情况下非常有用的bathwater--。

I've recently developed a drawing component for my company, featuring a Canvas on which you can draw certain shapes using click-and-drag. For each shape, I placed two adorners on its AdornerLayer: One for increased hit detection (basically a transparent rectangle that would exceed the shape's boundaries by a few pixels), and another for resizing (four Thumb controls on the corners).

But, I ran into many problems when implementing some of the features of the component, all adorner related.

  • They captured all preview events, since they were in another visual tree than the Canvas itself, that was unexpected, but I found a workaround, even if I did not like it that much. Using an AdornerDecorator did not solve this issue, a selection adorner as I implemented is a black hole for preview events.

  • When I implemented z-index manipulation of shapes on the Canvas (send to back, bring to front, etc), it worked fine using Panel.SetZIndex, as you'd expect. But, the adorners are in another visual tree! so they were not affected and the selection adorners were STILL on top of all other shapes, even if those shapes were on top of the one the selection adorner was detecting hits for. For example: Shape1, SelectionAdorner1. Shape2, SelectionAdorner2. Shape1 is on top (added later to the canvas) of Shape2, so it's overlapping it. So a click on it will be detected by SelectionAdorner1. I manipulated the ZIndex to send it to back, now Shape2 is on top and overlaps Shape1. I click on top of Shape2, but the click is detected by SelectionAdorner1 instead of SelectionAdorner2. This was particularly annoying. So, apparently since Adorners are on another visual tree, they don't respect ZIndexes. I tried to solve it by creating a DataBinding (and also by manually setting) between the ZIndex of the shape and the ZIndex of its SelectionAdorner. But this did not solve the issue. Altering the ZIndex of Adorners did not affect the way they were displayed on screen, maybe I was missing something, but it shouldn't be really this hard, since Adorners are supposed to be made to make things easier. The only solution I could come up with was manually removing all adorners and add them again manually one by one, adding for last the one that was supposed to be on top. That was retarded, but it worked.

  • Next, Adorners don't respect ClipToBounds! I set ClipToBounds=true in the Canvas I was doing my drawing on, and it worked fine, but damn adorners would still work! The solution to this was relatively painless, I just added an AdornerDecorator on top of each Shape. Not an ideal solution IMO, but one that was simple enough.

  • Adorners not always react well to LayoutTransforms performed on their adorned elements. I have a Panel on top of the canvas which implements Zoom and Pan functionality. It used Animations to make zooming in and out more smooth. But using animations caused my Adorners to go ape! The first zoom they would simply ignore the resize and stay the same size and position, on the second zoom they would scale to the previous size of the adorned element. That did not make any sense! only solution I could find was to disable animations, which thankfully worked

I don't quite remember which other issues I had, but this was more than enough to mame me wonder about the usefulness of Adorners, and I'm seriously considering not using them in my next project, which is similar to the one I described.

So, can anyone tell me what could possibly be the pros of using these seemingly useful but incredibly annoying things?

Thanks.

解决方案

I think you already know the answer to your question. They save time in some aspects, and cause problems in others. If you were to code this designer behavior using a variety of UserControls, you would find yourself writing a lot of boilerplate control classes to wrap the elements that you actually wanted to edit. If, on the other hand, you tried to write separate editing controls and intelligently overlay them, you would be writing boilerplate code to keep their positions and sizes in sync. The approach you took, using adorners, resulted in a lot of (fairly boilerplate) code to manage events.

While adorners may not be the best tool for this particular task, they are still a useful tool for other, simpler tasks. I recently wrote a similar kind of "design surface" and adorners were a godsend for two pieces:

  1. The drag-drop behavior. When I dragged different elements, they needed to have different visual previews; this was remarkably easy to accomplish using a custom adorner and data templates.
  2. The selection rectangle or "lasso." You can see something similar when you hold your left mouse button down on a Windows desktop and drag the pointer around. It creates a semi-transparent box that can select multiple elements. I was able to create this behavior almost instantly with the adorner layer, whereas creating my own custom control resulted in a lot of unnecessary book-keeping.

I think what you discovered in your project is that you may have been using adorners to try and accomplish too much. But don't throw the baby out with the bathwater-- they are still very useful in certain scenarios.

这篇关于什么是点到WPF装饰器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆