在单选按钮 WPF C# 中更改路径填充

Change Path Fill inside radio button 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), RelativeSource={RelativeSource FindAncestor, 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}}}"

你能帮忙吗?

I read on internet that to make a custom style of radio button you need to create a toggle button style.

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

为了解决您的问题,您应该为 RadioButton 创建一个合适的样式。没有必要在其中使用切换按钮,但即使您愿意,触发器也会在控件模板中定义。此外,您定义的 ToggleButton 的样式是 implicit (没有 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,0,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,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 作为选项标记并将您的自定义颜色应用于各个状态。

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

如果您想要自定义 Content 和选项标记而不创建不同的样式,您将必须创建一个派生自 RadioButton 的自定义单选按钮控件并公开一个依赖项 属性指定选项标记内容。然后就可以在控件模板中绑定了,不过那是另外一个问题了。