How to create a custom WPF XAML style for check box images
c#, wpf, xaml
Solution
In WPF you generally look for a control that has the functionality you need and then you make it look like you want. So if you want `CheckBox` functionality then you use `CheckBox` control and change its `Template` to be what you want. So you can create `Style` for `CheckBox` that will set your custom `Template`
<Window.Resources>
<Style TargetType="{x:Type CheckBox}" x:Key="myCheckboxStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<Image x:Name="checkboxImage" Source="normal.png" Width="32"/>
<ContentPresenter/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="checkboxImage" Property="Source" Value="checked.png"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsChecked" Value="False"/>
</MultiTrigger.Conditions>
<Setter TargetName="checkboxImage" Property="Source" Value="hover.png"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
and then just use it on any `CheckBox`
<CheckBox Style="{StaticResource myCheckboxStyle}" Content="ABC"/>
and you'll have all `CheckBox` functionality with your custom looks
Problem
I have a C# WPF Page and on it I have placed several small images that I want to act like check boxes (I have my own custom images for hover and selected states). I am manually changing the images like so: ``` <Image x:Name="Image_Custom" Source="/Images/checkcircle_off.png" Width="16" Height="16" HorizontalAlignment="Left" Margin="30,107,0,0" VerticalAlignment="Top" MouseEnter="Image_Custom_MouseEnter" MouseLeave="Image_Custom_MouseLeave" MouseUp="Image_Custom_MouseUp" MouseLeftButtonDown="Image_Custom_MouseLeftButtonDown"/> private void Image_Custom_MouseEnter(object sender, MouseEventArgs e) { if (_selected == false) { var uriSource = new Uri("/Images/checkcircle_hover.png", UriKind.Relative); Image_Custom.Source = new BitmapImage(uriSource); } } private void Image_Custom_MouseLeave(object sender, MouseEventArgs e) { if (_selected == false) { var uriSource = new Uri("/Images/checkcircle_off.png", UriKind.Relative); Image_Custom.Source = new BitmapImage(uriSource); } } private void Image_Custom_MouseUp(object sender, MouseButtonEventArgs e) { if (_selected) { var uriSource = new Uri("/Images/checkcircle_off.png", UriKind.Relative); Image_Custom.Source = new BitmapImage(uriSource); _selected = false; } else { var uriSource = new Uri("/Images/checkcircle_on.png", UriKind.Relative); Image_Custom.Source = new BitmapImage(uriSource); _selected = true; } } private void Image_Custom_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (_selected) { var uriSource = new Uri("/Images/checkcircle_off.png", UriKind.Relative); Image_Custom.Source = new BitmapImage(uriSource); _selected = false; } else { var uriSource = new Uri("/Images/checkcircle_on.png", UriKind.Relative); Image_Custom.Source = new BitmapImage(uriSource); _selected = true; } } ``` This works but is very cumbersome and I will have up to 20 check boxes. How can I create a custom XAML Style that I can use for each image or something similar. EDIT: I have used the following style to handle the hover over: ``` <Page.Resources> <Style TargetType="Image" x:Key="checkBoxStyle"> <Setter Property="Source" Value="/Images/checkcircle_off.png"/> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Source" Value="/Images/checkcircle_hover.png"/> </Trigger> </Style.Triggers> </Style> </Page.Resources> <Image x:Name="Image_Custom" Style="{StaticResource checkBoxStyle}" Width="16" Height="16" HorizontalAlignment="Left" Margin="30,107,0,0" VerticalAlignment="Top" MouseEnter="Image_Custom_MouseEnter" MouseLeave="Image_Custom_MouseLeave" MouseUp="Image_Custom_MouseUp" MouseLeftButtonDown="Image_Custom_MouseLeftButtonDown"/> ``` But I dont know how to handle the clicked event. How can I do this? EDIT 2 I have did the following: ``` <Style TargetType="{x:Type CheckBox}" x:Key="myCheckBoxStyle"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CheckBox}"> <Image x:Name="checkBoxImage" Source="/Images/checkcircle_off.png"></Image> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="checkBoxImage" Property="Source" Value="/Images/checkcircle_on.png"/> </Trigger> <Trigger Property="IsChecked" Value="False"> <Setter TargetName="checkBoxImage" Property="Source" Value="/Images/checkcircle_off.png"/> </Trigger> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="checkBoxImage" Property="Source" Value="/Images/checkcircle_hover.png"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <CheckBox Content="My CheckBox" Style="{StaticResource myCheckBoxStyle}" Width="16" Height="16" Foreground="white" FontSize="16" HorizontalAlignment="Left" Margin="30,242,0,0" VerticalAlignment="Top" /> ``` The correct images appear when hovered, checked and unchecked. But I noticed that the Content has disappeared ("My Checkbox") and also I only want the hover state to appear when its not checked, how can I do that?