How to create a custom checkbox as a button? I would be grateful for the example and brief explanations.
- as an option - stackoverflow.com/questions/23445409/… - Alexsandr Ter
- oneSo still WinForms or WPF? This is too different technology. It is probably worth asking two separate questions for each of them. - Alexander Petrov
- @AlexanderPetrov then a better winform - Victor Prokopenko
- If I were you, I’d rather look towards WPF. There is a couple of styles you can do. IMHO easier ... But still, yes, it is necessary to clearly indicate what you are developing and remove the extra label from the question. - EvgeniyZ
- @EvgeniyZ would not mind the WPF option, but still it is easier to winforms - Victor Prokopenko
3 answers
In WPF, as for me, this is much easier to do, because XAML with its styles and other "buns" is available for us.
For example, we need to make the first image. What is it made of?
Background with rounded corners
In WPF, Border with CornerRadius installed is perfect for this.Simple text of a specific color.
Well, let's write a simple style!
I will not implement everything here, but just show an example of how to proceed
We make a blank for our style.
With him we will set the Key so that it does not apply to all ChecBox, but only to those that we need. We also specify the type, and inside we define one Setter, which will override the Template of our element:<Style x:Key="MyCheckBox" TargetType="{x:Type CheckBox}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CheckBox}"> </ControlTemplate> </Setter.Value> </Setter> </Style>Add an additional Setter (color, text size, etc.).
Setter is essentially what the element will be standardly assigned to, it can be easily redefined after each element separately.<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"/>Now the time has come to override the template itself. In the ControlTemplate, let's create a Border with our contents inside.
<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 is just what will be specified through the Content element (or its child element).
Well, now it remains to be done so that it would be clear whether we set a “daw” or not. For this there is such a thing as "Triggers". In my case, I will do it simply, if
IsChecked = true, we make the text white.<ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="true"> <Setter Property="Foreground" Value="White"/> </Trigger> </ControlTemplate.Triggers>
The whole style ended up with this:
<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> It remains to attach this style to the desired item:
<CheckBox Style="{DynamicResource MyCheckBox}" Content="1" /> And the result:
In this example, a lot of things are not there, but I think you will understand the basic essence of how to edit elements on WPF. Good luck in learning!
- Thank you very much, but I would like to clarify how to correctly change through ControlTemplate.Triggers, I tried to add <Setter.Value> and <ControlTemplate TargetType = "{x: Type CheckBox}"> to edit via Border, but something does not work .. - Victor Prokopenko
- @ Viktor Prokopenko I didn’t understand the question a bit, what do you want and where to edit? - EvgeniyZ
- How to add a Border in ControlTemplate.Triggers for further change? If it is simpler, then I did not understand how to change the state of the checkbox when it is checked ... - Victor Prokopenko
- @ViktorProkopenko In Triggers there are only triggers, some say so, the events that we catch and change the desired parameter. You cannot create an object there, it will not be correct. All objects are in a ControlTemplate, not a ControlTemplate.Triggers! If you need to change only a specific element, in the ControlTemplate, give it a name (x: Name) and use (<Setter TargetName = ...) in the triggers. - EvgeniyZ
- <Setter TargetName = "\ CornerRadius" CornerRadius = "10" />? I also thought it would help <Setter Propetry = "CornerRadius" Value = "10" />, but to no avail - Victor Prokopenko
EvgeniyZ's answer is quite informative.
I will add the trade with my example with the basic animation.
We use:
<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> Type 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> Type 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> I somehow made styles
<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> red-green with CheckBox and becomes gray when it’s not active, but there is still 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> 


