Change circle button background image on click in WPF - c#

I have a circle button below
<Button x:Name="btnLight" Width="72" Height="72" Content="" Margin="180,0,372,94" VerticalAlignment="Bottom" d:LayoutOverrides="VerticalAlignment">
<Button.Template>
<ControlTemplate>
<Grid>
<Ellipse>
<Ellipse.Fill>
<ImageBrush ImageSource="Images/light-off.jpg"/>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
How do I change the background image (Images/light-on.jpg) when I click it?
Thank you!

Wow! You have been given some complicated answers here... you're all doing too much work!!! This question has a really simple solution. First, let's sort out this ControlTemplate the way it should be:
<Button x:Name="btnLight" Width="72" Height="72" Content="" Margin="180,0,372,94"
VerticalAlignment="Bottom">
<Button.Template>
<ControlTemplate>
<Ellipse Name="Ellipse" Fill="{TemplateBinding Background}" />
</ControlTemplate>
</Button.Template>
</Button>
Now, you can add a really simple Style to perform your image change:
<Style TargetType="{x:Type Button}">
<Setter Property="Button.Background">
<Setter.Value>
<ImageBrush ImageSource="Images/Add_16.png" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Button.IsPressed" Value="True">
<Setter Property="Button.Background">
<Setter.Value>
<ImageBrush ImageSource="Images/Copy_16.png" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

To do it properly you need to create a view model that contains a handler for the button to call when it's pressed and a boolean property you can use for a datatrigger to change the image. Start with the view model:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public RelayCommand OnClickedCommand { get; private set; }
private bool _ImageChanged;
public bool ImageChanged
{
get { return this._ImageChanged; }
private set {
this._ImageChanged = value;
OnPropertyChanged("ImageChanged");
}
}
public ViewModel()
{
this.OnClickedCommand = new RelayCommand(param => OnClicked());
}
private void OnClicked()
{
this.ImageChanged = true;
}
}
Now create an instance of it and set it as your button's data context. Your button XAML should looks something like this:
<Button x:Name="btnLight" Margin="148,0,372,63" VerticalAlignment="Bottom" Command="{Binding OnClickedCommand}" Height="69">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse>
<Ellipse.Fill>
<ImageBrush ImageSource="image1.png"/>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding ImageChanged}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse>
<Ellipse.Fill>
<ImageBrush ImageSource="image2.png"/>
</Ellipse.Fill>
</Ellipse>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

Related

Pass custom properties in WPF templates

I'm trying to create a menu that works with radio buttons. The buttons are graphically prettied by a template. here I would like to display an icon and a text. However, I don't know how I can pass several parameters, so far I only pass the text and have not yet found a way to pass the image.
<StackPanel Grid.Row="1" Margin="0,10,0,0">
<RadioButton Content="Dashboard"
IsChecked="True"
Style="{StaticResource MenuButtonTheme}"/>
<RadioButton Content="Product"
Style="{StaticResource MenuButtonTheme}"/>
<RadioButton Content="Inventory"
Style="{StaticResource MenuButtonTheme}"/>
</StackPanel>
Style Of the Radiobutton
<Style BasedOn="{StaticResource {x:Type ToggleButton}}"
TargetType="{x:Type RadioButton}"
x:Key="MenuButtonTheme">
<Style.Setters>
<Setter Property="Foreground" Value="#FFFFFF"/>
<Setter Property="FontFamily" Value="/Fonts/#Poppins"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border Background="{TemplateBinding Background}"
CornerRadius="5"
Margin="5,0,5,0">
<Grid VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Height="50"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<iconPacks:PackIconBoxIcons Kind="SolidPieChartAlt2"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="10,0,0,0"/>
<TextBlock Grid.Column="1" Text="{TemplateBinding Property=Content}"
VerticalAlignment="Center"
FontSize="20"
FontWeight="Regular"
Margin="10,0,0,0"/>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" Value="#212121"/>
<Setter Property="Foreground" Value="#4169E1"/>
</Trigger>
</Style.Triggers>
</Style>
Foreach particular part of UI in your application, I recommend you to make it a module, that is, a UserContol or ContentControl(recommened). These controls corresponds to View in MVVM, and foreach of them you should add a View Model.
namespace MyNameSpace{
public class View<T> : ContentControl {
public T ViewModel {
get { return (T)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(T), typeof(View<T>), new PropertyMetadata());
}
public abstract class ViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] String propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
If the relative logic is purely UI, then Model is not needed in this case.
Your View's xaml should look like this:
<local:View x:TypeArguments="MyAViewModel" x:Name="view"
x:Class="MyNameSpace.MyAView"
skip
xmlns:local="clr-namespace:MyNameSpace">
<Image Source="{Binding ViewModel.ImageSource,ElementName=view}"/>
</local:View>
Your ViewModel should look like this:
public class MyAViewModel: ViewModel {
public AbilityViewModel() {//Constructor with parameter
//Set the image source here
}
private ImageSource imageSource;
public ImageSource ImageSource{
get => imageSource
set{
imageSource = value;
NotifyPropertyChanged();
}
}
}
In the root element of your UI hierarchy, for example your MainWindow, add your custom contols:
<Window x:Name="window" skip>
<Grid>
<local:MyAView ViewModel="{Binding MyAViewModel,ElementName=window}"/>
<local:MyBView ViewModel="{Binding MyBViewModel,ElementName=window}"/>
</Grid>
</Window>
You may either do so with adding dependency properies of the MyAViewModel and MyBViewModel to your MainWindow, or just set MyAView's ViewModel in MainWindow's constructor or loaded event. You may create the ViewModel to pass to view, in which ImageSource is initialized in constructor, or change it after its construction by somewhere in your code.
Above codes are just demo, directly written in stackoverflow's webpage and is not tested. You may ask me if there is any problem.

Passing specific parameters borderbrush to custom template

WPF, I have custom template and I want to pass borderbrush to this templete from xaml window I Created DependencyProperty
public class PassParamBrush
{
public static DependencyProperty BorderBrushProperty = DependencyProperty.RegisterAttached
(
"BorderBrush",
typeof(SolidColorBrush),
typeof(PassParamBrush),
new PropertyMetadata(null)
);
public static SolidColorBrush GetBorderBrush(DependencyObject target)
{
return (SolidColorBrush)target.GetValue(BorderBrushProperty);
}
public static void SetBorderBrush(DependencyObject target, ImageSource value)
{
target.SetValue(BorderBrushProperty, value);
}
}
And in UI I call it in this way
xmlns:localOne="clr-namespace:Turk_Common_WPF_Style.Style.WindowsStyle"
<Button localOne:PassParamBrush.BorderBrush="#aadbff" Width="30" Height="30" Style="{DynamicResource btnLogout}" />
And here the template
<!--Buton With Image background-->
<Style x:Key="btnLogout" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border CornerRadius="150" BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:PassParamToTemplter.PassParamBrush.BorderBrush)}" BorderThickness="5">
<!--<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:PassParamToTemplter.ImageSource)}"
Margin="2" Stretch="Fill" RenderOptions.BitmapScalingMode="HighQuality"/>-->
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Gray" Opacity="1" BlurRadius="25" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Button.IsPressed" Value="True">
<Setter Property="Margin" Value="7,7,7,0" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="#E8AA6E" Opacity="1" BlurRadius="25" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
but still not working when i run the code and show me this error
**+ InnerException {"No imaging component suitable to complete this operation was found."} System.Exception {System.NotSupportedException}
**
I found the error
public class PassParamBrush{
public static DependencyProperty BorderBrushProperty = DependencyProperty.RegisterAttached
(
"BorderBrush",
typeof(SolidColorBrush),
typeof(PassParamBrush),
new PropertyMetadata(null)
);
public static SolidColorBrush GetBorderBrush(DependencyObject target)
{
return (SolidColorBrush)target.GetValue(BorderBrushProperty);
}
public static void SetBorderBrush(DependencyObject target, ImageSource value)
{
target.SetValue(BorderBrushProperty, value);
}
}
the error her i should change the format in SetBorderBrush from ImageSource To SolidColorBrush

Binding to dependency property in slider control style not working

All the default property bindings are working fine however my custom properties are using the fallback values. Specifically ColorThumb and ColorThumbBorder. As their names imply, these 2 properties color the respective parts of the slider's thumb using a brush.
I've had no problems in the past getting my styles to use custom properties for other controls. Is there something unique about the slider control?
Style Xaml
<Style TargetType="{x:Type local:DMSlider}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Slider}">
<Border>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TickBar x:Name="TopTick" Visibility="{TemplateBinding TickPlacement}" Fill="{TemplateBinding Foreground}" Placement="Top" Height="4" Grid.Row="0"/>
<TickBar x:Name="BottomTick" Visibility="{TemplateBinding TickPlacement}" Fill="{TemplateBinding Foreground}" Placement="Bottom" Height="4" Grid.Row="0"/>
<Border x:Name="TrackBackground" BorderThickness="1" CornerRadius="0" Margin="5,0" VerticalAlignment="Center" Height="4.0" Grid.Row="1"
Background="{Binding Background, RelativeSource={RelativeSource Mode=TemplatedParent}}"
BorderBrush="{Binding BorderBrush, RelativeSource={RelativeSource Mode=TemplatedParent}}">
<Canvas Margin="-6,-1">
<Rectangle Visibility="Hidden" x:Name="PART_SelectionRange" Height="4.0" StrokeThickness="1.0"/>
</Canvas>
</Border>
<Track x:Name="PART_Track" Grid.Row="1">
<Track.DecreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource DMSliderRepeatButton}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource DMSliderRepeatButton}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb x:Name="Thumb">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border x:Name="gripBorder" BorderThickness="1"
Background="{Binding ColorThumb,
RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, FallbackValue=Red}"
BorderBrush="{Binding ColorThumbBorder,
RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, FallbackValue=Green}" >
<Rectangle x:Name="grip" Height="15" Width="10" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Properties CS
public partial class DMSlider : Slider
{
public static readonly DependencyProperty ColorSliderLeftProperty =
DependencyProperty.Register("ColorSliderLeft", typeof(Brush), typeof(DMSlider));
public static readonly DependencyProperty ColorSliderRightProperty =
DependencyProperty.Register("ColorSliderRight", typeof(Brush), typeof(DMSlider));
public static readonly DependencyProperty ColorSliderThumbProperty =
DependencyProperty.Register("ColorThumb", typeof(Brush), typeof(DMSlider), new FrameworkPropertyMetadata(Brushes.Orange));
public static readonly DependencyProperty ColorSliderThumbHoverProperty =
DependencyProperty.Register("ColorThumbHover", typeof(Brush), typeof(DMSlider));
public static readonly DependencyProperty ColorSliderThumbBorderProperty =
DependencyProperty.Register("ColorThumbBorder", typeof(Brush), typeof(DMSlider));
public Brush ColorSliderLeft
{
get { return (Brush)GetValue(ColorSliderLeftProperty); }
set { SetValue(ColorSliderLeftProperty, value); }
}
public Brush ColorSliderRight
{
get { return (Brush)GetValue(ColorSliderRightProperty); }
set { SetValue(ColorSliderRightProperty, value); }
}
public Brush ColorThumb
{
get { return (Brush)GetValue(ColorSliderThumbProperty); }
set { SetValue(ColorSliderThumbProperty, value); }
}
public Brush ColorThumbHover
{
get { return (Brush)GetValue(ColorSliderThumbHoverProperty); }
set { SetValue(ColorSliderThumbHoverProperty, value); }
}
public Brush ColorThumbBorder
{
get { return (Brush)GetValue(ColorSliderThumbProperty); }
set { SetValue(ColorSliderThumbBorderProperty, value); }
}
}
Thanks to #Clemens for showing me what I was doing wrong. I needed to reference the slider not the the thumb.
I should have been targeting an ancestor like so:
Background="{Binding ColorThumb, RelativeSource={RelativeSource AncestorType=local:DMSlider}, Mode=TwoWay, FallbackValue=Red}"
BorderBrush="{Binding ColorThumbBorder, RelativeSource={RelativeSource AncestorType=local:DMSlider}, Mode=TwoWay, FallbackValue=Green}"
Full thumb style
<Thumb x:Name="Thumb">
<Thumb.Style>
<Style TargetType="{x:Type Thumb}">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border x:Name="gripBorder" BorderThickness="1"
Background="{Binding ColorThumb,
RelativeSource={RelativeSource AncestorType=local:DMSlider}, Mode=TwoWay, FallbackValue=Red}"
BorderBrush="{Binding ColorThumbBorder,
RelativeSource={RelativeSource AncestorType=local:DMSlider}, Mode=TwoWay, FallbackValue=Green}">
<Rectangle x:Name="grip" Height="15" Width="10" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Thumb.Style>

Why do my triggers end up with a blank control?

In WPF I'm trying to create a "flag" control that displays a checkmark or an X based on a bound dependency property (Flag)
<UserControl x:Name="Root" (Other user control stuff)>
<ContentControl Height="20" x:Name="flagHolder">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="False">
<Setter Property="Content" Value="{StaticResource XIcon}" />
<Setter Property="Foreground" Value="Crimson"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="True">
<Setter Property="Content" Value="{StaticResource CheckIcon}" />
<Setter Property="Foreground" Value="ForestGreen"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</UserControl>
On startup every icon is correct (I have several of these controls, each bound to different values). However, when I toggle a few (one that was "off" turns "on" and the one currently "on" turns "off") I see two things:
The control that was turned "on" has become a green check (as desired)
The control that was turned "off" is now just blank
Inspecting the visual tree seems to indicate that everything is working (though I could easily be missing something here), and the order of the triggers doesn't seem to matter. What am I doing wrong?
Here is an example icon, the path geometry is removed since its just noise:
<Viewbox x:Key="CheckIcon" x:Shared="False">
<Path Style="{StaticResource IconPathStyle}">
<Path.Data>
<PathGeometry Figures="Bunch of SVG" FillRule="NonZero"/>
</Path.Data>
</Path>
</Viewbox>
I'm unable to reproduce your issue, but here what I have and it's working:
App.xaml
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Viewbox x:Key="CheckIcon" x:Shared="False">
<Canvas Height="24" Width="32">
<Path Width="7.85446" Height="8.57578" Canvas.Left="-0.0522281" Canvas.Top="-0.100391" Stretch="Fill" StrokeThickness="1.04192" StrokeMiterLimit="2.75" Stroke="#FF000000" Data="F1 M 0.468732,4.66838L 3.03345,7.95443L 7.28127,0.420569"/>
</Canvas>
</Viewbox>
<Viewbox x:Key="XIcon" x:Shared="False">
<Canvas Height="24" Width="32">
<Path Data="M0,0 L1,1 M0,1 L1,0" Stretch="Fill" Stroke="Black" StrokeThickness="3" Width="12" Height="12" />
</Canvas>
</Viewbox>
</Application.Resources>
</Application>
YesNo.xaml
<UserControl x:Class="WpfApplication1.YesNo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Root">
<ContentControl Height="20" Name="flagHolder">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="False">
<Setter Property="Content" Value="{StaticResource XIcon}" />
<Setter Property="Foreground" Value="Crimson"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=Root, Path=Flag}" Value="True">
<Setter Property="Content" Value="{StaticResource CheckIcon}" />
<Setter Property="Foreground" Value="ForestGreen"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</UserControl>
YesNo.xaml.cs
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class YesNo : UserControl
{
public YesNo()
{
InitializeComponent();
}
public static readonly DependencyProperty FlagProperty = DependencyProperty.Register(
"Flag", typeof(bool), typeof(YesNo), new PropertyMetadata(default(bool)));
public bool Flag {
get {
return (bool) GetValue(FlagProperty);
}
set {
SetValue(FlagProperty, value);
}
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="" Width="400" Height="400">
<StackPanel Orientation="Vertical" Margin="50">
<wpfApplication1:YesNo Flag="{Binding Flag1}"/>
<wpfApplication1:YesNo Flag="{Binding Flag2}"/>
<wpfApplication1:YesNo Flag="{Binding Flag2}"/>
<wpfApplication1:YesNo Flag="{Binding Flag1}"/>
<Button Content="Toggle" Click="ButtonBase_OnClick"></Button>
</StackPanel>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : INotifyPropertyChanged
{
private bool _flag1;
private bool _flag2;
public MainWindow()
{
InitializeComponent();
DataContext = this;
Flag1 = true;
Flag2 = false;
}
public bool Flag1 {
get {
return _flag1;
}
set {
_flag1 = value;
OnPropertyChanged();
}
}
public bool Flag2 {
get {
return _flag2;
}
set {
_flag2 = value;
OnPropertyChanged();
}
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
Flag1 = !Flag1;
Flag2 = !Flag2;
}
}
How it looks like:
Video: http://www.screencast.com/t/J5IY7DR3Ry

Why Binding Between Picture Change To Click on It Not Working

I want when I press on bulb button every time picture will change. I tried but without success. My code doesn't work, please tell my why, thanks.
Here is the UserControl in XAML:
<UserControl x:Class="PL_Wpf.CustomControls.Bulb"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
>
<Grid>
<Button x:Name="BulbButton" Height="60" Width="40" Click="BulbButton_Click" >
<Button.Template>
<ControlTemplate>
<Image Source="../Pics/bulb_off.jpg" Width="40" Height="60" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=Bulb, Path=OnOff}" Value="True">
<Setter Property="Source" Value="../Pics/bulb_on.jpg" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=Bulb, Path=OnOff}" Value="False">
<Setter Property="Source" Value="../Pics/bulb_off.jpg" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
</UserControl>
And here is the code behind:
public partial class Bulb : UserControl, INotifyPropertyChanged
{
public bool OnOff { get; set; }
public Bulb()
{
InitializeComponent();
DataContext = this;
OnOff = false;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
{
PropertyChanged(this, e);
}
}
public void BulbButton_Click(object sender, RoutedEventArgs e)
{
OnOff = (OnOff == false) ? true : false;
}
public bool On
{
get { return OnOff; }
set
{
OnOff = value;
OnPropertyChanged(new PropertyChangedEventArgs("On"));
}
}
}
The think that you want to achieve with your control can be simply done by modifying the control template of a checkbox.
Just add this code in the window in place of your control:
<CheckBox>
<CheckBox.Template>
<ControlTemplate TargetType="CheckBox">
<Grid>
<Image Source="pack://siteoforigin:,,,/Pics/bulb_off.jpg" Width="40" Height="60" />
<Image Source="pack://siteoforigin:,,,/Pics/bulb_on.jpg" Width="40" Height="60" Name="CheckMark" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false">
<Setter TargetName="CheckMark" Property="Visibility" Value="Hidden"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</CheckBox.Template>
</CheckBox>

Categories

Resources