Стилизация неопределенного состояния флажка WPF
Я хочу установить неопределенное состояние флажка WPF. У нас есть элемент управления treeview с флажками, и мы хотим, чтобы неопределенное состояние представляло, что некоторые потомки проверены, а некоторые не отмечены.
Решение, которое я вижу повсюду, - это переопределить шаблон управления по умолчанию для флажка и делать то, что мне нужно.
У меня есть две проблемы:
-
Я не могу найти шаблон управления
для нормального флажка Aero. Эта
один:
http://msdn.microsoft.com/en-us/library/ms752319.aspx
выглядит тупой.
-
Шаблон управления, который я получаю из Expression Blend, имеет этот элемент BulletChrome, и я не могу понять, что с ним делать.
Знает ли кто-нибудь, где можно получить шаблон управления флажком, который выглядит "нормальным", или есть более простой способ просто самостоятельно определить неопределенное состояние?
Я уверен, что есть простой способ, с которым я просто не замечаю... Правильно?
Ответы
Ответ 1
Попробуйте это (изменено из статьи, связанной с publicgk)
<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>
Ответ 2
Вы уже пытались загрузить Aero Theme xaml и заглянули в нее?
Где можно загрузить стандартные темы WPF от Microsoft?
Ответ 3
Вы можете использовать стиль CheckBox
из классической темы, расположенной по адресу:
-
C:\Program Files (x86)\Microsoft Expression\Blend 4\SystemThemes\Wpf\classic.xaml
В этой реализации есть Path
, представляющий значок флажка CheckMarkPath
. Я просто заменил этот Path
на заполненный Rectangle
, чтобы получить следующие результаты:
![Checkboxes]()
Ответ 4
Назовите меня сумасшедшим, но я действительно переопределил стандартный флажок Aero в чистом XAML. Если вы хотите настроить флажок Aero, это хорошая отправная точка. Вы можете найти другие стили в мой репозиторий на GitHub (конкретный commit, в случае перемещения файлов).
BulletCommon.xaml (общие ресурсы для CheckBox и 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 (ресурсы для 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>
Примечания:
-
{xx:SystemBrush ControlText}
является ярлыком для {DynamicResource {x:Static SystemColors.ControlTextBrushKey}}
. Вы можете использовать ярлык или просто найти и заменить с помощью регулярного выражения.
-
RTL, анимации, странные случаи не поддерживаются.
-
Этот стиль медленнее, чем использование BulletChrome
, которое сильно оптимизировано.
Ответ 5
Ниже приведен пример флажка с тремя состояниями.
<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>
Лучшим программным обеспечением для изменения существующего внешнего вида элементов управления является Expression Blend. Если вы хотите изменить существующий внешний вид и вам нужно изменить контрольный шаблон элемента управления.
Ответ 6
Другим вариантом может быть стиль кнопки переключения, так как он имеет несколько состояний. В прошлых проектах я создал пользовательские кнопки переключения с несколькими состояниями, которые выглядят и функционируют как chekcboxes. Я использовал blend, чтобы внести изменения, но используя кнопку tggle в качестве базы, я смог создать более индивидуальный внешний вид для различных состояний кнопки /chekcbox. Использование кнопки переключения можно обойти многие проблемы, связанные с хромом, которые сильно зависят от стандартного управления chekcbox.
Ответ 7
Вы думали об использовании SimpleStyles в качестве базы для управления?
![ExpressionSimpleStyles]()
Выбрав этот элемент управления на панели "Активы", Expression Blend поместит в свой проект новый ресурсный диктар, который вы можете использовать, чтобы изменить стиль по своему усмотрению. Возможно, это лучшая отправная точка, чем попытка взломать стандартный флажок Chrome.
Ответ 8
Использование шаблона из Blend:
Чтобы сделать работу BulletChrome, вам нужно добавить ссылку на PresentationFramework.Aero и добавить объявление пространства имен xml для пространства имен темы:
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
Я не пробовал это сам, но я считаю, что он должен работать (я сделал это с Луной).
Ответ 9
Вы можете установить флажок IsThreeState
в значение true.
Это, однако, позволяет переключить значение флажка в значение null.
Если это нежелательно, вы можете вместо этого добавить к своему шаблону CheckBox триггер для нулевого значения, как показывает Greg Bacchus в своем ответе:
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="{x:Null}">
<!-- TODO: Do Stuff Here -->
</Trigger>
</ControlTemplate.Triggers>