如何在WPF数据模板触发器中切换Polygon的Points集合?
问题:通过WPF数据模板触发器切换显示不同Polygon的顶点
我希望通过WPF数据模板触发器显示不同的Polygon(注:不用在意Circle的顶点集合,我知道它完全不像圆形 ;-))
我最初在资源中定义了两个Polygon和一个空Polygon:
<ContentControl.Resources> <Polygon x:Key="Circle" Grid.Column="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" Fill="DarkGray" Width="25" Height="25" Points=" 0,50 25,100 75,100" /> <Polygon x:Key="Hexagon" Grid.Column="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" Fill="DarkGray" Width="25" Height="25" Points=" 0,50 25,100 75,100 100,50 75,0 25,0 0,50" /> <Polygon Name="path" Grid.Column="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" Fill="DarkGray" Width="25" Height="25" /> </ContentControl.Resources>
然后尝试用数据模板触发器切换,但抛出运行时异常——因为我把整个Polygon对象赋值给了Points属性(它需要的是PointCollection):
<DataTemplate.Triggers> <DataTrigger Binding="{Binding SimulationType}" Value="{x:Static vm:SimulationType.ServerSimulated}"> <DataTrigger.Setters> <Setter TargetName="path" Property="Points" Value="{StaticResource Hexagon}"/> </DataTrigger.Setters> </DataTrigger> <DataTrigger Binding="{Binding SimulationType}" Value="{x:Static vm:SimulationType.ServerInSimulation}"> <DataTrigger.Setters> <Setter TargetName="path" Property="Points" Value="{StaticResource Circle}"/> </DataTrigger.Setters> </DataTrigger> </DataTemplate.Triggers>
我不清楚如何在XAML中定义PointCollection,也不知道如何通过触发器实现Polygon顶点的替换,请问该如何实现需求?
解决方案
有两种常用的实现方式,可根据需求选择:
方法一:定义PointCollection资源,切换Points属性
把原来的Polygon资源换成PointCollection,直接赋值给Polygon的Points属性:
<ContentControl.Resources> <!-- 定义顶点集合资源 --> <PointCollection x:Key="CirclePoints">0,50 25,100 75,100</PointCollection> <PointCollection x:Key="HexagonPoints">0,50 25,100 75,100 100,50 75,0 25,0 0,50</PointCollection> <!-- 共用的Polygon控件 --> <Polygon Name="path" Grid.Column="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" Fill="DarkGray" Width="25" Height="25" /> </ContentControl.Resources> <DataTemplate.Triggers> <DataTrigger Binding="{Binding SimulationType}" Value="{x:Static vm:SimulationType.ServerSimulated}"> <Setter TargetName="path" Property="Points" Value="{StaticResource HexagonPoints}"/> </DataTrigger> <DataTrigger Binding="{Binding SimulationType}" Value="{x:Static vm:SimulationType.ServerInSimulation}"> <Setter TargetName="path" Property="Points" Value="{StaticResource CirclePoints}"/> </DataTrigger> </DataTemplate.Triggers>
这种方法适合所有Polygon样式(Stroke、Fill、Size等)完全一致的场景,仅切换顶点集合。
方法二:触发器切换整个Polygon控件
如果后续需要不同样式(比如不同填充色、边框粗细),可以直接替换整个Polygon控件:
<ContentControl.Resources> <Polygon x:Key="Circle" Grid.Column="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" Fill="DarkGray" Width="25" Height="25" Points=" 0,50 25,100 75,100" /> <Polygon x:Key="Hexagon" Grid.Column="0" Stretch="Fill" Stroke="Black" StrokeThickness="1" Fill="DarkGray" Width="25" Height="25" Points=" 0,50 25,100 75,100 100,50 75,0 25,0 0,50" /> </ContentControl.Resources> <!-- 用ContentControl承载图形,通过触发器切换Content --> <ContentControl x:Name="shapeContainer" Content="{StaticResource Circle}"/> <DataTemplate.Triggers> <DataTrigger Binding="{Binding SimulationType}" Value="{x:Static vm:SimulationType.ServerSimulated}"> <Setter TargetName="shapeContainer" Property="Content" Value="{StaticResource Hexagon}"/> </DataTrigger> <DataTrigger Binding="{Binding SimulationType}" Value="{x:Static vm:SimulationType.ServerInSimulation}"> <Setter TargetName="shapeContainer" Property="Content" Value="{StaticResource Circle}"/> </DataTrigger> </DataTemplate.Triggers>
这种方法更灵活,每个Polygon可独立设置样式,触发器仅负责替换整个控件。
内容的提问来源于stack exchange,提问作者bas
相关产品推荐
相关产品推荐

