如何在WPF单选按钮中设计类似复选框的样式

问题描述 投票:0回答:3

我想要一个类似于复选框的单选按钮,所以我在字典文件中定义了一个样式,例如:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:WpfCheckBoxLikeRadiobutton">

<Style x:Key="MyRadioButton" TargetType="{x:Type RadioButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type RadioButton}">
                <Grid>
                    <CheckBox
                        IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                        Path=IsChecked, Mode=TwoWay}"
                        IsHitTestVisible="False" />
                    <CheckBox
                    IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                    Path=IsChecked, Mode=TwoWay}" Opacity="0"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

并将其合并到 app.xaml 文件中,如下所示

<Application x:Class="WpfCheckBoxLikeRadiobutton.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:WpfCheckBoxLikeRadiobutton"
         StartupUri="MainWindow.xaml">
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Dictionary1.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

然后在我的窗口中使用它

<GroupBox Margin="5" Padding="5">
        <StackPanel >
            <CheckBox Content="this is checkbox" />
            <RadioButton Content="this is first radio button" Style="{DynamicResource MyRadioButton}"/>
            <RadioButton Content="this is Second radio button" Style="{DynamicResource MyRadioButton}"/>
            <RadioButton Content="this is third radio button" Style="{DynamicResource MyRadioButton}"/>
        </StackPanel>
    </GroupBox>

但是为单选按钮指定样式后,该内容将消失。 我的风格有什么问题吗?

wpf xaml templates checkbox styles
3个回答
9
投票

发生这种情况是因为您忽略了自己的控制内容

ControlTemplate
。你的风格应该是这样的:

<Style x:Key="MyRadioButton" TargetType="{x:Type RadioButton}">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type RadioButton}">
            <Grid>
                <CheckBox
                    IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                                Path=IsChecked, Mode=TwoWay}"
                    IsHitTestVisible="False" Content="{TemplateBinding Content}" />
                <CheckBox
                IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                            Path=IsChecked, Mode=TwoWay}"   
                Content="{TemplateBinding Content}" Opacity="0"/>
            </Grid>
        </ControlTemplate>
    </Setter.Value>
</Setter>


0
投票

我认为你甚至可以做得更简单,让它看起来更好,只需右键单击 --> EditStyle 并用模板中的矩形替换每个椭圆。有很多动画你不会因为这种方式而丢失。

这就是我所做的,看起来不错,如果你愿意,你也可以从复选框样式中复制“CheckIcon”,使其看起来完全像一个复选框。


0
投票

除了 Verbon 的答案之外,我还有一种样式,其中复选框看起来像单选按钮。

        <Style x:Key="CheckBoxRadioButtonStyle" TargetType="CheckBox">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
            <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
            <Setter Property="MinWidth" Value="30"/>
            <Setter Property="UseSystemFocusVisuals" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="CheckBox">
                        <Grid BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="PointerOver">
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="OuterEllipse">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="CheckOuterEllipse">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="CheckOuterEllipse">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightTransparentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="CheckGlyph">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseMediumBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="OuterEllipse">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="CheckOuterEllipse">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="CheckOuterEllipse">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="CheckGlyph">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="CheckStates">
                                    <VisualState x:Name="Checked">
                                        <Storyboard>
                                            <DoubleAnimation Duration="1" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckGlyph"/>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="OuterEllipse"/>
                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckOuterEllipse"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unchecked">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="OuterEllipse"/>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckOuterEllipse"/>
                                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="CheckGlyph"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Indeterminate"/>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid Height="32" VerticalAlignment="Top">
                                <Ellipse x:Name="OuterEllipse" Height="20" Fill="Green" Stroke="Green" Opacity="0" StrokeThickness="{ThemeResource RadioButtonBorderThemeThickness}" UseLayoutRounding="False" Width="20"/>
                                <Ellipse x:Name="CheckOuterEllipse" Fill="White" Height="20" Opacity="1" Stroke="Gray" StrokeThickness="{ThemeResource RadioButtonBorderThemeThickness}" UseLayoutRounding="False" Width="20"/>
                                <Ellipse x:Name="CheckGlyph" Fill="White" Height="12" Opacity="1" UseLayoutRounding="False" Width="12"/>
                            </Grid>
                            <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" Content="{TemplateBinding Content}" Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" TextWrapping="Wrap" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

然后将上面的样式合并到Verbon的样式中:

    <Grid>
                            <CheckBox  IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=TwoWay}" IsHitTestVisible="False" Content="{TemplateBinding Content}" Style="{StaticResource CheckBoxRadioButtonStyle}"/>
                            <CheckBox  IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=TwoWay}" Content="{TemplateBinding Content}" Opacity="0" Style="{StaticResource CheckBoxRadioButtonStyle}"/>
                        </Grid>
© www.soinside.com 2019 - 2024. All rights reserved.