自定义wpf中切换按钮的切换状态

时间:2009-10-07 16:02:28

标签: c# wpf controls togglebutton

我想在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>

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

4 个答案:

答案 0 :(得分: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是列表中的项目数。)

答案 1 :(得分:5)

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

这里给你个性化,只需要在你的C:\目录下放一个名为“on.jpg”的图像和另一个名为“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>

答案 2 :(得分:3)

这是一个包含3个图像和弹出窗口的ToggleButton:

  1. IsChecked = false时的图像。
  2. IsChecked = true时的图像。
  3. IsMouseOver = true时的图像。
  4. 图像作为BitmapImage存储在资源中,以避免在trigers上更改Visual。

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

    当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>
    

答案 3 :(得分:1)

像Drew Noakes说的那样,在我的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>

很简单,我将触发器移动到数据模板中。不知道这是你的正确答案。似乎在起作用