我想要扩展ItemsPanel,以便我能够显示一个“分层”的视觉结构,其中我有一个已知大小和大量覆盖的“框架”,类似于地图或插图应用程序。
我面临的问题是找出如何将事物组合起来,使一切都如预期的那样工作。我到目前为止所做的事:
ItemsControl的控件;Viewbox的ItemsPresenterItemsPanel设置为由Canvas组成的ItemsTemplate。因此,我希望,在Live检查中,我应该看到,在嵌套结构中:
相反,我看到的是:
因此,问题是ViewBox包含在画布中,与呈现的项一起。
然后,我的问题是:如何在嵌套顺序为ItemsPresenter->Viewbox->Canvas->ItemsPresenter-> LayerContainer ->ItemsPresenter->Viewbox->Canvas->ItemsPresenter->Viewbox->Canvas->ItemsPresenter->ItemsPresenter->Viewbox->Canvas->ItemsPresenter->ItemsPresenter->Viewbox->Canvas->ItemsPresenter->ItemsPresenter->Viewbox->Canvas->ItemsPresenter->ItemsPresenter->Viewbox-
下面是我的控件(名称实际上不是LayerContainer)
<ItemsControl x:Class="Miotec.PressureMapping.UserControls.BaroLayerContainer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Miotec.PressureMapping.UserControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ItemsControl.Resources>
<Style TargetType="local:BaroLayerContainer">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas Width="{Binding Parametros.Colunas}"
Height="{Binding Parametros.Linhas}"
IsItemsHost="True"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<Viewbox Stretch="Uniform" x:Name="container">
<ItemsPresenter
Width="{Binding ActualWidth, ElementName=container}"
Height="{Binding ActualHeight, ElementName=container}"/>
</Viewbox>
</ItemsControl>发布于 2019-02-11 22:20:47
如果您想要一个如何做到这一点的工作示例,那么请查看我的GitHub上的Perfy编辑器,相关部分在MainWindow.xaml文件中。它还展示了如何实现缩放和滚动(如果您想同时支持这两种功能,那么您实际上不需要一个ViewBox,只需要一个ScrollViewer父级和一个ItemsControl上的LayoutTransform )。
要回答您的问题,每个项目都包装在一个ContentPresenter中,诀窍是在此父项上设置画布位置。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设置为画布,通过ItemContainerStyle设置ContentPresenter的样式,然后使用DataTemplates和/或触发器来指定集合项本身的外观。
发布于 2019-02-12 12:44:33
经过一些思考和googling之后,我意识到我可以“覆盖”我的控件的Template属性,使用一个ControlTemplate,在这里我会将Viewbox作为根,并在其中放置ItemsPresenter。然后,在呈现时,每个项目将被放置在包含ItemsPanelTemplate的Canvas中,分配给ItemsPanel属性。
下面是最后的工作表格。解决方案的原则是,除了Template属性(用于画布)之外,还设置ItemsPanel属性(用于ViewBox)。
<ItemsControl x:Class="Miotec.PressureMapping.UserControls.BaroLayerContainer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Miotec.PressureMapping.UserControls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Grid x:Name="container">
<Viewbox Stretch="Uniform"
Width="{Binding ActualWidth, ElementName=container}"
Height="{Binding ActualHeight, ElementName=container}">
<ItemsPresenter/>
</Viewbox>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="{Binding Parametros.Colunas}"
Height="{Binding Parametros.Linhas}"
IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>https://stackoverflow.com/questions/54637458
复制相似问题