在深度嵌套的视觉树中拖放装饰器

Posted

技术标签:

【中文标题】在深度嵌套的视觉树中拖放装饰器【英文标题】:Drag&Drop-adorner in deeply nested visual trees 【发布时间】:2009-06-18 12:58:57 【问题描述】:

我们有一个 WPF 应用程序,它在画布上具有自定义窗口,而画布又包含自定义控件(包含自定义窗口的主画布再次是自定义控件显示内容)。所以基本上视觉树看起来像这样(没有隐含的边框和其他东西):

- Windows
  - Canvas
    - WindowMgr
      - CustomWindow (maximized with z-index 0, functioning as background)
        - ScrollPresenter
          - CustomControl1
      - CustomWindow
        - ScrollPresenter
          - CustomControl2

现在我们需要从这些自定义控件相互拖放(通常是从可移动窗口到背景窗口)。要显示拖放装饰器,需要一个装饰元素和一个装饰层。通常示例使用它们的网格或项目控件,并从同一元素中获取装饰层。

在这里做同样的事情是行不通的,因为 ScrollPreseneter/CustomWindows 会剪辑它们的内容,这会阻止你拖出窗口。现在,我们沿着可视化树向上走,直到找到根画布并将其用作装饰元素,但这似乎有点脏(而且根据我们的经验,它不是很健壮)。

对此有什么稳健的解决方案建议吗?

【问题讨论】:

【参考方案1】:

如果我正确阅读了您的问题,并且由于您自己没有提及,您可能正在寻找AdornerDecorator Class,它为可视树中其下方的元素提供了一个装饰层

假设ScrollPresenter 是从ContentPresenter 派生的,值得注意的是,要实现高级自定义控件,您可能希望用AdornerDecorator 包围它们的ContentPresenter,就像Window Class 一样,例如,请参阅 Don’t forget the AdornerDecorator 以了解涉及拖放的不错的真实工作场景。

也就是说,通过AdornerDecorator,您将确保所需的AdornerLayer 包含在您的自定义控件中,因此无需通过在可视化树上向上检索它,例如:

 <ControlTemplate TargetType="x:Type CustomWindow">
     <Border ...>
         <Grid>
             <AdornerDecorator>
                 <ScrollPresenter ... />
             </AdornerDecorator>
         </Grid>
     </Border>
 </ControlTemplate>

根据您的特定情况,您可能需要AdornerDecorator 用于您的自定义窗口、自定义控件或两者。

有关装饰器架构的更多详细信息,请参阅Adorners Overview。

【讨论】:

以上是关于在深度嵌套的视觉树中拖放装饰器的主要内容,如果未能解决你的问题,请参考以下文章

无法访问拖动装饰器模板

5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器

装饰器模式问题 - 如何调用嵌套装饰器方法?

Python基础高阶函数+函数嵌套+闭包 ==装饰器

装饰器

在装饰器中使用全局嵌套模块