Why do my triggers end up with a blank control? - c#

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

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.

Show dialog in menu and prevent clicks not on dialog controls from closing the menu / dialog

I have a MenuItem.
When I click the item, I want the sub-MenuItem to open and show a form to login.
Hereunder what I already made (feel free to completely redesign this)...
The problem now is:
when I mouse-over or click in the subitem, the item is highlighted.
when i click on an item (except the textbox) the menu closes.
Thank you for your help!
<MenuItem>
<MenuItem.Header>
<Image
Width="16"
Height="16">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{StaticResource DisconnectedIcon}" />
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Connected}">
<Setter Property="Source" Value="{StaticResource ConnectedIcon}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</MenuItem.Header>
<autogrid:AutoGrid
Columns="Auto,Auto"
Margin="1"
RowHeight="25">
<autogrid:AutoGrid.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="3" />
<Setter Property="Width" Value="100" />
</Style>
<Style TargetType="{x:Type PasswordBox}">
<Setter Property="Margin" Value="3" />
<Setter Property="Width" Value="100" />
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="3" />
<Setter Property="Width" Value="100" />
</Style>
</autogrid:AutoGrid.Resources>
<TextBlock Text="System: "/>
<TextBox></TextBox>
<TextBlock Text="Username: "/>
<TextBox></TextBox>
<TextBlock Text="Password: "/>
<PasswordBox></PasswordBox>
</autogrid:AutoGrid>
<Button Content="Connect"/>
</MenuItem>
I recommend making your login controls part of a new window.
And for anyone else following along, you need to run Install-Package WpfAutoGrid -Version 1.4.0 in your package manager console.
For future reference, please post a MINIMAL and complete example.
Took me longer than it should have to throw this together.
Please read "How to create a Minimal, Complete, and Verifiable example"
Here's my MCVE example:
MainWindow.xaml:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:autogrid="clr-namespace:WpfAutoGrid;assembly=WpfAutoGrid"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="250" Width="500">
<Window.DataContext>
<local:VM/>
</Window.DataContext>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem>
<MenuItem.Header>
<Image
Width="16"
Height="16">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{StaticResource DisconnectedIcon}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Connected}" Value="true">
<Setter Property="Source" Value="{StaticResource ConnectedIcon}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Connected}" Value="false">
<Setter Property="Source" Value="{StaticResource DisconnectedIcon}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</MenuItem.Header>
<MenuItem x:Name="connectMenuItem" Header="{Binding ConnectOrDisconnect}" Click="MenuItem_Click"/>
</MenuItem>
</Menu>
<Grid DockPanel.Dock="Bottom" Background="Black" />
</DockPanel>
</Window>
MainWindow.xaml.cs:
using System.Windows;
namespace WpfApp1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
VM thisDC = (VM)this.DataContext;
if (thisDC.Connected)
{
// DisConnect
thisDC.Connected = false;
}
else
{
ConnectWindow cw = new ConnectWindow
{
Owner = this,
DataContext = this.DataContext
};
cw.ShowDialog();
}
}
}
}
ConnectWindow.xaml:
<Window x:Class="WpfApp1.ConnectWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:autogrid="clr-namespace:WpfAutoGrid;assembly=WpfAutoGrid"
mc:Ignorable="d" Title="ConnectWindow" Height="180" Width="270">
<autogrid:AutoGrid
Columns="Auto,Auto"
Rows="Auto,Auto, Auto, Auto"
Margin="20"
RowHeight="25">
<autogrid:AutoGrid.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="3" />
<Setter Property="Width" Value="100" />
</Style>
<Style TargetType="{x:Type PasswordBox}">
<Setter Property="Margin" Value="3" />
<Setter Property="Width" Value="100" />
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="3" />
<Setter Property="Width" Value="100" />
</Style>
</autogrid:AutoGrid.Resources>
<TextBlock Text="System: "/>
<TextBox></TextBox>
<TextBlock Text="User Name: "/>
<TextBox></TextBox>
<TextBlock Text="Password: "/>
<PasswordBox></PasswordBox>
<Button Grid.ColumnSpan="2" Content="Connect" Click="Button_Click" />
</autogrid:AutoGrid>
</Window>
ConnectWindow.xaml.cs:
using System.Windows;
namespace WpfApp1
{
public partial class ConnectWindow : Window
{
public ConnectWindow()
{
InitializeComponent();
}
private bool verified = true;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (verified)
{
VM thisDC = (VM)this.DataContext;
thisDC.Connected = true;
this.Close();
}
else
{
// error message
this.Close();
}
}
}
}
VM.cs:
using System.ComponentModel;
namespace WpfApp1
{
class VM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool connected;
public bool Connected
{
get { return connected; }
set
{
{
connected = value;
OnPropertyChanged("Connected");
if (value) { ConnectOrDisconnect = "Disconnect"; }
else { ConnectOrDisconnect = "Connect"; }
}
}
}
private string connectOrDisconnect;
public string ConnectOrDisconnect
{
get { return connectOrDisconnect; }
set
{
connectOrDisconnect = value;
OnPropertyChanged("ConnectOrDisconnect");
}
}
public VM()
{
Connected = false;
}
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
App.xaml:
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
resources.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<BitmapImage x:Key="ConnectedIcon" UriSource="pack://application:,,,/WpfApp1;component/ConnectedIcon.ico" />
<BitmapImage x:Key="DisconnectedIcon" UriSource="pack://application:,,,/WpfApp1;component/DisconnectedIcon.ico" />
</ResourceDictionary>

Setfocus from within VM not working

I've following code in my WPF app.I'm trying to set the focus on a textbox on a button click...i.e. on invoking Check() method...
Code:
MainWindowResources.xaml
<Style TargetType="TextBox" x:Key="MyFiedlStyle">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=FocusOnMyField}" Value="true">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=myField}"/>
</DataTrigger>
</Style.Triggers>
</Style>
MainWindow.xaml
<TextBox HorizontalAlignment="Left" Margin="1,1,0,0" Width="180" Text="{Binding MyAttributes.MyFieldValue}" TabIndex="4" Grid.Row="3" VerticalAlignment="Top" Grid.Column="5"
Name="myField" Style="{DynamicResource MyFieldStyle}"/>
MainWindowViewModel
private bool FocusOnMyField
{
get { return m_FocusOnMyField; }
set
{
m_FocusOnMyField = value;
OnPropertyChanged("FocusOnMyField");
}
}
private void Check()
{
this.FocusOnSecDescription = true;
}
Thanks.

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>

Change circle button background image on click in WPF

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>

Categories

Resources