Changing Button image when IsEnabled - wpf

I want to change button image when button IsEnabled == False.
Below is my example, bindings are fine, when I change them for False/True it is still not working.
<Button x:Name="btnBackward" Grid.Column="0" Grid.Row="2" Command="{Binding UserWorkflowManager.NavigateBackward}" IsEnabled="{Binding UserWorkflowManager.NavigateBackwardEnable}" Grid.RowSpan="2">
<Button.Template>
<ControlTemplate>
<Image Name="_image" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Uniform">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="/UserWorkflow.View;component/Images/LDC500_butX_PreviousPane_norm.bmp" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=btnBackward, Path=IsEnabled}" Value="False">
<Setter Property="Source" Value="/UserWorkflow.View;component/Images/LDC500_butX_PreviousPane_dis.bmp"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</ControlTemplate>
</Button.Template>
</Button>

Try the following
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled,RelativeSource={RelativeSource AncestorType=Button}}" Value="False">
<Setter Property="Source" Value="/UserWorkflow.View;component/Images/LDC500_butX_PreviousPane_dis.bmp"/>
</DataTrigger>
</Style.Triggers>
Or add the trigger directly in the control template like so
<ControlTemplate>
<Image Name="_image" HorizontalAlignment="Center">
..........
</Image>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="_image" Property="Source" Value="/UserWorkflow.View;component/Images/LDC500_butX_PreviousPane_dis.bmp" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Try this:
<Button x:Name="btnBackward" Grid.Column="0" Click="btnBackward_Click">
<Button.Template>
<ControlTemplate>
<Image Name="_image" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Uniform">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="/Images/0.png" />
</Style>
</Image.Style>
</Image>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Source" Value="/Images/1.png" TargetName="_image"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
You should specify "TargetName" property for a setter within "ControlTemplate.Triggers"

The soution is is to use RelativeSource={RelativeSource Self}} in your DataTrigger.
<DataTrigger
Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}"
Value="False">
Example
Add this style:
<Style x:Key="MainButtonStyle" TargetType="Button" BasedOn="{StaticResource ChromelessButtonStyle}">
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}" Value="False">
<Setter Property="Background" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
Then apply this style to the button:
<Button x:Name="ActionButton" Style="{StaticResource MainButtonStyle}" Command="{Binding MyCmd}" IsEnabled="{Binding ActionButtonEnabled}"/>

Related

Set image on datagrid row header through xaml

I tried to setup a Datagrid so that I have an image in the RowHeader to show the status of each object that is listed.
To achieve that, I have a IsTaskCompletedSuccessfully nullable boolean property in my view model.
In my resources, I added an image with the following style:
<DataGrid.Resources>
<Image x:Name="editImage"
x:Key="rowHeaderTemplate"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Width="16"
Margin="1,0">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding IsTaskCompletedSuccessfully}" Value="true">
<Setter Property="Source" Value="/RFiDGear;component/Resources/confirm.ico"/>
</DataTrigger >
<DataTrigger Binding="{Binding IsTaskCompletedSuccessfully}" Value="false">
<Setter Property="Source" Value="/RFiDGear;component/Resources/error.ico"/>
</DataTrigger >
<DataTrigger Binding="{Binding IsTaskCompletedSuccessfully}" Value="{x:Null}">
<Setter Property="Source" Value="/RFiDGear;component/Resources/wait.ico"/>
</DataTrigger >
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataGrid.Resources>
below i have the rowheaderstyle:
<DataGrid.RowHeaderStyle>
<Style TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Content" Value="{StaticResource rowHeaderTemplate}"/>
</Style>
</DataGrid.RowHeaderStyle>
Unfortunately it only works on the last row/object added not on all rows. What did i miss here?!
Edit1:
I edited the Style to a RowHeaderTemplate. Later i figured out that databinding isn't working correctly this way. My Image Source won't update. There are no binding errors in the output window at runtime.
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<Image x:Name="editImage"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Width="16"
Margin="1,0">
</Image>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsTaskCompletedSuccessfully}" Value="True">
<Setter TargetName="editImage" Property="Source" Value="/RFiDGear;component/Resources/confirm.ico"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsTaskCompletedSuccessfully}" Value="False">
<Setter TargetName="editImage" Property="Source" Value="/RFiDGear;component/Resources/error.ico"/>
</DataTrigger>
<!--<DataTrigger Binding="{Binding IsTaskCompletedSuccessfully}" Value="{x:Null}">
<Setter TargetName="editImage" Property="Source" Value="/RFiDGear;component/Resources/wait.ico"/>
</DataTrigger>-->
</DataTemplate.Triggers>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
Got it working. I have to work with relativesource to find the datacontext.
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<Image x:Name="editImage"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Width="16"
Margin="1,0">
</Image>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridRow}, Path=DataContext.IsTaskCompletedSuccessfully}" Value="True">
<Setter TargetName="editImage" Property="Source" Value="/RFiDGear;component/Resources/confirm.ico"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridRow}, Path=DataContext.IsTaskCompletedSuccessfully}" Value="False">
<Setter TargetName="editImage" Property="Source" Value="/RFiDGear;component/Resources/error.ico"/>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridRow}, Path=DataContext.IsTaskCompletedSuccessfully}" Value="{x:Null}">
<Setter TargetName="editImage" Property="Source" Value="/RFiDGear;component/Resources/wait.ico"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGrid.RowHeaderTemplate>

WPF - changing background button

i would like change background color using binding. When i dont use Style="{DynamicResource ButtonStyle}", Background changes. This is my code:
<Button Style="{DynamicResource ButtonStyle}" Content="{Binding Title, UpdateSourceTrigger=PropertyChanged}"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=DataContext.SelectButton}"
CommandParameter="{Binding}" ToolTip="{Binding Description}">
<Button.Resources>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}" Value="False">
<Setter Property="Background" Value="Blue"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Resources>
</Button>
How i change background color in button using trigger? can be a trigger to insert a reference to style?
You could use a value converter instead a style if you cannot apply the trigger to the control template of the button or the style.
Background="{Binding IsSelected, Converter={StaticResource SelectedToBackgroundConverter}}"
Or with style
<Style x:Key="ButtonStyle2" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}" Value="False">
<Setter Property="Background" Value="Blue"/>
</DataTrigger>
</Style.Triggers>
</Style>
Or control template
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="myGrid" Width="200" Height="20" Background="{TemplateBinding Background}">
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="myGrid" Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}" Value="False">
<Setter TargetName="myGrid" Property="Background" Value="Blue"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Style Trigger for different images and border background

I Want to use different Border Background and Different Images (each image must use different background color)
how i change use StyleTrigger to do it ? (Now it just show red border for all images)
<DataTemplate>
<Border BorderThickness="1" Width="18" Height="18" CornerRadius="2" BorderBrush="Red" Background="Red">
<Image Width="16" Height="16">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{x:Null}" />
<Style.Triggers>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="High">
<Setter Property="Source" Value="/project;component/Images/High.png" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="Medium">
<Setter Property="Source" Value="/project;component/Images/Medium.png" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="Low">
<Setter Property="Source" Value="/project;component/Images/Low.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Border>
</DataTemplate>
Thank you.
Assuming that your Binding is correct, you just need to add a similar Style to the Border to update the Background property and remove the Background value from the Border itself:
<DataTemplate>
<Border BorderThickness="1" Width="18" Height="18" CornerRadius="2" BorderBrush="Red">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="High">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="Medium">
<Setter Property="Background" Value="Blue" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="Low">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Image Width="16" Height="16">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="{x:Null}" />
<Style.Triggers>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="High">
<Setter Property="Source" Value="/project;component/Images/High.png" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="Medium">
<Setter Property="Source" Value="/project;component/Images/Medium.png" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.DataContext.my}" Value="Low">
<Setter Property="Source" Value="/project;component/Images/Low.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Border>
</DataTemplate>
Try this.

Wpf TreeView IsExpanded

I tried to bind to IsExpanded property in Hierarchical template with another context.
<HierarchicalDataTemplate x:Key="TreeView1" ItemsSource="{Binding Path=Folders}" >
<StackPanel Margin="5,5,5,5" Orientation="Horizontal">
<StackPanel Name="spinCont">
<ModulesUpToDateChecker1:Spinner Width="20" x:Name="Spin" FolderContext="{Binding}" StateContext="{Binding Path=State}"></ModulesUpToDateChecker1:Spinner>
<Image x:Name="imgFolderIcon" Width="16" Visibility="Hidden"
Source="/ModulesUpToDateChecker;component/Resources/FolderClosed16.png">
<Image.Triggers>
</Image.Triggers>
</Image>
<Image VerticalAlignment="Center" x:Name="imgFolderItem"
Source="{Binding Path=State, Converter={StaticResource stateFolderConverter}}">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=IsLast}" Value="true"></Condition>
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
<StackPanel DataContext="{Binding Path=Modules}">
<ModulesUpToDateChecker1:Spinner Width="20">
<ModulesUpToDateChecker1:Spinner.Style>
<Style TargetType="{x:Type ModulesUpToDateChecker1:Spinner}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Animation}" Value="True" >
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ModulesUpToDateChecker1:Spinner.Style>
</ModulesUpToDateChecker1:Spinner>
<Image VerticalAlignment="Center"
Source="{Binding Path=State, Converter={StaticResource stateImageConverter}}">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Animation}" Value="True" >
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
<TextBlock Text="{Binding Path=Name}" Margin="10,0,0,0"></TextBlock>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<!--<Trigger Property="{Binding}" Value="true">
<Setter TargetName="imgFolderIcon" Property="Source" Value="/ModulesUpToDateChecker;component/Resources/Error.png" />
</Trigger>-->
**<DataTrigger Binding="{Binding Path=IsExpanded}" Value="true">
<Setter TargetName="imgFolderIcon" Property="Source" Value="/ModulesUpToDateChecker;component/Resources/Error.png" />
</DataTrigger>**
doest work
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
I have the "Folder" context (its hierarchical object) but how can i bind to theTreeView properties in HierarchicalDataTemplate.Triggers? When i start this, output shows that there is no IsExpanded property in Folder object. So, i have wrong context.
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=TreeViewItem}, Path=IsExpanded}" Value="true">
<Setter TargetName="imgFolderIcon" Property="Source" Value="/Resources/FolderExpanded.png" />
</DataTrigger>
Easy

Change Button Image Issue

Im working in WPF and I am trying to change the image of a button, I have created some triggers and Setters, but it is not working.
Here's my XAML code:
<Button BorderThickness="0" Height="23" HorizontalAlignment="Left" Margin="59,6,0,0" Name="topButton" Width="26" VerticalAlignment="Top"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" IsEnabled="False" >
<StackPanel>
<Image>
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=topButton, Path=Button.IsEnabled}" Value="True">
<Setter Property="Image.Source" Value="Images/MoveFirst_Enabled.bmp" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=topButton, Path=Button.IsEnabled}" Value="False">
<Setter Property="Image.Source" Value="Images/MoveFirst_Disabled.bmp" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Button>
I cant realize what I am doing wrong. Hope you can help me. Thank you in advance.
Remove the Button. for the Path. So instead of
Path=Button.IsEnabled
you should have
Path=IsEnabled
Example
<Button BorderThickness="0" Height="23" HorizontalAlignment="Left" Margin="59,6,0,0" Name="topButton" Width="26" VerticalAlignment="Top" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" IsEnabled="False">
<StackPanel>
<Image>
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=topButton, Path=IsEnabled}" Value="True">
<Setter Property="Source" Value="Images/MoveFirst_Enabled.bmp" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=topButton, Path=IsEnabled}" Value="False">
<Setter Property="Source" Value="Images/MoveFirst_Disabled.bmp" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Button>
I think you are not using the correct Uri string for the Source of the Image.
<Button BorderThickness="0" Height="23" HorizontalAlignment="Left" Margin="59,6,0,0" Name="topButton" Width="26" VerticalAlignment="Top"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}" IsEnabled="False" >
<StackPanel>
<Image>
<Image.Style>
<Style TargetType="Image">
<!-- If you are using the Image as a Resource, you should use the following format.-->
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=topButton, Path=Button.IsEnabled}" Value="True">
<Setter Property="Image.Source" Value="assemblyname;component/Images/MoveFirst_Enabled.bmp" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=topButton, Path=Button.IsEnabled}" Value="False">
<Setter Property="Image.Source" Value="assemblyname;component/Images/MoveFirst_Disabled.bmp" />
</DataTrigger>
</Style.Triggers>
<!-- If you are using the Image as Content then you should use the below format.-->
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=topButton, Path=Button.IsEnabled}" Value="True">
<Setter Property="Image.Source" Value="Images/MoveFirst_Enabled.bmp" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=topButton, Path=Button.IsEnabled}" Value="False">
<Setter Property="Image.Source" Value="Images/MoveFirst_Disabled.bmp" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackPanel>
</Button>
I hope it may help you...

Resources