2009-10-07 127 views
8

我想自定义wpf中切换按钮的切换状态。我想在开启按钮时将图像设置为切换按钮,并在关闭时设置另一个图像。为此,我想到了使用触发器。这就是我最终做的,自定义wpf中的切换按钮的切换状态

<Window ...> 
    <Window.Resources> 
     <Image x:Key="OnImage" Source="C:\ON.jpg" /> 
     <Image x:Key="OffImage" Source="C:\OFF.jpg" /> 
     <Style x:Key="OnOffToggleImageStyle" TargetType="ToggleButton"> 
      <Style.Triggers> 
       <Trigger Property="IsChecked" Value="True"> 
        <Setter Property="Content" Value="{StaticResource OnImage}" /> 
       </Trigger> 
       <Trigger Property="IsChecked" Value="False"> 
        <Setter Property="Content" Value="{StaticResource OffImage}" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Window.Resources> 
    <ListBox> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       ... 
       <ToggleButton IsChecked="{Binding Status}" Width="100" Height="35" Style="{StaticResource OnOffToggleImageStyle}" /> 
       ... 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
</Window> 

上面的代码似乎只适用于列表框中的两个项目。如果多个项目具有绑定值,状态为true,则不起作用(仅适用于一个此类项目)。请告诉我我是否正朝着正确的方向前进。另外告诉我其他方法来实现这一点。

回答

10

这里的问题是因为您正在使用Image资源。您资源中的Image是控件的具体实例。它一次只能在一个地方。所以,当你的列表中有多个项目......

这应该为你工作:

<Style x:Key="OnOffToggleImageStyle" TargetType="ToggleButton"> 
<Style.Triggers> 
    <Trigger Property="IsChecked" Value="True"> 
    <Setter Property="Content"> 
     <Setter.Value> 
     <Image Source="C:\ON.jpg" /> 
     </Setter.Value> 
    </Setter> 
    </Trigger> 
    <Trigger Property="IsChecked" Value="False"> 
    <Setter Property="Content"> 
     <Setter.Value> 
     <Image Source="C:\OFF.jpg" /> 
     </Setter.Value> 
    </Setter> 
    </Trigger> 
</Style.Triggers> 
</Style> 

注意,您可以通过使用ImageSource在每个图像文件提高该性能的资源,然后参考Image。这实际上意味着每张图片只能从磁盘加载一次,而不是2 * N次(其中N是列表中的项目数)。

+3

上面代码段抛出异常。以下是详细信息, 无法将'System.Windows.Controls.Image'类型的内容添加到'System.Object'类型的对象。标记文件 – sudarsanyes 2009-10-07 16:22:41

+1

中的对象'System.Windows.Controls.Image'出错这非常有帮助。 :)谢谢.. – 2011-03-30 07:43:39

5

This answer会帮助您。在那里,我使用了一个ToggleButton并将其设置为TreeView中的ToggleButton(用于展开折叠节点的+/- 部分)。您只需更改绘制 - 和+号的路径,即可显示图像。

这里去个性化你的,只是把所谓的“on.jpg”的图像,另一个你的C下称“off.jpg”:\目录下,它应该工作的只是复制/粘贴到你的窗口:

<Window.Resources> 
     <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> 
     <ControlTemplate x:Key="toggleButtonTemplate" TargetType="ToggleButton"> 
      <Grid 
       Width="15" 
       Height="13" 
       Background="Transparent"> 
       <Image x:Name="ExpandImage" 
         Source="C:\off.jpg" 
         HorizontalAlignment="Left" 
         VerticalAlignment="Center" 
         Margin="1,1,1,1" />      
      </Grid> 
      <ControlTemplate.Triggers> 
       <Trigger Property="IsChecked" 
        Value="True"> 
        <Setter Property="Source" 
         TargetName="ExpandImage" 
         Value="C:\on.jpg"/> 
       </Trigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 
     <Style x:Key="toggleButtonStyle" TargetType="ToggleButton"> 
      <Setter Property="Template" Value="{StaticResource toggleButtonTemplate}" /> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <ToggleButton Style="{StaticResource toggleButtonStyle}" /> 
    </Grid> 
+0

什么是ExpandImage在上面的片段?没有称为ExpandImage的触发器类型。你能检查一下吗? – sudarsanyes 2009-10-07 16:47:40

+0

模板内部图像的名称:。这样ControlTemplate就可以访问它并修改其属性: Carlo 2009-10-07 17:13:28

+0

对不起,我没有完整阅读。谢谢。它的工作现在。为什么它不适合我?为什么只有一次? – sudarsanyes 2009-10-07 17:32:34

1

像德鲁诺克斯说的,在我的snippte中只有两个图像。所以只有两个项目正常工作。我用下面的代码解决了这个问题。

<ToggleButton 
    Grid.Row="0" Grid.Column="2" Grid.RowSpan="2" 
    VerticalAlignment="Center" HorizontalAlignment="Center" 
    IsChecked="{Binding Status}" 
    Width="100" Height="35"> 
    <ToggleButton.Resources> 
    <Image x:Key="OnImage" Source="C:\ON.jpg" /> 
    <Image x:Key="OffImage" Source="C:\OFF.jpg" /> 
    </ToggleButton.Resources> 
    <ToggleButton.Style> 
    <Style TargetType="ToggleButton"> 
     <Style.Triggers> 
     <Trigger Property="IsChecked" Value="True"> 
      <Setter Property="Content" Value="{StaticResource OnImage}"> 
      </Setter> 
     </Trigger> 
     <Trigger Property="IsChecked" Value="False"> 
      <Setter Property="Content" Value="{StaticResource OffImage}"> 
      </Setter> 
     </Trigger> 
     </Style.Triggers> 
    </Style> 
    </ToggleButton.Style> 
</ToggleButton> 

简单,我将触发器移入数据模板中。不知道这是否是你正确的答案。似乎是工作

+0

有趣的是,我得到错误“System.Windows.Controls.Image”不是'Setter.Value'的有效值;从Visual或ContentElement派生的值不受支持。 – 2010-02-02 23:47:40

+0

感谢您发表该答案。 – Tony 2011-11-04 00:06:04

3

这里是一个切换按钮3倍的图像和一个弹出:

  1. 一种图像时器isChecked =假。
  2. IsChecked = true时的图像。
  3. IsMouseOver = true时的图像。

图像以BitmapImage的形式存储在资源中,以避免更改视频对象。

必须将图像文件添加到资源中,然后添加到项目中“Resoruces”文件夹的文件必须标记为BuildAction =资源

当ToggleButton IsEnabled = false时,它也对Image控件应用不透明度;

代码:

<ToggleButton 
     x:Name="btnToggleImage" 
     Margin="5" 
     Width="50"    
     Height="50" 
     > 
     <ToggleButton.Resources> 
      <BitmapImage x:Key="imgNormal" UriSource="/YOURPROJECTNAME;component/Resources/YourUncheckedImage.png"/> 
      <BitmapImage x:Key="imgHover" UriSource="/YOURPROJECTNAME;component/Resources/YourHoverImage.png"/> 
      <BitmapImage x:Key="imgChecked" UriSource="/YOURPROJECTNAME;component/Resources/YourCheckedImage.png"/> 
     </ToggleButton.Resources> 

     <ToggleButton.Style> 
      <Style TargetType="ToggleButton"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="ToggleButton"> 
          <Image 
           x:Name="PART_Image" 
           Source="{StaticResource imgNormal}" 
           /> 
          <ControlTemplate.Triggers> 
           <Trigger Property="IsChecked" Value="true"> 
            <Setter TargetName="PART_Image" Property="Source" Value="{StaticResource imgChecked}"/> 
           </Trigger> 
           <Trigger Property="IsMouseOver" Value="true"> 
            <Setter TargetName="PART_Image" Property="Source" Value="{StaticResource imgHover}"/> 
           </Trigger> 
           <Trigger Property="IsEnabled" Value="false"> 
            <Setter TargetName="PART_Image" Property="Opacity" Value="0.6"/> 
           </Trigger> 
          </ControlTemplate.Triggers> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </ToggleButton.Style> 
    </ToggleButton>   

    <Popup 
     x:Name="popup1" 
     PlacementTarget="{Binding ElementName=btnToggleImage}" 
     PopupAnimation="Slide" 
     IsOpen="{Binding ElementName=btnToggleImage, Path=IsChecked, Mode=TwoWay}" 
     StaysOpen="False" 
     MinWidth="{Binding ElementName=btnToggleImage, Path=Width}"> 
     <Grid Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"> 
      <!--<ItemsPresenter/>--> 
      <Label Content="Hello Wolrd!"/> 
     </Grid> 
    </Popup>