【发布时间】:2017-03-12 18:12:24
【问题描述】:
我有一个ItemsControl,它使用Canvas 作为ItemsPanel,它的项目根据绑定类型呈现为不同的 WPF 形状,基本上是这样的:
<ItemsControl ItemsSource="{Binding PreviewShapes}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:UiPreviewLineViewModel}">
<Line X1="{Binding Start.X}" Y1="{Binding Start.Y}"
X2="{Binding End.X}" Y2="{Binding End.Y}"
StrokeThickness="0.75" Stroke="{Binding Brush}" x:Name="Line" ToolTip="{Binding Text}">
</Line>
</DataTemplate>
<DataTemplate DataType="{x:Type local:UiPreviewEllipsisViewModel}">
<Ellipse Canvas.Left="{Binding UpperLeft.X" Canvas.Top="{Binding UpperLeft.Y}"
Width="{Binding Width}" Height="{Binding Height}"
StrokeThickness="0.75" Stroke="{Binding Brush}" x:Name="Ellipse" ToolTip="{Binding Text}">
</Ellipse>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True" HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="SketchCanvas" ClipToBounds="False">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
所以我基本上将对象添加到视图模型的PreviewShapes,并根据它们呈现到 WPF Lines 或 Ellipses 的类型。这基本上可行,但附加属性 Canvas.Left 和 Canvas.Top 被忽略,即使使用静态值也是如此。
VS 或 ReSharper 也会通知我附加的属性在当前上下文中无效。
如何在不使用附加属性的情况下将Ellipse 定位在画布上?或者还有什么其他的解决方案是合适的?
【问题讨论】:
-
DataTemplate 中的元素不会成为 Canvas 的直接子元素(因为它们将被用作作为项目容器的 ContentPresenter 的内容)。您只能在 ItemContainerStyle 中设置
Canvas.Left和Canvas.Top,如下所示,例如在this answer。 This answer 也可能有帮助。 -
除此之外,在 ItemsControl 的资源中拥有 ListBoxItem 样式看起来很奇怪。
-
Style一定是旧代码的遗留物,我将其从示例代码中删除。
标签: wpf datatemplate attached-properties