为什么我的自定义WPF RadioButton看起来不正确?

时间:2009-10-29 16:44:46

标签: wpf checkbox radio-button

我正在用复选框替换单选按钮的样式。我知道你会说这是一个坏主意,但它真的需要以这种方式工作。无论如何,使用Expression Blend我能够提取CheckBox的样式并将其应用于RadioButton。我唯一的问题是,当它绘制时,没有边界。谁能告诉我为什么?这是代码(自原始帖子以来已经更新):

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Royale"
Title="Customized RadioButton" Width="496" ShowInTaskbar="True" ResizeMode="NoResize" Height="105">
<Window.Resources>
    <SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F"/>

    <Style x:Key="RadioButtonCheckBoxStyle" TargetType="{x:Type RadioButton}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="#F4F4F4"/>
        <Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RadioButton}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                        <BulletDecorator Background="Transparent">
                            <BulletDecorator.Bullet>
                                <Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" IsChecked="{TemplateBinding IsChecked}" IsRound="false" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
                            </BulletDecorator.Bullet>
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
                        </BulletDecorator>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="HasContent" Value="true">
                            <Setter Property="Padding" Value="4,0,0,0"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<StackPanel>
    <CheckBox Height="16" Name="checkBox1" Width="120">CheckBox</CheckBox>
    <RadioButton Height="16" Name="radioButton1" Width="120">RadioButton</RadioButton>
    <RadioButton Content="RadioButton with CheckBox Style" Margin="4" Style="{DynamicResource RadioButtonCheckBoxStyle}" FocusVisualStyle="{x:Null}" GroupName="Header" IsChecked="False" IsEnabled="True" HorizontalAlignment="Center" />
</StackPanel>

alt text http://img260.imageshack.us/img260/65/33733770.jpg

要查看其显示方式,请将其粘贴到Visual Studio中。您将看到Customized RadioButton看起来不正确。它缺少CheckBox通常具有的常规3D效果。我不关心任何内容(我不会有任何内容)我只是希望它看起来像普通的CheckBox。

2 个答案:

答案 0 :(得分:2)

由于您要覆盖模板,因此您需要自己附加到类的属性。

以下列方式在模板中声明边框:

<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>

另外,你有一个小bug。你已经多次为你的风格定义了“BorderBrush”的setter。

修改:看到您的图片后,这是您真正的问题:

<Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" IsChecked="{TemplateBinding IsChecked}" IsRound="false" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>

你错过了子弹中的BorderThickness。它有效地将您的厚度设置为0,这就是您没有看到任何内容的原因。

答案 1 :(得分:0)

图像可能会有所帮助,但您希望边界在哪里?你期待整个内容的边界?根据您使用的模板,唯一的边界应该是复选标记所在的位置。如果您想在所有内容周围添加边框,则需要在Border中添加ControlTemplate,如下所示:

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                            <BulletDecorator Background="Transparent">
                                <BulletDecorator.Bullet>
                                    <Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" IsChecked="{TemplateBinding IsChecked}" IsRound="false" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"/>
                                </BulletDecorator.Bullet>
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignme    nt}" RecognizesAccessKey="True"/>
                        </BulletDecorator>
                            <ControlTemplate.Triggers>
                                    <Trigger Property="HasContent" Value="true">
                                    <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}"/>
                                    <Setter Property="Padding" Value="4,0,0,0"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>

附注:您已在复选框本身设置了FocusVisualStyle="{x:Null}",但您的模板会在其HasContent属性触发器中更改此属性。如果你真的不想要一个FocusVisualStyle,你应该删除那个setter。