在继承自ItemsPanel

时间:2019-02-11 19:09:05

标签: wpf xaml wpf-controls itemscontrol itemspresenter

我想扩展ItemsPanel,以便可以显示“分层”的视觉结构,其中有一个“框架”,该框架的大小已知且有很多覆盖层,类似于制图或插图应用程序

我遇到的问题是找出如何组合事物以使所有事物都能按预期工作的方式。到目前为止,我所做的事情:

  • 创建了一个继承自ItemsControl的控件;
  • 在控件内部,放入包含Viewbox的{​​{1}}
  • 在控件的“资源”中,创建一个针对其自身类型的样式,将ItemsPresenter设置为包含ItemsPanel的ItemsTemplate。

因此,我希望在“活树检查”下,我应该看到嵌套结构:

  • LayerContainer(我的控件的类名)
    • 查看框
      • ItemsPresenter
      • 帆布
        • Item1
        • Item2

相反,我看到的是这样:

  • LayerContainer
    • 边界
      • ItemsPresenter
      • 帆布
        • 查看框
        • Item1
        • Item2

因此,问题在于ViewBox包含在Canvas内以及渲染的项目旁边。

然后我的问题是:如何以嵌套顺序为ItemsPresenter-> Viewbox-> Canvas-> Items的方式构造LayerContainer控件?

这是我的控制权(名称实际上不是Canvas

LayerContainer

2 个答案:

答案 0 :(得分:0)

如果您想了解如何执行此操作的示例,请查看我的Perfy editor on GitHub,相关内容位于the MainWindow.xaml file中。它还显示了如何实现缩放和滚动(如果您想同时支持缩放和滚动,则实际上并不需要ViewBox,而只需要ScrollViewer父级和ItemsControl上的LayoutTransform)。

要回答您的问题,每个项目都包裹在ContentPresenter中,诀窍是改为在此父项目上设置Canvas位置。 ItemsControl公开了ItemContainerStyle,可让您做到这一点:

<ItemsControl.ItemContainerStyle>
    <Style TargetType="{x:Type ContentPresenter}">
        <Setter Property="Canvas.Left" Value="{Binding X}" />
        <Setter Property="Canvas.Top" Value="{Binding Y}" />
    </Style>
</ItemsControl.ItemContainerStyle>

尤其要注意,您不需要自己显式声明ItemsPresenter,这是因为您已经在使用ItemsControl开头。只需将ItemsPanel设置为Canvas,通过ContentPresenter设置ItemContainerStyle的样式,然后使用DataTemplates和/或触发器来指定集合项本身的外观。< / p>

答案 1 :(得分:0)

经过一番思考和谷歌搜索,我意识到我可以使用Template“覆盖”控件的ControlTemplate属性,在其中我可以将Viewbox放在根目录中它,ItemsPresenter。然后,在渲染时,每个项目都将放置在包含ItemsPanelTemplate的{​​{1}}中,并分配给Canvas属性。

因此,下面是最终的工作表格。解决方案的原则是还设置ItemsPanel属性(对于ViewBox) Template属性(对于Canvas)

ItemsPanel