如何触发 Validation.HasError 更改复选框背景颜色?

How to trigger on Validation.HasError to change checkbox background color?

我在 XAML 中有一个复选框:

<Style TargetType="{x:Type CheckBox}">
        <Setter Property="Height" Value="14" />
        <Setter Property="FontSize" Value="12" />
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="Background" Value="Red"/>
            </Trigger>
        </Style.Triggers>
    </Style>


<CheckBox  Content="Cash Only" 
              HorizontalAlignment="Left" Margin="158,0,0,264" VerticalAlignment="Bottom" Width="83" IsThreeState="True" >
        <CheckBox.IsChecked>
            <Binding Path="ServiceBilling.CashOnly">
                <Binding.ValidationRules>
                    <h:Not_Null_Rule ValidatesOnTargetUpdated="True"/>
                </Binding.ValidationRules>
            </Binding>
        </CheckBox.IsChecked>
    </CheckBox>

如果复选框 IsChecked 属性 为空,Not_Null_Rule 正确 returns 为假,否则为真。

但是,当为 null 时,复选框会在框内显示一个灰色的复选标记。该框有红色边框,但未填充红色。

我做错了什么?我希望框为空时填充红色。

TIA

您可以使用这种风格来完成任务

您需要根据需要更改颜色

<Style TargetType="CheckBox" x:Key="CircleCheckbox">
        <Setter Property="Cursor" Value="Hand"></Setter>   
        <Setter Property="Content" Value=""></Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">                   
                    <Grid>                     
                        <Ellipse x:Name="outerEllipse">
                            <Ellipse.Fill>
                                <RadialGradientBrush>
                                    <GradientStop Offset="0" Color="Red"/>
                                    <GradientStop Offset="0.88" Color="LightCoral"/>
                                    <GradientStop Offset="1" Color="DarkRed"/>
                                </RadialGradientBrush>
                            </Ellipse.Fill>
                        </Ellipse>
                        <Ellipse Margin="10" x:Name="highlightCircle" >
                            <Ellipse.Fill >
                                <LinearGradientBrush >
                                    <GradientStop Offset="0" Color="Green"/>
                                    <GradientStop Offset="0.5" Color="LightGreen"/>
                                    <GradientStop Offset="1" Color="DarkGreen"/>
                                </LinearGradientBrush>
                            </Ellipse.Fill>
                        </Ellipse>
                        <ContentPresenter x:Name="content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True">
                            <Setter TargetName="highlightCircle" Property="Fill">
                                <Setter.Value>
                                    <LinearGradientBrush StartPoint="0.3,0" EndPoint="0.7,1">
                                        <GradientStop Offset="0" Color="Green"/>
                                        <GradientStop Offset="0.5" Color="LightGreen"/>
                                        <GradientStop Offset="1" Color="DarkGreen"/>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                            <Setter TargetName="outerEllipse" Property="Fill">
                                <Setter.Value>
                                    <RadialGradientBrush>
                                        <GradientStop Offset="0" Color="Green"/>
                                        <GradientStop Offset="0.88" Color="LightGreen"/>
                                        <GradientStop Offset="1" Color="DarkGreen"/>
                                    </RadialGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="False">
                            <Setter TargetName="highlightCircle" Property="Fill">
                                <Setter.Value>
                                    <LinearGradientBrush StartPoint="0.3,0" EndPoint="0.7,1">
                                        <GradientStop Offset="0" Color="Red"/>
                                        <GradientStop Offset="0.5" Color="LightCoral"/>
                                        <GradientStop Offset="1" Color="DarkRed"/>
                                    </LinearGradientBrush>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>  

您还可以查看 Default Template of CheckBox 以更好地了解您想对复选框做什么

任何感兴趣的人,这个新手问题的答案比第一次出现时要复杂得多。

  1. 在研究复选框样式时,不存在对本身包含在 BulletDecorator 中的边框背景的依赖性 属性。因此,唯一的方法就是按照@MohitShrivastava 的建议,将默认样式替换为 OverridesDefaultStyle。 See Customizing the Checkbox
  2. 看来验证最终归结为 AdornedElementPlaceholder,AFAIK 不会公开所持有元素的任何属性。See How to apply style to an adorned element

所以,代替更好的想法,这里是我的工作代码。欢迎提出更好的建议。

 <ControlTemplate x:Key="validationTemplate">
            <DockPanel LastChildFill="True">
                <TextBlock DockPanel.Dock="Right" Foreground="Red" FontSize="12pt">!!!</TextBlock>
                <TextBlock DockPanel.Dock="Left" Foreground="Red" FontSize="12pt">!!!</TextBlock>
                <Border BorderBrush="Red" BorderThickness="1">
                    <AdornedElementPlaceholder/>
                </Border>
            </DockPanel>
        </ControlTemplate>

 <CheckBox  
            Content="Cash Only" HorizontalAlignment="Left" Margin="202,0,0,264" VerticalAlignment="Bottom" 
            Width="108" FontSize="16"
            Style="{StaticResource WarningCheckbox}"  Validation.ErrorTemplate="{DynamicResource validationTemplate}"
             >
            <CheckBox.IsChecked>
                <Binding Path="ServiceBilling.CashOnly" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <h:Not_Null_Rule ValidatesOnTargetUpdated="True"/>
                    </Binding.ValidationRules>
                </Binding>
            </CheckBox.IsChecked>

        </CheckBox>

 <!--Warning CheckBox to show Red when null-->
  <Style x:Key="WarningCheckbox" TargetType="CheckBox">
    <Setter Property="SnapsToDevicePixels"    Value="False" />
    <Setter Property="OverridesDefaultStyle"  Value="true" />
    <Setter Property="FocusVisualStyle"       Value="{x:Null}" />
    <Setter Property="BorderBrush"            Value="Black" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="CheckBox">
          <BulletDecorator Background="Transparent">
            <BulletDecorator.Bullet>
              <Border x:Name="Border"
                        Width="18"
                        Height="18"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="1"
                        ClipToBounds="True">
                <Border.Effect>
                  <DropShadowEffect BlurRadius="5" ShadowDepth="2" />
                </Border.Effect>
                <Path x:Name="CheckMark"
                        Width="18"
                        Height="18"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Data="M 0 0 L 8 8 M 0 8 L 8 0"
                        Stretch="Fill"
                        Stroke="Black"
                        StrokeEndLineCap="Round"
                        StrokeStartLineCap="Round"
                        StrokeThickness="2" />
              </Border>
           </BulletDecorator.Bullet>
               <ContentPresenter Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" RecognizesAccessKey="True" />
          </BulletDecorator>
          <ControlTemplate.Triggers>
            <Trigger Property="IsChecked" Value="{x:Null}">
                    <Setter TargetName="CheckMark" Property="Stroke" Value="Red" />
                    <Setter TargetName="Border" Property="Background" Value="Red" />
            </Trigger>
            <Trigger Property="IsChecked" Value="false">
                <Setter TargetName="CheckMark" Property="Visibility" Value="Hidden" />
                <Setter TargetName="Border" Property="Background" Value="White" />
            </Trigger>
            <Trigger Property="IsChecked" Value="true">
              <Setter TargetName="CheckMark" Property="Stroke" Value="Black" />
              <Setter TargetName="CheckMark" Property="Visibility" Value="Visible" />
              <Setter TargetName="Border" Property="Background" Value="White" />
            </Trigger>

            <!--
            <Trigger Property="IsFocused" Value="true">
              <Setter Property="BorderBrush" Value="White" />
            </Trigger>-->
            <Trigger Property="IsEnabled" Value="false">
              <Setter Property="BorderBrush" Value="Gray" />
              <Setter TargetName="CheckMark" Property="Stroke" Value="Gray" />
            </Trigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>