我有这个简单的 XAML 示例:
<Window x:Class="DynTemplateTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="30" Height="30" Fill="Red"></Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Position}"></Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<ContentPresenter
Content="{Binding Path=Items}"
ContentTemplate="{StaticResource ItemTemplate}"
>
</ContentPresenter>
</DockPanel>
</Window>
它正在以 MVVM 风格渲染可观察集合中的项目。每个项目在属性中都有其水平位置。每个项目还有一个属性 IsSpecial,它告诉它是否要以某种特殊的方式呈现。我希望普通项目 (IsSpecial=false) 呈现为红色方 block (已在代码中),特殊项目呈现为蓝色圆圈,其中包含“特殊”文本。
我不知道如何调整 XAML 代码来为项目进行模板选择。有没有一种方法可以在不编写我自己的 ItemTemplateSelector 的情况下做到这一点?它仍然适用于基于绑定(bind)的 Canvas 定位吗?我认为解决方案是将项目模板提取到一个单独的模板,为特殊项目再创建一个模板,然后以某种方式使用触发器......但这对我来说并不容易,因为我目前是 WPF 初学者。
另一件事是我非常不喜欢将位置传递给项目的方式。还有其他办法吗?
对于如何改进代码还有其他建议吗?
最佳答案
我自己解决了:D
<Window x:Class="DynTemplateTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="NormalItem">
<Rectangle Width="30" Height="30" Fill="Red"></Rectangle>
</DataTemplate>
<DataTemplate x:Key="SpecialItem">
<Rectangle Width="30" Height="30" Fill="Red"></Rectangle>
</DataTemplate>
<DataTemplate x:Key="ItemTemplate">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource NormalItem}" x:Name="ItemsContentControl" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSpecial}" Value="true">
<Setter TargetName="ItemsContentControl" Property="ContentTemplate" Value="{StaticResource SpecialItem}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Position}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<DockPanel LastChildFill="True">
<ContentPresenter
Content="{Binding Path=Items}"
ContentTemplate="{StaticResource ItemTemplate}"
>
</ContentPresenter>
</DockPanel>
</Window>
但是,对于替代方案或改进有什么想法吗?
关于wpf - WPF 中基于数据的模板选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1060108/