WPF Setting Image.Source from DataTrigger - wpf

I'm trying to define a DataTrigger for an Image element so that it shows a connected/disconnected image. I keep getting an Invalid PropertyDescriptor message. Any ideas?
<Image>
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static my:Server.Instance}, Path=Connected, Mode=OneWay}"
Value="True">
<Setter Property="Source"
Value="serverconnected.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>

I just changed Property="Source" to Property="Image.Source" and it's working. Thanks everyone

Add a BitmapImage to your resources like so:
<BitmapImage x:Key="serverConnected" UriSource="serverconnected.png" />
And change your existing code to refer to it:
<Image>
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Source={x:Static my:Server.Instance}, Path=Connected, Mode=OneWay}"
Value="True">
<Setter Property="Source"
Value="{StaticResource serverConnected}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>

Related

Toggle button - change icon on click

I have an app in WPF. I am using entypo icons and i decalred one as a resource:
<Grid.Resources>
<iconPacks:Entypo x:Key="PlayIcon" Width="50" Height="30" Kind="ControllerPlay"></iconPacks:Entypo>
</Grid.Resources>
Let's say I have two icons like this ( play/pause icon) and I want to change between them when the user clicks on ToggleButton. I came up with something like this, but unfortunately, it's not working:
<ToggleButton>
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=IsChecked}"
Value="true">
<Setter Property="Source"
Value="{StaticResource PauseIcon}" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton}, Path=IsChecked}"
Value="false">
<Setter Property="Source"
Value="{StaticResource PlayIcon}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</ToggleButton>
Could anyone tell me if I can achieve it like this (with slight modifications) or point me into right direction?
You can't set the Source of an Image to a PackIconEntypo. Set the Content property of the ToggleButton instead:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content" Value="{StaticResource PlayIcon}" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Content" Value="{StaticResource PauseIcon}" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>

DataTriger Style Setter for Image Element

I have an image element that is populated via databinding - if the binding returns a path, the image is drawn. If not (path comes in an an empty string), we get no image.
<Image Source="{Binding Path=.Screenshot, Mode=OneWay}" Stretch="Fill" Margin="5,5,5,5" />
That works well, except that the margin is applied to the layout no matter what (which looks bad for empty images). I figured I'd do a DataTrigger instead that only applies the margin is the path is not empty, but:
Image doesn't seem to have a Style (actually it does, ignore this part)
I don't know how to test for "string is not empty".
What I'd like to do is something like the pseudo-XAML below. Is that possible in XAML?
<Image Source="{Binding Path=.Screenshot, Mode=OneWay}" Stretch="Fill" >
<Image.Style>
<Style TargetType="Image">
<Setter Property="Margin" Value="0,0,0,0" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=.Screenshot}" Value="!NullOrEmpty">
<Setter Property="Margin" Value="5,5,5,5" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
Should I be maybe using an entirely different approach for this?
Do it the other way round, by having a DataTrigger for the values null and "":
<Style TargetType="Image">
<Setter Property="Margin" Value="5,5,5,5" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Screenshot}" Value="{x:Null}">
<Setter Property="Margin" Value="0,0,0,0" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Screenshot}" Value="">
<Setter Property="Margin" Value="0,0,0,0" />
</DataTrigger>
</Style.Triggers>
</Style>
You may probably also just have a Trigger on the Images's Source property:
<Style TargetType="Image">
<Setter Property="Margin" Value="5,5,5,5" />
<Style.Triggers>
<Trigger Property="Source" Value="{x:Null}">
<Setter Property="Margin" Value="0,0,0,0" />
</Trigger>
</Style.Triggers>
</Style>

WPF RelativeSource issue with nested controls

I have the following markup:
<Button Name="m_SaveButton" Command="{Binding SaveCommand}">
<StackPanel>
<Image Source="{StaticResource IconSave16}">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}}" Value="False">
<Setter Property="Source" Value="{StaticResource IconSaveInactive16}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Label Content="Save" />
</StackPanel>
</Button>
I want to change the Image nested inside the Button when Button.IsEnabled is false. The markup above is not working.
I was trying to use Meleak's code found here: WPF Mouseover Trigger Effect for Child Controls
Does anyone can suggest me a solution for this?
Thank you in advance!
You can't change a local value in style because of Value Precedence. This should work.
<Image>
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source" Value="{StaticResource IconSave16}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}}" Value="False">
<Setter Property="Source" Value="{StaticResource IconSaveInactive16}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>

WPF: Simplest of DataTriggers

I'm just trying to learn DataTriggers. What's wrong with this simple code? It tells me that "Source" is not a property of FrameworkElement.
<Image>
<Image.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Sent">
<Setter Property="Source" Value="Resources\Approve_64_Trans.bmp"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="SendFailed">
<Setter Property="Source" Value="Resources\Cancel_64_Trans.bmp"/>
</DataTrigger>
</Image.Triggers>
</Image>
Also, is it correct to use a value "SendFailed" or "Sent" when the Status field is of enum type and SendFailed and Sent are two valid enum values?
You need to put that kind of trigger in a style, like so:
<Image>
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Sent">
<Setter Property="Source" Value="Resources\Approve_64_Trans.bmp"/>
</DataTrigger>
<DataTrigger Binding="{Binding Status}" Value="SendFailed">
<Setter Property="Source" Value="Resources\Cancel_64_Trans.bmp"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>

WPF Image Style Trigger - small issue

i'm having a small issue with an style trigger on an image. The trigger does change the source of the image, but when it does i lose the streght="fill" property. I've also tried setting it in the trigger, but it seem to ignore it. What am i missing here?
<Image x:Name="xBackground"
Height="99.5"
Width="271"
Stretch="Fill">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="Green.png" />
<Style.Triggers>
<DataTrigger Binding="{Binding HasAlarm}" Value="true">
<Setter Property="Source" Value="Red.png" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>

Resources