更改路径填充内部单选按钮WPF C#

问题描述

我在互联网上读到,要创建自定义样式的单选按钮,您需要创建一个切换按钮样式。

所以这是我的风格:

<Style targettype="{x:Type ToggleButton}">
   <Setter Property="Background" Value="{StaticResource MainorangeBrush}" />
   <Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
   <Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
   <Setter Property="Focusable" Value="False" />
   <Setter Property="Margin" Value="0" />
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate targettype="ToggleButton">
            <Border
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
               <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Border>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
   <Style.Triggers>
      <Trigger Property="IsMouSEOver" Value="True">
         <Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
         <Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
         <Setter Property="BorderBrush" Value="{StaticResource MainorangeBrush}" />
      </Trigger>
      <Trigger Property="Ispressed" Value="True">
         <Setter Property="Foreground" Value="{StaticResource MainorangeBrush}" />
         <Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
         <Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
      </Trigger>
      <Trigger Property="IsChecked" Value="True">
         <Setter Property="Foreground" Value="{StaticResource MainorangeBrush}" />
         <Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
         <Setter Property="BorderBrush" Value="{StaticResource MainorangeBrush}" />
      </Trigger>
      <Trigger Property="IsEnabled" Value="False">
         <Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
         <Setter Property="Background" Value="{StaticResource disableGrayBrush}" />
         <Setter Property="BorderBrush" Value="{StaticResource MainWhiteBrush}" />
      </Trigger>
   </Style.Triggers>
</Style>
<Style targettype="{x:Type RadioButton}">
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate>
            <ToggleButton Content="{Binding Path=(Content),RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type RadioButton}}}" IsChecked="{Binding Path=(IsChecked),AncestorType={x:Type RadioButton}}}" />
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

我仍然不太了解ContentTemplateContentPresenter。我知道内容呈现器适用于UI元素中的所有内容

所以我的问题是我想将填充设置为与切换按钮内的前景相同的颜色:

<RadioButton
   x:Name="Btn"
   Width="40"
   Height="40"
   HorizontalAlignment="Right"
   IsChecked="{Binding IsChecked}"
   ToolTip="Btn">
   <Path
      Width="30"
      Margin="2"
      HorizontalAlignment="Center"
      VerticalAlignment="Center"
      Data="F1 M 19.135,13.006 L 12.740,13.006 L 17.243,0.000 L 0.000,17.142 L 6.397,17.142 L 1.480,30.148 L 19.135,13.006 Z"
      Fill="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"
      Stretch="Uniform" />
</RadioButton>

此行不起作用:

Fill="{Binding Path=Foreground,RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"

你能帮忙吗?

解决方法

我在互联网上读到,要创建自定义样式的单选按钮,您需要创建一个切换按钮样式。

不。您必须为类型RadioButton创建样式。 RelativeSource绑定不起作用,因为它不会在控制模板内搜索祖先,因此将找不到ToggleButton

为了解决您的问题,您应该为RadioButton创建适当的样式。不必在其中使用切换按钮,但是即使您愿意,触发器也将在控制模板中定义。此外,您定义的ToggleButton的样式是隐式(没有x:Key),这将使其应用于范围中的每个切换按钮,而不仅仅是RadioButton,那不是您想要的。

我创建了一个示例样式,该样式看起来可能与您尝试的样式相似。

<Style x:Key="FocusVisual1">
   <Setter Property="Control.Template">
      <Setter.Value>
         <ControlTemplate>
            <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>
<Style x:Key="OptionMarkFocusVisual1">
   <Setter Property="Control.Template">
      <Setter.Value>
         <ControlTemplate>
            <Rectangle Margin="14,0" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>
<Style TargetType="{x:Type RadioButton}">
   <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/>
   <Setter Property="Background" Value="{StaticResource MainOrangeBrush}" />
   <Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
   <Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Focusable" Value="False" />
   <Setter Property="Margin" Value="0" />
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type RadioButton}">
            <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
               <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition Width="*"/>
               </Grid.ColumnDefinitions>
               <Border x:Name="radioButtonBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,1,2,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                  <Grid x:Name="markGrid" Margin="2">
                     <Path x:Name="optionMark"
                                 MinHeight="6"
                                 MinWidth="6"
                                 Margin="2"
                                 Opacity="0"
                                 HorizontalAlignment="Center"
                                 VerticalAlignment="Center"
                                 Data="F1 M 19.135,13.006 L 12.740,13.006 L 17.243,0.000 L 0.000,17.142 L 6.397,17.142 L 1.480,30.148 L 19.135,13.006 Z"
                                 Fill="{TemplateBinding Foreground}"
                                 Stretch="Uniform" />
                  </Grid>
               </Border>
               <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Grid>
            <ControlTemplate.Triggers>
               <Trigger Property="HasContent" Value="true">
                  <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual1}"/>
                  <Setter Property="Padding" Value="4,-1,0"/>
               </Trigger>
               <Trigger Property="IsMouseOver" Value="true">
                  <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
                  <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainOrangeBrush}"/>
                  <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainDarkerGrayBrush}"/>
               </Trigger>
               <Trigger Property="IsEnabled" Value="false">
                  <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource DisableGrayBrush}"/>
                  <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
                  <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainDarkerGrayBrush}"/>
               </Trigger>
               <Trigger Property="IsPressed" Value="true">
                  <Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
                  <Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainDarkerGrayBrush}"/>
                  <Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainOrangeBrush}"/>
               </Trigger>
               <Trigger Property="IsChecked" Value="true">
                  <Setter Property="Opacity" TargetName="optionMark" Value="1"/>
               </Trigger>
               <Trigger Property="IsChecked" Value="{x:Null}">
                  <Setter Property="Opacity" TargetName="optionMark" Value="0.56"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

结果如下所示。它仍然是一个单选按钮,但是将您的自定义Path作为选项标记,并将您的自定义颜色应用于相应的状态。

Radio Button Sample

在此示例中,Path嵌入在控制模板中,而Content嵌入在此处,文本 Test 仍然适用。您当然可以进一步自定义模板,使其适合您的要求。

如果您想自定义Content和选项标记而无需创建其他样式,则必须创建一个自RadioButton派生的自定义单选按钮控件,并公开依赖项属性以指定选项标记的内容。然后,您可以将其绑定到控件模板中,但这是另一个问题。