Создание кастомного checkbox

244
04 июня 2018, 09:00

Как создать кастомный вариант checkbox в виде кнопки? Был бы благодарен примеру и краткими объяснениями

Answer 1

В WPF как по мне такое сделать намного легче, ведь для нас становиться доступен XAML с его стилями и другими "плюшками".

К примеру нам надо сделать первое изображение. Из чего оно состоит?

  • Фон с закругленными углами
    В WPF для этого отлично подойдет Border c установленным CornerRadius.

  • Простой текст определенного цвета.

Ну так давайте напишем простенький стиль!
Я не буду тут реализовывать все, а просто покажу пример того, как можно поступить

  1. Сделаем заготовку для нашего стиля.
    У него мы зададим Key, что бы не применялся ко всем ChecBox, а только к тем, которые нам нужны. Также укажем тип, ну и внутри зададим один Setter, который будет переопределять Template нашего элемента:

    <Style x:Key="MyCheckBox" TargetType="{x:Type CheckBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
  2. Добавим дополнительные Setter (цвет, размер текста и др.).
    Setter - это по сути то, что стандартно будет задано элементу, их спокойно можно переопределить после у каждого элемента по отдельности.

    <Setter Property="Foreground" Value="#FF000000"/>
    <Setter Property="Background" Value="#FFA4CE36"/>
    <Setter Property="MaxWidth" Value="100"/>
    <Setter Property="MaxHeight" Value="100"/>
    <Setter Property="FontSize" Value="40"/>
    <Setter Property="FontWeight" Value="DemiBold"/>
  3. Теперь время дошло до переопределения самого шаблона. В ControlTemplate создадим Border с нашим содержимом внутри.

    <ControlTemplate TargetType="{x:Type CheckBox}">
        <Border Width="{TemplateBinding Width}"
                Height="{TemplateBinding Height}"
                BorderBrush="#33000000"
                BorderThickness="1"
                CornerRadius="25"
                Background="{TemplateBinding Background}">
            <ContentPresenter x:Name="contentPresenter" 
                              Focusable="False" 
                              HorizontalAlignment="Center"
                              VerticalAlignment="Center"
                              Margin="{TemplateBinding Padding}"
                              RecognizesAccessKey="True"
                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>
    </ControlTemplate>

ContentPresenter - это как раз то, что будет задано через Content элементу (либо его дочерний элемент).

  1. Ну теперь остается сделать так, что бы было понятно, поставили ли мы "галку" или нет. Для этого существует такая вещь, как "Триггеры". В моем случае сделаю просто, если IsChecked = true - делаем текст белый.

    <ControlTemplate.Triggers>
        <Trigger Property="IsChecked" Value="true">
            <Setter Property="Foreground" Value="White"/>
        </Trigger>
    </ControlTemplate.Triggers>

Весь стиль в итоге получился такой:

<Style x:Key="MyCheckBox" TargetType="{x:Type CheckBox}">
    <Setter Property="Foreground" Value="#FF000000"/>
    <Setter Property="Background" Value="#FFA4CE36"/>
    <Setter Property="MaxWidth" Value="100"/>
    <Setter Property="MaxHeight" Value="100"/>
    <Setter Property="FontSize" Value="40"/>
    <Setter Property="FontWeight" Value="DemiBold"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <Border Width="{TemplateBinding Width}"
                        Height="{TemplateBinding Height}"
                        BorderBrush="#33000000"
                        BorderThickness="1"
                        CornerRadius="25"
                        Background="{TemplateBinding Background}">
                    <ContentPresenter x:Name="contentPresenter" 
                                      Focusable="False" 
                                      HorizontalAlignment="Center"
                                      VerticalAlignment="Center"
                                      Margin="{TemplateBinding Padding}"
                                      RecognizesAccessKey="True"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Осталось прицепить данный стиль на нужный элемент:

<CheckBox Style="{DynamicResource MyCheckBox}" Content="1" />

И результат:

В этом примере много чего нету, но основную суть того, как редактировать элементы на WPF думаю вы поймете. Удачи в изучение!

Answer 2

Ответ EvgeniyZ довольно содержательный.
Дополню трэд своим примером с базовой анимацией.

Используем:

<Grid ShowGridLines="True">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <CheckBox Template="{StaticResource CustomCheckBox}" Background="Green" Foreground="Red"/>
    <CheckBox  Grid.Row="1" Template="{StaticResource CustomCheckBox}" Background="Aqua" Foreground="DarkBlue" Content="Hello world"/>
    <CheckBox Grid.Column="1" Template="{StaticResource CustomCheckBox2}" Background="Red"/>
    <CheckBox Grid.Row="1" Grid.Column="1" Template="{StaticResource CustomCheckBox2}" Background="Red" Content="Custom checkbox 2"/>
</Grid>

Тип 1:

<ControlTemplate x:Key="CustomCheckBox" TargetType="CheckBox">
    <ControlTemplate.Resources>
        <Storyboard x:Key="Checkbox_True">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="rectangle">
                <DiscreteObjectKeyFrame KeyTime="0:0:0.01" Value="{x:Static Visibility.Visible}"/>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="Checkbox_False">
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="rectangle">
                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
                <DiscreteObjectKeyFrame KeyTime="0:0:0.01" Value="{x:Static Visibility.Hidden}"/>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </ControlTemplate.Resources>
    <Viewbox Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}">
        <StackPanel Orientation="Horizontal">
            <Grid>
                <Rectangle Width="30" Height="30" Fill="White"/>
                <Rectangle Width="25" Height="25" RadiusX="10" RadiusY="10" Fill="{TemplateBinding Background}"/>
                <Rectangle Width="18" Height="18" RadiusX="10" RadiusY="10" Fill="White"/>
                <Rectangle x:Name="rectangle" Width="14" Height="14" RadiusX="10" RadiusY="10" Fill="{TemplateBinding Foreground}" Visibility="Hidden"/>
            </Grid>
            <TextBlock VerticalAlignment="Center" Text="{TemplateBinding Content}"/>
        </StackPanel>
    </Viewbox>
    <ControlTemplate.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Trigger.ExitActions>
                <BeginStoryboard x:Name="Checkbox_False_BeginStoryboard" Storyboard="{StaticResource Checkbox_False}"/>
            </Trigger.ExitActions>
            <Trigger.EnterActions>
                <BeginStoryboard x:Name="Checkbox_True_BeginStoryboard" Storyboard="{StaticResource Checkbox_True}"/>
            </Trigger.EnterActions>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Тип 2:

<ControlTemplate x:Key="CustomCheckBox2" TargetType="CheckBox">
    <ControlTemplate.Resources>
        <Storyboard x:Key="Checkbox2_True">
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="path">
                <EasingColorKeyFrame KeyTime="0" Value="#00000000"/>
                <EasingColorKeyFrame KeyTime="0:0:0.1" Value="Black"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="Checkbox2_False">
            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Stroke).(SolidColorBrush.Color)" Storyboard.TargetName="path">
                <EasingColorKeyFrame KeyTime="0" Value="Black"/>
                <EasingColorKeyFrame KeyTime="0:0:0.1" Value="#00000000"/>
            </ColorAnimationUsingKeyFrames>
        </Storyboard>
    </ControlTemplate.Resources>
    <Viewbox Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}">
        <StackPanel Orientation="Horizontal">
            <Grid>
                <Rectangle Width="30" Height="30" Fill="White"/>
                <Rectangle Width="25" Height="25" RadiusX="10" RadiusY="10" Fill="{TemplateBinding Background}"/>
                <Rectangle Width="18" Height="18" RadiusX="10" RadiusY="10" Fill="White"/>
                <Path x:Name="path" Stroke="#00000000" StrokeThickness="1.5">
                    <Path.Data>
                        <GeometryGroup>
                            <LineGeometry StartPoint="10 15" EndPoint="15.5 22"/>
                            <LineGeometry StartPoint="15 22" EndPoint="20 10"/>
                        </GeometryGroup>
                    </Path.Data>
                </Path>
            </Grid>
            <TextBlock VerticalAlignment="Center" Text="{TemplateBinding Content}"/>
        </StackPanel>
    </Viewbox>
    <ControlTemplate.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Trigger.ExitActions>
                <BeginStoryboard x:Name="Checkbox2_False_BeginStoryboard" Storyboard="{StaticResource Checkbox2_False}"/>
            </Trigger.ExitActions>
            <Trigger.EnterActions>
                <BeginStoryboard x:Name="Checkbox2_True_BeginStoryboard" Storyboard="{StaticResource Checkbox2_True}"/>
            </Trigger.EnterActions>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>
Answer 3

я как то с делал стили

<Style x:Key="MainStyleCheckBox" TargetType="{x:Type CheckBox}">
    <Setter Property="SnapsToDevicePixels"
      Value="true" />
    <Setter Property="OverridesDefaultStyle"
      Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <BulletDecorator Background="{TemplateBinding Background}">
                    <BulletDecorator.Bullet>
                        <StackPanel Orientation="Horizontal">
                            <Border Width="30" Height="28" Name="Border" Background="#FF595959" Cursor="Hand" BorderBrush="#FF484848" CornerRadius="4" BorderThickness="1">
                                <Border.Effect>
                                    <DropShadowEffect ShadowDepth="0"/>
                                </Border.Effect>
                                <Border Name="ChechedBorder" Width="24" BorderThickness="1" CornerRadius="4" Height="22" BorderBrush="DimGray" Background="#FF5A5A5A"></Border>
                            </Border>
                        </StackPanel>
                    </BulletDecorator.Bullet>
                </BulletDecorator>
                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="True"/>
                            <Condition Property="IsEnabled" Value="True"/>
                        </MultiTrigger.Conditions>
                            <Setter TargetName="ChechedBorder" Property="Background"  Value="LightGreen"/>
                            <Setter TargetName="ChechedBorder" Property="BorderBrush" Value="#FF484848" />
                            <Setter TargetName="Border" Property="Background"  Value="Green"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="False"/>
                            <Condition Property="IsEnabled" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ChechedBorder" Property="Background"  Value="#FFD6586A"/>
                        <Setter TargetName="ChechedBorder" Property="BorderBrush" Value="#FFA80808" />
                        <Setter TargetName="Border" Property="Background"  Value="#FFA02323"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="False"/>
                            <Condition Property="IsEnabled" Value="False"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ChechedBorder" Property="Background"  Value="#FF595959"/>
                        <Setter TargetName="ChechedBorder" Property="BorderBrush" Value="black" />
                        <Setter TargetName="Border" Property="Background"  Value="#FF484848"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsChecked" Value="true"/>
                            <Condition Property="IsEnabled" Value="False"/>
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ChechedBorder" Property="Background"  Value="#FF30462F"/>
                        <Setter TargetName="ChechedBorder" Property="BorderBrush" Value="#FF1F1F1F" />
                        <Setter TargetName="Border" Property="Background"  Value="Green"/>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

красно зеленый с CheckBox и становится до кучи серым при не активности, а есть еще on/off

<Style x:Key="CheckBoxStyle2"
           TargetType="{x:Type CheckBox}">
    <Setter Property="SnapsToDevicePixels"
      Value="true" />
    <Setter Property="OverridesDefaultStyle"
      Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <BulletDecorator Background="{TemplateBinding Background}">
                    <BulletDecorator.Bullet>
                        <StackPanel Orientation="Horizontal">
                            <Border x:Name="Border"
                                    Width="32"
                                    Height="28"
                                    CornerRadius="2"
                                    BorderThickness="1" 
                                    BorderBrush="#FF242424"
                                    Cursor="Hand" Background="#FFDEDEDE">
                                <Border.Effect>
                                    <DropShadowEffect ShadowDepth="0"/>
                                </Border.Effect>
                                <Label Name="BooleanContent2" 
                                           Content="Off" HorizontalContentAlignment="Center" 
                                           VerticalContentAlignment="Center" FontWeight="Bold" />
                            </Border>
                            <Label Content="{TemplateBinding Content}" 
                                       />
                        </StackPanel>
                    </BulletDecorator.Bullet>
                </BulletDecorator>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="True" >
                        <Trigger.Setters>
                            <Setter TargetName="BooleanContent2" Property="Content" Value="On"/>
                            <Setter TargetName="Border" Property="Background" Value="#FF60A3ED"/>
                        </Trigger.Setters>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="False">
                        <Trigger.Setters>
                            <Setter TargetName="BooleanContent2" Property="Content" Value="Off"/>
                            <Setter TargetName="Border" Property="Background" Value="#FFDEDEDE"/>
                        </Trigger.Setters>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
READ ALSO
Конвертирование Enum в C#

Конвертирование Enum в C#

Возможно глупый вопросМожно ли преобразовать один enum в другой? К пример Namespace1

201
ContexMenuStrip картинка

ContexMenuStrip картинка

Как и дальше убирать место для картинки?!

225
3d объект на 2d сцене

3d объект на 2d сцене

Можно ли такое сделать? Есть поле, и на нем должен появляться 3д объект, само поле в 2д, камера сверхуБудет ли взаимодействовать физика 3д объекта...

184
Поиск по БД УСЛОВИЕ

Поиск по БД УСЛОВИЕ

Ребята, как сделать сам поиск я знаю, запросы и все такоеПомогите мне, возможно ли написать красивое условие если несколько разновидностей...

224