2011-01-12 27 views
14

Tôi muốn tạo kiểu cho trạng thái không xác định của hộp kiểm WPF. Chúng tôi có một kiểm soát treeview với hộp kiểm, và chúng tôi muốn trạng thái không xác định để đại diện cho một số hậu duệ được kiểm tra và một số được bỏ chọn.Tạo kiểu cho trạng thái không xác định của hộp kiểm WPF

Giải pháp tôi thấy ở mọi nơi là ghi đè mẫu kiểm soát mặc định cho hộp kiểm và thực hiện những gì tôi cần làm.

Tôi có hai vấn đề với điều đó:

  1. tôi không thể tìm thấy sự kiểm soát mẫu cho một hộp kiểm Aero bình thường. Điều này một: http://msdn.microsoft.com/en-us/library/ms752319.aspx trông có vẻ ngốc nghếch.

  2. Mẫu kiểm soát tôi nhận được từ Expression Blend có phần tử BulletChrome trong đó và tôi không thể tìm ra việc cần làm với điều đó.

Vì vậy, không ai biết nơi để có được một mẫu kiểm soát hộp trông "bình thường" hoặc là có một cách dễ dàng hơn để chỉ phong cách trạng thái không xác định bởi chính nó?

Tôi chắc chắn có một cách dễ dàng tôi chỉ nhìn ... Phải không?

+0

tôi có cảm giác đó không phải là dễ dàng như người ta có thể nghĩ rằng, có lẽ không thể thậm chí không cần xây dựng lại toàn bộ phong cách bulletchrome bằng tay ... –

+0

Đó là những gì tôi sợ, nhưng thậm chí sau đó - có ai có phong cách đó đã được xây dựng ở đâu đó không? Điều đó sẽ giúp đỡ vô cùng ... –

Trả lời

1

Bạn có thể sử dụng CheckBox phong cách từ chủ đề cổ điển nằm tại địa chỉ:

  • C:\Program Files (x86)\Microsoft Expression\Blend 4\SystemThemes\Wpf\classic.xaml

thực hiện này có Path đại diện cho dấu hộp kiểm gọi CheckMarkPath. Tôi chỉ đơn giản là thay thế Path này với một điền Rectangle để có được những kết quả này:

Checkboxes

0

Mã dưới đây là một hộp kiểm tra mẫu với ba trạng thái.

<Window x:Class="WpfApplication1.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" Height="300" Width="300"> 
<Window.Resources> 
    <!-- Focus Style --> 

    <SolidColorBrush x:Key="InputBackgroundFocused" Color="Orange"></SolidColorBrush> 

    <Style x:Key="CheckBoxFocusVisualStyle"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Border CornerRadius="2" Margin="0,0,4,3" BorderThickness="2" BorderBrush="{StaticResource InputBackgroundFocused}" Background="Transparent"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <!-- Fill Brushes --> 

    <LinearGradientBrush x:Key="NormalBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#FFF" Offset="0.0"/> 
       <GradientStop Color="#CCC" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="HorizontalNormalBrush" StartPoint="0,0" EndPoint="1,0"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#FFF" Offset="0.0"/> 
       <GradientStop Color="#CCC" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#FFF" Offset="0.0"/> 
       <GradientStop Color="#EEE" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="HorizontalLightBrush" StartPoint="0,0" EndPoint="1,0"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#FFF" Offset="0.0"/> 
       <GradientStop Color="#EEE" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#FFF" Offset="0.0"/> 
       <GradientStop Color="#AAA" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="PressedBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#BBB" Offset="0.0"/> 
       <GradientStop Color="#EEE" Offset="0.1"/> 
       <GradientStop Color="#EEE" Offset="0.9"/> 
       <GradientStop Color="#FFF" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" /> 

    <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" /> 

    <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" /> 

    <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" /> 

    <!-- Border Brushes --> 

    <LinearGradientBrush x:Key="NormalBorderBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#CCC" Offset="0.0"/> 
       <GradientStop Color="#444" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="HorizontalNormalBorderBrush" StartPoint="0,0" EndPoint="1,0"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#CCC" Offset="0.0"/> 
       <GradientStop Color="#444" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="DefaultedBorderBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#777" Offset="0.0"/> 
       <GradientStop Color="#000" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <LinearGradientBrush x:Key="PressedBorderBrush" StartPoint="0,0" EndPoint="0,1"> 
     <GradientBrush.GradientStops> 
      <GradientStopCollection> 
       <GradientStop Color="#444" Offset="0.0"/> 
       <GradientStop Color="#888" Offset="1.0"/> 
      </GradientStopCollection> 
     </GradientBrush.GradientStops> 
    </LinearGradientBrush> 

    <SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" /> 

    <SolidColorBrush x:Key="SolidBorderBrush" Color="#888" /> 

    <SolidColorBrush x:Key="LightBorderBrush" Color="#AAA" /> 

    <!-- Miscellaneous Brushes --> 
    <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> 

    <SolidColorBrush x:Key="LightColorBrush" Color="#DDD" /> 
    <Style TargetType="{x:Type CheckBox}"> 
     <Setter Property="SnapsToDevicePixels" Value="true"/> 
     <Setter Property="OverridesDefaultStyle" Value="true"/> 
     <Setter Property="FocusVisualStyle" Value="{DynamicResource CheckBoxFocusVisualStyle}" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="CheckBox"> 
        <BulletDecorator Background="Transparent"> 
         <BulletDecorator.Bullet> 
          <Border x:Name="Border" 
           Width="17" 
           Height="17" 
           CornerRadius="2" 
           Background="{StaticResource NormalBrush}" 
           BorderThickness="1" 
           BorderBrush="{StaticResource NormalBorderBrush}"> 
           <Path 
           Width="11" Height="11" 
           x:Name="CheckMark" 
           SnapsToDevicePixels="False" 
           Stroke="{StaticResource GlyphBrush}" 
           StrokeThickness="2" 
           Data="M 2,4 C 2,4 3,5 5,13 C 5,13 5,3 12,0" /> 
          </Border> 
         </BulletDecorator.Bullet> 
         <ContentPresenter Margin="4,0,0,0" 
          VerticalAlignment="Center" 
          HorizontalAlignment="Left" 
          RecognizesAccessKey="True"/> 
        </BulletDecorator> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsChecked" Value="false"> 
          <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/> 
         </Trigger> 
         <Trigger Property="IsChecked" Value="{x:Null}"> 
          <Setter TargetName="CheckMark" Property="Data" Value="M 0 7 L 7 0" /> 
         </Trigger> 
         <Trigger Property="IsMouseOver" Value="true"> 
          <Setter TargetName="Border" Property="Background" Value="{StaticResource DarkBrush}" /> 
         </Trigger> 
         <Trigger Property="IsPressed" Value="true"> 
          <Setter TargetName="Border" Property="Background" Value="{StaticResource PressedBrush}" /> 
          <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource PressedBorderBrush}" /> 
         </Trigger> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" /> 
          <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" /> 
          <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 

      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 
<Grid> 
    <StackPanel> 
    <CheckBox>Hello</CheckBox> 
     <CheckBox IsThreeState="True">asdfsdaf</CheckBox> 
     </StackPanel> 
</Grid> 

Các phần mềm tốt nhất để thay đổi giao diện hiện diện của các điều khiển là Expression Blend. Nếu bạn muốn thay đổi giao diện hiện tại và bạn phải sửa đổi Mẫu Điều khiển của điều khiển.

+0

Vẫn không giống như hộp kiểm Aero thông thường. Tôi thà mọi thứ vẫn giữ nguyên cho bất kỳ chủ đề nào mà HĐH đang sử dụng.Không, tôi muốn tất cả các hộp kiểm trông giống như chủ đề Aero. Như tôi đã đề cập trong câu hỏi của mình, tôi đã sử dụng Expression Blend, và nó không cung cấp cho bạn toàn bộ xaml cho Checkbox. Nó thực hiện rất nhiều phép thuật trong điều khiển BulletChrome. –

0

Một tùy chọn khác có thể là tạo kiểu cho nút chuyển đổi vì nó cũng có nhiều trạng thái. Trong các dự án trước đây, tôi đã tạo các nút bật/tắt tùy chỉnh với nhiều trạng thái trông và hoạt động như chekcbox. Tôi đã sử dụng pha trộn để thực hiện các thay đổi nhưng bằng cách sử dụng nút tggle làm cơ sở tôi có thể tạo giao diện tùy chỉnh hơn cho các trạng thái khác nhau của nút/chekcbox. Sử dụng nút chuyển đổi có thể bỏ qua rất nhiều vấn đề liên quan đến chrome được kiểm soát chekcbox chuẩn.

0

Bạn có nghĩ về việc sử dụng SimpleStyles làm cơ sở để kiểm soát không?

ExpressionSimpleStyles

Bằng cách chọn kiểm soát này từ bảng điều khiển tài sản, Expression Blend sẽ đặt một dictonary tài nguyên mới trong dự án của bạn mà bạn có thể sử dụng để thay đổi phong cách như bạn xin vui lòng.Có thể là điểm khởi đầu tốt hơn là cố gắng xâm nhập vào Chrome cho hộp kiểm chuẩn.

+0

Tôi muốn làm cho nó trông giống như một hộp kiểm Aero ... –

0

Sử dụng mẫu từ Blend:

Để làm cho công việc BulletChrome, bạn cần phải thêm một tham chiếu đến PresentationFramework.Aero, và thêm phần khai báo xml namespace cho các "chủ đề" namespace:

xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 

Tôi đã không tự mình thử nhưng tôi tin rằng nó sẽ hoạt động (tôi đã thực hiện nó với Luna).

3

Hãy thử điều này (sửa đổi từ các bài viết mà publicgk liên quan đến)

<Window x:Class="WpfApplication1.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> 
    <Style x:Key="CheckRadioFocusVisual"> 
     <Setter Property="Control.Template"> 
     <Setter.Value> 
      <ControlTemplate> 
      <Rectangle Margin="14,0,0,0" 
         StrokeThickness="1" 
         Stroke="Black" 
         StrokeDashArray="1 2" 
         SnapsToDevicePixels="true"/> 
      </ControlTemplate> 
     </Setter.Value> 
     </Setter> 
    </Style> 

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

    <SolidColorBrush x:Key="CheckBoxFillNormal" 
        Color="#F4F4F4"/> 
    <SolidColorBrush x:Key="CheckBoxStroke" 
        Color="#8E8F8F"/> 
    <Style x:Key="{x:Type CheckBox}" 
     TargetType="{x:Type CheckBox}"> 
     <Setter Property="Foreground" 
      Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="Background" 
      Value="{StaticResource CheckBoxFillNormal}"/> 
     <Setter Property="BorderBrush" 
      Value="{StaticResource CheckBoxStroke}"/> 
     <Setter Property="BorderThickness" 
      Value="1"/> 
     <Setter Property="FocusVisualStyle" 
      Value="{StaticResource EmptyCheckBoxFocusVisual}"/> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type CheckBox}"> 
      <BulletDecorator Background="Transparent" 
          SnapsToDevicePixels="true"> 
       <BulletDecorator.Bullet> 
       <theme:BulletChrome Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}" 
            RenderMouseOver="{TemplateBinding IsMouseOver}" 
            RenderPressed="{TemplateBinding IsPressed}" 
            IsChecked="{TemplateBinding IsChecked}"/> 
       </BulletDecorator.Bullet> 
       <ContentPresenter Margin="{TemplateBinding Padding}" 
           VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
           HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
           RecognizesAccessKey="True" 
           SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
      </BulletDecorator> 
      <ControlTemplate.Triggers> 
       <Trigger Property="IsChecked" 
         Value="{x:Null}"> 
       <!-- TODO: Do Stuff Here --> 
       </Trigger> 
       <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> 
    </Style> 
    </Window.Resources> 
    <StackPanel> 
    <CheckBox IsChecked="True" Content="Checked"/> 
    <CheckBox IsChecked="{x:Null}" Content="Unknown"/> 
    <CheckBox IsChecked="False" Content="Not Checked"/> 
    </StackPanel> 
</Window> 
+1

{x: Null} là những gì tôi đang tìm kiếm. Cảm ơn bạn. – xr280xr

1

Hãy gọi cho tôi điên, nhưng tôi đã thực sự reimplemented hộp kiểm Aero tiêu chuẩn trong XAML tinh khiết. Nếu bạn muốn tùy chỉnh hộp kiểm Aero, đó là một điểm khởi đầu tốt. Bạn có thể tìm thấy các kiểu khác trong my repository on GitHub (specific commit, trong trường hợp tệp được di chuyển).

BulletCommon.xaml(tài nguyên chung cho CheckBox và RadioButton)

<ResourceDictionary 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:xx="clr-namespace:Alba.WpfThemeGenerator.Markup"> 

    <!-- Colors --> 

    <!-- Background overlay --> 
    <SolidColorBrush x:Key="Bullet.BackgroundOverlay.Hover" Color="#DEF9FA"/> 
    <SolidColorBrush x:Key="Bullet.BackgroundOverlay.Pressed" Color="#C2E4F6"/> 
    <SolidColorBrush x:Key="Bullet.BackgroundOverlay.Disabled" Color="#F4F4F4"/> 
    <!-- Border overlay --> 
    <SolidColorBrush x:Key="Bullet.BorderOverlay.Hover" Color="#3C7FB1"/> 
    <SolidColorBrush x:Key="Bullet.BorderOverlay.Pressed" Color="#2C628B"/> 
    <SolidColorBrush x:Key="Bullet.BorderOverlay.Disabled" Color="#ADB2B5"/> 
    <!-- Inner border --> 
    <LinearGradientBrush x:Key="Bullet.InnerBorder.Disabled" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#E1E3E5" Offset="0.25"/> 
     <GradientStop Color="#E8E9EA" Offset="0.5"/> 
     <GradientStop Color="#F3F3F3" Offset="1"/> 
    </LinearGradientBrush> 
    <!-- Indeterminate inner border --> 
    <LinearGradientBrush x:Key="Bullet.InnerBorder.IndeterminateDisabled" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#BFD0DD" Offset="0"/> 
     <GradientStop Color="#BDCBD7" Offset="0.5"/> 
     <GradientStop Color="#BAC4CC" Offset="1"/> 
    </LinearGradientBrush> 
    <!-- Inner fill --> 
    <LinearGradientBrush x:Key="Bullet.InnerFill.Normal" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#CBCFD5" Offset="0.2"/> 
     <GradientStop Color="#F7F7F7" Offset="0.8"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="Bullet.InnerFill.Hover" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#B1DFFD" Offset="0.2"/> 
     <GradientStop Color="#E9F7FE" Offset="0.8"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="Bullet.InnerFill.Pressed" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#7FBADC" Offset="0.2"/> 
     <GradientStop Color="#D6EDF9" Offset="0.8"/> 
    </LinearGradientBrush> 
    <!-- Indeterminate fill --> 
    <LinearGradientBrush x:Key="Bullet.Fill.Indeterminate" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#2FA8D5" Offset="0.2"/> 
     <GradientStop Color="#25598C" Offset="0.8"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="Bullet.Fill.IndeterminateHover" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#33D7ED" Offset="0.2"/> 
     <GradientStop Color="#2094CE" Offset="0.8"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="Bullet.Fill.IndeterminatePressed" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#17447A" Offset="0.2"/> 
     <GradientStop Color="#218BC3" Offset="0.8"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="Bullet.Fill.IndeterminateDisabled" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#C0E5F3" Offset="0.2"/> 
     <GradientStop Color="#BDCDDC" Offset="0.8"/> 
    </LinearGradientBrush> 

    <!-- Styles --> 

    <Style x:Key="Bullet.FocusVisual.Normal"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle Margin="14,0,0,0" SnapsToDevicePixels="True" 
          StrokeThickness="1" Stroke="{xx:SystemBrush ControlText}" StrokeDashArray="1 2"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <Style x:Key="Bullet.FocusVisual.Empty"> 
     <Setter Property="Control.Template"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Rectangle Margin="1" SnapsToDevicePixels="True" 
          StrokeThickness="1" Stroke="{xx:SystemBrush ControlText}" StrokeDashArray="1 2"/> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

</ResourceDictionary> 

CheckBox.xaml(nguồn lực cho CheckBox)

<ResourceDictionary 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:xx="clr-namespace:Alba.WpfThemeGenerator.Markup"> 

    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="BulletCommon.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 

    <!-- Colors --> 

    <SolidColorBrush x:Key="CheckBox.Stroke" Color="#8E8F8F"/> 
    <SolidColorBrush x:Key="CheckBox.Fill" Color="#F4F4F4"/> 
    <!-- Check mark --> 
    <SolidColorBrush x:Key="CheckBox.Glyph.Stroke.Normal" Color="#FFFFFF"/> 
    <SolidColorBrush x:Key="CheckBox.Glyph.Stroke.Pressed" Color="#B2FFFFFF"/> 
    <SolidColorBrush x:Key="CheckBox.Glyph.Fill.Normal" Color="#31347C"/> 
    <SolidColorBrush x:Key="CheckBox.Glyph.Fill.Pressed" Color="#B231347C"/> 
    <SolidColorBrush x:Key="CheckBox.Glyph.Fill.Disabled" Color="#AEB7CF"/> 
    <!-- Inner border --> 
    <LinearGradientBrush x:Key="CheckBox.InnerBorder" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#AEB3B9" Offset="0.25"/> 
     <GradientStop Color="#C2C4C6" Offset="0.5"/> 
     <GradientStop Color="#EAEBEB" Offset="1"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="CheckBox.InnerBorder.Hover" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#79C6F9" Offset="0.3"/> 
     <GradientStop Color="#79C6F9" Offset="0.5"/> 
     <GradientStop Color="#D2EDFD" Offset="1"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="CheckBox.InnerBorder.Pressed" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#54A6D5" Offset="0.3"/> 
     <GradientStop Color="#5EB5E4" Offset="0.5"/> 
     <GradientStop Color="#C4E5F6" Offset="1"/> 
    </LinearGradientBrush> 
    <!-- Indeterminate inner border --> 
    <LinearGradientBrush x:Key="CheckBox.InnerBorder.Indeterminate" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#2A628D" Offset="0"/> 
     <GradientStop Color="#245479" Offset="0.5"/> 
     <GradientStop Color="#193B55" Offset="1"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="CheckBox.InnerBorder.IndeterminateHover" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#29628D" Offset="0"/> 
     <GradientStop Color="#245479" Offset="0.5"/> 
     <GradientStop Color="#193B55" Offset="1"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="CheckBox.InnerBorder.IndeterminatePressed" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#193B55" Offset="0"/> 
     <GradientStop Color="#245479" Offset="0.5"/> 
     <GradientStop Color="#29628D" Offset="1"/> 
    </LinearGradientBrush> 
    <!-- Indeterminate highlight --> 
    <LinearGradientBrush x:Key="CheckBox.Highlight.Indeterminate" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#80FFFFFF" Offset="0"/> 
     <GradientStop Color="#00FFFFFF" Offset="0.5"/> 
     <GradientStop Color="#003333A0" Offset="0.5"/> 
     <GradientStop Color="#003333A0" Offset="1"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="CheckBox.Highlight.IndeterminateHover" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#80FFFFFF" Offset="0"/> 
     <GradientStop Color="#00FFFFFF" Offset="0.5"/> 
     <GradientStop Color="#003333A0" Offset="0.5"/> 
     <GradientStop Color="#803333A0" Offset="1"/> 
    </LinearGradientBrush> 
    <LinearGradientBrush x:Key="CheckBox.Highlight.IndeterminatePressed" StartPoint="0,0" EndPoint="1,1"> 
     <GradientStop Color="#00FFFFFF" Offset="0.5"/> 
     <GradientStop Color="#20FFFFFF" Offset="1"/> 
    </LinearGradientBrush> 

    <!-- Images --> 

    <PathGeometry x:Key="CheckBox.Glyph.Geometry"> 
     <PathFigure StartPoint="9.0, 1.833" IsClosed="True"> 
      <LineSegment Point="10.667, 3.167"/> 
      <LineSegment Point="7, 10.667"/> 
      <LineSegment Point="5.333, 10.667"/> 
      <LineSegment Point="3.333, 8.167"/> 
      <LineSegment Point="3.333, 6.833"/> 
      <LineSegment Point="4.833, 6.5"/> 
      <LineSegment Point="6, 8"/> 
     </PathFigure> 
    </PathGeometry> 

    <!-- Styles --> 

    <Style x:Key="{x:Type CheckBox}" TargetType="{x:Type CheckBox}"> 
     <Setter Property="FocusVisualStyle" Value="{StaticResource Bullet.FocusVisual.Empty}"/> 
     <Setter Property="Foreground" Value="{xx:SystemBrush ControlText}"/> 
     <Setter Property="Background" Value="{StaticResource CheckBox.Fill}"/> 
     <Setter Property="BorderBrush" Value="{StaticResource CheckBox.Stroke}"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type CheckBox}"> 
        <BulletDecorator Background="Transparent" SnapsToDevicePixels="True"> 
         <BulletDecorator.Bullet> 
          <Grid Width="13" Height="13"> 
           <Rectangle x:Name="Background" Margin="0" Fill="{TemplateBinding Background}"/> 
           <Rectangle x:Name="BackgroundOverlay" Margin="0"/> 
           <Rectangle x:Name="InnerFill" Margin="3" Fill="{StaticResource Bullet.InnerFill.Normal}"/> 
           <Rectangle x:Name="InnerBorder" Margin="2" Stroke="{StaticResource CheckBox.InnerBorder}"/> 
           <Rectangle x:Name="Highlight" Margin="3"/> 
           <Path x:Name="GlyphStroke" Margin="0" StrokeThickness="1.5" Data="{StaticResource CheckBox.Glyph.Geometry}"/> 
           <Path x:Name="GlyphFill" Margin="0" Data="{StaticResource CheckBox.Glyph.Geometry}"/> 
           <Rectangle x:Name="Border" Margin="0" Stroke="{TemplateBinding BorderBrush}"/> 
           <Rectangle x:Name="BorderOverlay" Margin="0"/> 
          </Grid> 
         </BulletDecorator.Bullet> 
         <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Margin="{TemplateBinding Padding}" 
           VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
           RecognizesAccessKey="True"/> 
        </BulletDecorator> 
        <ControlTemplate.Triggers> 

         <Trigger Property="HasContent" Value="True"> 
          <!-- if (HasContent) --> 
          <Setter Property="FocusVisualStyle" Value="{StaticResource Bullet.FocusVisual.Normal}"/> 
          <Setter Property="Padding" Value="4,0,0,0"/> 
         </Trigger> 

         <Trigger Property="IsMouseOver" Value="True"> 
          <!-- if (IsMouseOver) --> 
          <Setter TargetName="BackgroundOverlay" Property="Fill" Value="{StaticResource Bullet.BackgroundOverlay.Hover}"/> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.InnerFill.Hover}"/> 
          <Setter TargetName="BorderOverlay" Property="Stroke" Value="{StaticResource Bullet.BorderOverlay.Hover}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.Hover}"/> 
         </Trigger> 
         <Trigger Property="IsChecked" Value="{x:Null}"> 
          <!-- if (IsChecked == null) --> 
          <Setter TargetName="Highlight" Property="Stroke" Value="{StaticResource CheckBox.Highlight.Indeterminate}"/> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.Indeterminate}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.Indeterminate}"/> 
         </Trigger> 
         <Trigger Property="IsPressed" Value="True"> 
          <!-- if (IsPressed) --> 
          <Setter TargetName="BackgroundOverlay" Property="Fill" Value="{StaticResource Bullet.BackgroundOverlay.Pressed}"/> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.InnerFill.Pressed}"/> 
          <Setter TargetName="BorderOverlay" Property="Stroke" Value="{StaticResource Bullet.BorderOverlay.Pressed}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.Pressed}"/> 
         </Trigger> 
         <MultiTrigger> 
          <!-- if (IsChecked == null && IsMouseOver) --> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsChecked" Value="{x:Null}"/> 
           <Condition Property="IsMouseOver" Value="True"/> 
          </MultiTrigger.Conditions> 
          <Setter TargetName="Highlight" Property="Stroke" Value="{StaticResource CheckBox.Highlight.IndeterminateHover}"/> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.IndeterminateHover}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.IndeterminateHover}"/> 
         </MultiTrigger> 

         <MultiTrigger> 
          <!-- if (IsChecked == null && IsPressed) --> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsChecked" Value="{x:Null}"/> 
           <Condition Property="IsPressed" Value="True"/> 
          </MultiTrigger.Conditions> 
          <Setter TargetName="Highlight" Property="Stroke" Value="{StaticResource CheckBox.Highlight.IndeterminatePressed}"/> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.IndeterminatePressed}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource CheckBox.InnerBorder.IndeterminatePressed}"/> 
         </MultiTrigger> 
         <MultiTrigger> 
          <!-- if (IsChecked == true && IsPressed) --> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsChecked" Value="True"/> 
           <Condition Property="IsPressed" Value="True"/> 
          </MultiTrigger.Conditions> 
          <Setter TargetName="GlyphStroke" Property="Stroke" Value="{StaticResource CheckBox.Glyph.Stroke.Pressed}"/> 
          <Setter TargetName="GlyphFill" Property="Fill" Value="{StaticResource CheckBox.Glyph.Fill.Pressed}"/> 
         </MultiTrigger> 
         <MultiTrigger> 
          <!-- if (IsChecked == true && !IsPressed) --> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsChecked" Value="True"/> 
           <Condition Property="IsPressed" Value="False"/> 
          </MultiTrigger.Conditions> 
          <Setter TargetName="GlyphStroke" Property="Stroke" Value="{StaticResource CheckBox.Glyph.Stroke.Normal}"/> 
          <Setter TargetName="GlyphFill" Property="Fill" Value="{StaticResource CheckBox.Glyph.Fill.Normal}"/> 
         </MultiTrigger> 

         <Trigger Property="IsEnabled" Value="False"> 
          <!-- if (!IsEnabled) --> 
          <Setter Property="Foreground" Value="{xx:SystemBrush GrayText}"/> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{x:Null}"/> 
          <Setter TargetName="GlyphStroke" Property="Stroke" Value="{x:Null}"/> 
          <Setter TargetName="BorderOverlay" Property="Stroke" Value="{StaticResource Bullet.BorderOverlay.Disabled}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource Bullet.InnerBorder.Disabled}"/> 
         </Trigger> 
         <MultiTrigger> 
          <!-- if (IsChecked == null && !IsEnabled) --> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsChecked" Value="{x:Null}"/> 
           <Condition Property="IsEnabled" Value="False"/> 
          </MultiTrigger.Conditions> 
          <Setter TargetName="InnerFill" Property="Fill" Value="{StaticResource Bullet.Fill.IndeterminateDisabled}"/> 
          <Setter TargetName="InnerBorder" Property="Stroke" Value="{StaticResource Bullet.InnerBorder.IndeterminateDisabled}"/> 
         </MultiTrigger> 
         <MultiTrigger> 
          <!-- if (IsChecked == true && !IsEnabled) --> 
          <MultiTrigger.Conditions> 
           <Condition Property="IsChecked" Value="True"/> 
           <Condition Property="IsEnabled" Value="False"/> 
          </MultiTrigger.Conditions> 
          <Setter TargetName="GlyphFill" Property="Fill" Value="{StaticResource CheckBox.Glyph.Fill.Disabled}"/> 
         </MultiTrigger> 

        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

</ResourceDictionary> 

Ghi chú:

  1. {xx:SystemBrush ControlText} là phím tắt cho {DynamicResource {x:Static SystemColors.ControlTextBrushKey}}. Bạn có thể sử dụng shortcut hoặc chỉ tìm và thay thế bằng regex.

  2. RTL, hoạt ảnh, trường hợp lạ không được hỗ trợ.

  3. Kiểu này chậm hơn sử dụng BulletChrome được tối ưu hóa nhiều.

+0

Cảm ơn. Điều này đã giúp, vì tôi không thể tìm thấy bất kỳ nơi nào khác với mẫu BulletChrome. Một vấn đề là xmlns: xx = "clr-namespace: tham chiếu Alba.WpfThemeGenerator.Markup. Tôi đã nhận xét nó và thay thế tất cả các giá trị {xx: SystemBrush ControlText} bằng {DynamicResource {x: Static SystemColors.ControlTextBrushKey}} – Eternal21

0

Bạn có thể đặt thuộc tính IsThreeState của hộp kiểm thành true.

Điều này, tuy nhiên, cho phép chuyển đổi giá trị của hộp kiểm thành rỗng.
Nếu điều đó là không mong muốn, bạn thay vì có thể thêm vào Template của CheckBox bạn một kích hoạt cho các giá trị null, giống như Greg Bacchus shows in his answer:

<ControlTemplate.Triggers> 
    <Trigger Property="IsChecked" Value="{x:Null}"> 
     <!-- TODO: Do Stuff Here --> 
    </Trigger> 
</ControlTemplate.Triggers> 
Các vấn đề liên quan