概述WPF中的切换按钮

时间:2011-07-26 23:25:14

标签: wpf styles togglebutton

我有一些切换按钮可以控制某些标签的可见性。按钮的样式使其在按下时变为蓝色,在没有时变为灰色。问题是当按下一个切换按钮时,第一个切换按钮将切换回灰色但具有蓝色轮廓。如果选择了其他控件(不是其中一个切换按钮),按钮将变为灰色而没有蓝色轮廓。我不想要蓝色轮廓。

我的风格是:

<Style x:Key="TabToggleButtonStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Background" Value="lightGray"/>
    <Setter Property="Margin" Value="3" />
    <Setter Property="Padding" Value="7,2,7,2" />
    <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Setter Property="Background" Value="#FF41B8F2" />
        </Trigger>
    </Style.Triggers>
</Style>

切换:

<DockPanel LastChildFill="False">
  <ToggleButton
      DockPanel.Dock="Right"
      Style="{StaticResource TabToggleButtonStyle}"
      Click="BtnOneClick"
      IsChecked="{Binding ElementName=_mainTabControl, Path=BtnOneTab.IsSelected}"
      Content="Agent Info"/>

    <ToggleButton
      DockPanel.Dock="Right"
      Style="{StaticResource TabToggleButtonStyle}"
      Click="BtnTwoClick"
      IsChecked="{Binding ElementName=_mainTabControl, Path=BtnTwoTab.IsSelected}"
      Content="Help"/>
</DockPanel>

点击命令在标签上设置IsSelected = true

3 个答案:

答案 0 :(得分:3)

我认为您的问题是ToggleButton的模板正在使用ButtonChrome来设置可能的状态,例如IsKeyboardFocused

因此,当您取消选中ToggleButton时,它仍然会有键盘焦点(因为您只是点击它),所以它仍然会被设置为样式。

ToggleButton的默认模板如下所示

<ControlTemplate TargetType="{x:Type ToggleButton}">
    <MS_Themes:ButtonChrome x:Name="Chrome"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            Background="{TemplateBinding Background}"
                            RenderMouseOver="{TemplateBinding IsMouseOver}"
                            RenderPressed="{TemplateBinding IsPressed}"
                            RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
                            SnapsToDevicePixels="true">
        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          Margin="{TemplateBinding Padding}"
                          RecognizesAccessKey="True"
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
    </MS_Themes:ButtonChrome>
    <ControlTemplate.Triggers>
        <Trigger Property="IsKeyboardFocused" Value="true">
            <Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="true">
            <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="#ADADAD"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

删除IsKeyboardFocused触发器可以解决您的问题(这还需要您添加对PresentationFramework.Aero的引用)。但既然你不能只改变模板的一部分(这是一个全有或全无的交易),你将不得不重写它

所以ToggleButton样式将是

<Style x:Key="TabToggleButtonStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="Background" Value="lightGray"/>
    <Setter Property="Margin" Value="3" />
    <Setter Property="Padding" Value="7,2,7,2" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}"
                             xmlns:MS_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
                <MS_Themes:ButtonChrome x:Name="Chrome"
                                        BorderBrush="{TemplateBinding BorderBrush}"
                                        Background="{TemplateBinding Background}"
                                        RenderMouseOver="{TemplateBinding IsMouseOver}"
                                        RenderPressed="{TemplateBinding IsPressed}"
                                        RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
                                        SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                        Margin="{TemplateBinding Padding}"
                                        RecognizesAccessKey="True"
                                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </MS_Themes:ButtonChrome>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="#ADADAD"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Setter Property="Background" Value="#FF41B8F2" />
        </Trigger>
    </Style.Triggers>
</Style>

答案 1 :(得分:2)

最有可能的问题是Focus Visual Style。您可以通过将此构造添加到您的资源来摆脱它:

<!-- StyleNoFocusRect -->
<Style x:Key="StyleNoFocusRect">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Control}">
                <Canvas></Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

然后将其添加到您的ToggleButton样式:

<Setter Property="FocusVisualStyle" Value="{StaticResource StyleNoFocusRect}"/>

那应该摆脱你的蓝色轮廓。

答案 2 :(得分:0)

在.net 4.0中,我刚刚添加了这个

<Style TargetType="ToggleButton">
    <Setter Property="Focusable" Value="False" />
</Style>

当我切换另一个按钮时,它删除了轮廓蓝色,但按钮无法通过键盘进行对焦。