我正在尝试构建一个控件,该控件将在一个调度网格中显示项目,以便根据它们的类别水平放置它们,并根据它们的计划时间和垂直时间垂直放置该项目将完成。我目前继承自System.Windows.Controls.Control,默认样式和模板如下所示:
<Style TargetType="KHS:TimeGrid">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="KHS:TimeGrid">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<DockPanel>
<Grid Name="PART_HeaderGrid" DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ActualWidth, ElementName=TimeColumn}"/>
</Grid.ColumnDefinitions>
</Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled">
<Grid Name="PART_BodyGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Name="TimeColumn" Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
</ScrollViewer>
</DockPanel>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
对于我的项目,我只是使用这个界面:
Public Interface ITimeGridItem
Property StartTime As Date
Property Duration As TimeSpan
End Interface
将行添加到&#34; BodyGrid&#34;对于每个时间增量(默认表示15分钟),项目根据其开始时间和持续时间给出Grid.Row和Grid.RowSpan值。
当我尝试为项目实现DataTemplates时,我遇到了问题。我目前正在尝试使用ContentPresenters来显示这些项目。为TimeGrid创建一个ItemTemplate属性会很容易,只是将它用于所有项目,但是如果我需要使用唯一模板模拟不同类型的项目呢?
这让我想到其他控件如何将DataTemplates添加到具有不同DataType的Resources集合中,并且控件知道搜索资源并选择正确的模板。不幸的是,我还没有弄清楚如何实现这一点。谁知道我怎么能做到这一点?它必须是可能的,因为微软在它们的控件中做到了。
答案 0 :(得分:0)
我不太了解您的具体实现,以便为您提供准确的答案,但我可能会考虑使用您应用自定义模板的包装器控件,然后在其中放置一个ContentControl来呈现孩子们用他们自己模仿的东西来观察。
老实说虽然我不会使用网格来做这样的事情,但我过去做过的方式是使用数据绑定。为要显示的所有项目创建视图模型,并为其指定X和Y属性。然后在你的XAML中使用一个以Canvas作为背景的ItemsControl将它们全部绘制出来,并将项目的Canvas.Top和Canvas.Left dp绑定到X和Y&#39; s。这样,您的视图模型代码可以完全自由地将子项准确定位到您想要的位置,您也可以进行单元测试,而无需自己调用视图类。一旦我停止尝试使用XAML过于聪明,并且只是坚持使用它进行松散耦合的数据绑定,复杂的GUI设计突然变得非常容易实现。
答案 1 :(得分:0)
天啊,我不敢相信这么简单。实际上,我必须对@ ed-plunkett给予一些赞赏,因为他的所有显而易见的评论。我看起来有点困难,偶然发现如果我改变了这个:
<DataTemplate DataType="local:TestItem">
到此:
<DataTemplate DataType="{x:Type local:TestItem}">
它有效!
几分钟后,我发现了这篇文章:
http://briannoyesblog.azurewebsites.net/2013/11/23/use-xtype-with-wpf-implicit-datatemplates
*叹气*我希望我早些时候找到了。
因此,只要我使用{x:Type}语法,我就可以将DataTemplate放在范围内的任何位置并将其应用。