2

我一直在使用带有 ToggleButton 作为控件模板的自定义 RadioButton 控件。这是 xaml 的样子:

    <RadioButton.Template>
        <ControlTemplate>
            <ToggleButton x:Name="tb" IsChecked="{Binding IsChecked, Mode=TwoWay, 
                                RelativeSource={RelativeSource TemplatedParent}}" 
                                      Content="{TemplateBinding RadioButton.Content}"
                          PreviewMouseDown="tb_PreviewMouseDown">
            </ToggleButton>
        </ControlTemplate>
    </RadioButton.Template>

它一直运行良好,除非我尝试以编程方式设置按钮的 IsChecked 属性或与它进行绑定。然后应该检查的按钮在视觉上没有响应 - 它似乎没有被按下,并且 Aero 鼠标悬停效果也没有出现。Clicked 事件处理程序仍然有效,当我检查 RadioButton 和 ControlTemplate 的切换按钮的值时,它们的 IsChecked 属性都是 true。艾米,我装订有问题吗?有任何想法吗?

这是我如何在应用程序中使用它的示例:

<local:RadioToggleButton Content="1Hr" GroupName="Interval" x:Name="oneHrBtn" 
IsChecked="{BindingPath=oneHrBtnIsChecked, Mode=TwoWay}" Margin="2 5 3 5" 
IsEnabled="{Binding Path=oneHrBtnIsEnabled, Mode=TwoWay}"/>
4

3 回答 3

1

你所拥有的很奇怪。RadioButton 类派生自 ToggleButton。因此,您可以有效地将按钮放入按钮中。您是否只是想让 RadioButton 看起来像一个 ToggleButton?如果是这样,为什么不直接使用 ToggleButton 呢?

如果您想让 RadioButton 看起来像 ToggleButton 以便您可以使用 GroupName 功能,那么您必须复制 ToggleButton 控件模板并使用它(不要在控件模板中嵌入 ToggleButton)。

您可以从这里获取默认模板。然后搜索 ToggleButton 样式并将其复制为 ControlTemplate。

编辑:

以下示例显示了如何做到这一点。您只需添加对 PresentationFramework.Aero 的引用。

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

        <LinearGradientBrush x:Key="ButtonNormalBackground" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStop Color="#F3F3F3" Offset="0" />
                <GradientStop Color="#EBEBEB" Offset="0.5" />
                <GradientStop Color="#DDDDDD" Offset="0.5" />
                <GradientStop Color="#CDCDCD" Offset="1" />
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
        <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070" />

            <Style x:Key="ButtonFocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" StrokeThickness="1" Stroke="Black" StrokeDashArray="1 2" SnapsToDevicePixels="true" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
            <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}" />
            <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Padding" Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <theme:ButtonChrome Name="Chrome" Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
                                RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"
                                SnapsToDevicePixels="true">
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </theme:ButtonChrome>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsKeyboardFocused" Value="true">
                                <Setter TargetName="Chrome" Property="RenderDefaulted" Value="true" />
                            </Trigger>
                            <Trigger Property="ToggleButton.IsChecked" Value="true">
                                <Setter TargetName="Chrome" Property="RenderPressed" Value="true" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="#ADADAD" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <StackPanel>
        <RadioButton GroupName="TestGroup">Option 1</RadioButton>
        <RadioButton GroupName="TestGroup">Option 2</RadioButton>
    </StackPanel>
</Window>
于 2011-03-21T18:27:35.780 回答
1

如果您想要的只是RadioButton看起来像 a 的 a ToggleButton,您实际上可以按类型将 ToggleButton 的样式隐式引用为静态资源:

<RadioButton Style="{StaticResource {x:Type ToggleButton}}" />

这似乎可行,因为 RadioButton 是 ToggleButton 的后代。因此,例如,您不能使用{StaticResource {x:Type ComboBox}}.

我无法找到任何使用;x:Type作为资源的文档Style。我很想看看它,如果那里有人知道在哪里看的话。

于 2016-01-11T00:06:21.043 回答
0

所以我的自定义 RadioToggleButton 控件的问题确实是由非常奇怪的东西引起的。我将在下面描述我的解决方案,不是因为我希望其他人遇到这个特定问题,而是作为一个似乎与问题无关的解决方案示例。

包含按钮组的 GroupBox 的 IsEnabled 属性有一个绑定。这种绑定似乎工作正常,在适当的时候启用和禁用所有内部控制。但是一旦我删除了这个绑定,我上面描述的问题就消失了。这并不理想,但我认为我在这个问题上花了太多时间,所以我将各个控件的 IsEnabled 属性绑定到 GroupBox 绑定到的相同属性,现在至少我有了我的行为通缉。

于 2011-03-23T15:39:19.723 回答