项目场景:
我有一个为TreeViewItem设计的Style,里面包含一个ToggleButton
,我想为这个控件添加两张图片作为控件的图标,并且根据IsChecked
的True
和False
状态切换这两张图片。
问题描述
我写了两个Trigger分别放上了两张图片的路径,并将生成操作设为Resource,运行后图片能够加载上,也能够根据状态切换。但既然是Style那就是需要复用,在多添加了几个TreeViewItem后,出现了多个ToggleButton图标不能同时显示的问题。
<Style x:Key="DynamicToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="ToggleActived.ico" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="ToggleInactived.ico" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
原因分析:
由于所有控件只能存在一个图标,分析可能是图片资源不能共享,查看《WPF编程宝典》里面提到,可以设置资源的IsShared
属性
解决方案:
方案一
将Image提出作为资源,并将IsShared
设为False
<Image x:Key="ToggleActiveImg" x:Shared ="false" Source="ToggleActived.ico" Stretch="None" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image x:Key="ToggleInactiveImg" x:Shared ="false" Source="ToggleInactived.ico" Stretch="None" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Style x:Key="DynamicToggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="{StaticResource ToggleActiveImg}"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" Value="{StaticResource ToggleInactiveImg}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
方案二
将图片作为画刷,即可将画刷设为按钮背景
<ImageBrush x:Key="ToggleActiveImgBrush" x:Shared ="false" ImageSource="ToggleInactived.ico" Stretch="None"/>
<ImageBrush x:Key="ToggleInactiveImgBrush" x:Shared ="false" ImageSource="ToggleInactived.ico" Stretch="None"/>
然后将setter中的两句改为对background
的设置
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="{StaticResource ToggleActiveImgBrush}"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Opacity" Value="{StaticResource ButtonNormalOpacity}"/>
</Trigger>
</ControlTemplate.Triggers>