Why is this WPF Button background not changing behind an image? - c#

My squares are either SaddleBrown or WhiteSmoke in color, shifting to DarkTurquoise when selected. This works when there is no image on top of the squares. When I have a (PNG) image on top of the square the original SaddleBrown/WhiteSmoke color shows behind it but when the color is supposed to change to DarkTurquoise nothing happens to the background color of the square.
What could be the problem?
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="Square"
Command="{Binding DataContext.BoardGUI.SquareClickCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<Image Source="{Binding Source, Converter={StaticResource NullImageConverter}}"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding SquareColor}" Value="Dark">
<Setter TargetName="Square" Property="Background" Value="SaddleBrown"/>
</DataTrigger>
<DataTrigger Binding="{Binding SquareColor}" Value="White">
<Setter TargetName="Square" Property="Background" Value="WhiteSmoke"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="Square" Property="Background" Value="DarkTurquoise"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>

As determined in the comments, based on the screenshot and the definition of the triggers, it appears that "SquareColor" is likely getting set or changed after IsSelected is set.

Related

Add style to border (parent element) when checkbox is selected WPF

I'm trying to add differences style to the border when the radio button is checked and not checked. Is there anyway to do this in xaml with binding?
<Border
Width="672"
Height="122"
HorizontalAlignment="Left">
<RadioButton
Margin="0,0,0,8"
HorizontalAlignment="Left"
VerticalAlignment="Top"/>
</Border>
This is what i'm doing now but it doesnt work for me yet
<Border.Style>
<Style TargetType="{x:Type Border}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Child.Children[0].IsChecked}" Value="true">
<Setter Property="Background" Value="red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>

WPF Changing Image in Button Template

I'm trying to create a button template where the button image content changes. However, I get no image showing at all with the following code. What am I doing wrong? Setting the style directly in the Page xaml works fine.
<Style x:Key="NetworkConnectivity" TargetType="Button">
<Setter Property="Width" Value="120"/>
<Setter Property="Height" Value="120"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Opacity" Value="0.7"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Width="50">
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding NetConfig}" Value="false">
<Setter Property="Image.Source" Value="/images/Unconfigured.png"/>
</DataTrigger>
<DataTrigger Binding="{Binding NetConfig}" Value="true">
<Setter Property="Image.Source" Value="/images/Disconnected.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Not the exact solution but an alternative. Below is a excerpt from my work that shows how to switch images for buttons based on triggers. Instead of style, I use a usercontrol which is reused. The data that are bound are dependency properties. You can use data trigger. In your case assign two images, make one collapsed and on trigger toggle collapse.
<UserControl x:Class="ParameterModule.Base.Controls.ButtonWImage"
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:local="clr-namespace:ParameterModule.Base.Controls"
mc:Ignorable="d"
x:Name="UctrlButtonWImage"
d:DesignHeight="100" d:DesignWidth="100">
<Button Click="Button_Click" CommandParameter="{Binding CommandParameter, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ButtonWImage}}}" Command="{Binding Command, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ButtonWImage}}}" Cursor="Hand" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<StackPanel>
<Image x:Name="PrimaryImage" Source="{Binding PrimaryImage, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ButtonWImage}}}" Visibility="Visible" Stretch="UniformToFill" StretchDirection="Both"/>
<Image x:Name="SecondaryImage" Source="{Binding HoverImage, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ButtonWImage}}}" Visibility="Collapsed" Stretch="UniformToFill" StretchDirection="Both"/>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="PrimaryImage" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="SecondaryImage" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</UserControl>

How to toggle image based on BooleanToVisibilityConverter?

In a WPF DataGrid, I have a DataGridTemplateColumn:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image Visibility="{Binding ShowImage, Mode=OneWay, Convert{StaticResource BooleanToVisibilityConverter}}" Source="{StaticResource Image1}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
This column starts with no image. Then some processing occurs. If ShowImage is assigned true, an image is displayed. Else, nothing is displayed.
How do I toggle between two images based on the assignment to ShowImage?
Just use another converter (maybe you can call it BoolToImageCoverter) that will assign one image if ShowImage is true and a different image if ShowImage is false.
You could use another converter, or you could use Style.Triggers:
<Image Source="{StaticResource Image1}">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding ShowImage}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>

DataTrigger for IconTemplate in RadWindow

I have a WPF application and I use Telerik.
I'm trying to set the Icon Template so that it has a default value and only on a certain condition will it bind the image source:
<telerik:RadWindow.Resources>
<Style x:Key="CustomIconStyle" TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsConditionMet, ElementName=MyWindow, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="Source" Value="{Binding Path=IconImageSource, ElementName=MyWindow, UpdateSourceTrigger=PropertyChanged}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadWindow.Resources>
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Style="{StaticResource CustomIconStyle}" Source="/MyAssembly;Component/Resources/myIcon.ico" Height="16" Margin="0,0,5,0"/>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
For some reason it always show the default icon.
I would also like to mention that I did implement the property changed - and I copied the same style just to a control inside the window and not in the template and it worked - so the problem isn't with the property changed
Any ideas?
You can use Triggers like that :
<telerik:RadWindow.Resources>
<Style TargetType="Image" x:Key="Style1">
<Setter Property="Source" Value="default.ico"/>
<Style.Triggers>
<DataTrigger Binding="{Binding MyCondition}" Value="true">
<Setter Property="Source" Value="custom.ico"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadWindow.Resources>
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Style="{StaticResource Style1}" Height="16" Margin="0,0,5,0"/>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
So the problem was that once the RadWindow was loaded it didn't change the Icon.
The solution:
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Height="16" Margin="0,0,5,0">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/MyAssembly;Component/Resources/myIcon.ico" />
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsConditionMet, ElementName=MyWindow}">
<Setter Property="Source" Value="{Binding Path=IconImageSource, ElementName=MyWindow}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
But the trick is to give the correct value of IsConditionMet in the windows constructor before the load.
Thanks for the help everyone.

Use an image for a menu option in WPF

I use the following XAML to achieve a menu using radio buttons:
<Grid.Resources>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<TextBlock Text="{TemplateBinding Content}">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource AncestorType={x:Type RadioButton}}}" Value="True">
<Setter Property="Foreground" Value="Gold" />
</DataTrigger>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type RadioButton}}}" Value="True">
<Setter Property="Foreground" Value="Gold" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<StackPanel Margin="25,74,644,78" Background="{x:Null}">
<RadioButton Content="1. Do something." Click="RadioButton1_Click" FontSize="16" Margin="5"/>
<RadioButton Content="2. Do something else." Click="RadioButton2_Click" FontSize="16" Margin="5"/>
</StackPanel>
This works fine but I want to include an image as a menu option instead of text. (The image is for 'Home' and it will have a normal image and a hover over image)
Here is what I want to achieve:
How do I do this?
You can define another style for displaying Radio Button as an Image based on the existing style posted in question, just need slight changes in ControlTemplate's content part. Following is an example of such a Style and the usage :
<StackPanel Orientation="Horizontal" Background="Black">
<StackPanel.Resources>
<Style x:Key="PictSTyle" TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Image Width="50" Height="50">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="home_default.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type RadioButton}}}" Value="True">
<Setter Property="Source" Value="home_hovered.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<RadioButton Margin="5" Style="{StaticResource ResourceKey=PictSTyle}"/>
</StackPanel>
To give a menu item an image:
<MenuItem>
<MenuItem.Icon>
<Image Source=""/>
</MenuItem.Icon>
</MenuItem>
for your trigger just change the MenuItem's icon to the "highlighted one", when the user hovers over the menu item (IsMouseOver), by changing the Icon's image source.
Put an image element as the "Content" property for your radio button
<RadioButton Click=HomRadioButtonClick>
<RadioButton.Content>
<Image Source=""/>
</RadioButton.Content>
</RadioButton>
You'll need some extra logic for the hover behavior, but that should at least get the image in your menu.

Categories