Conditional Trigger is it possible? - wpf

I have a situation where I need to check a property "HasDelivered" if true.
the foreground color of my textBlock should be green else red.
Any ideas or suggestions

Use a style with a data trigger:
<TextBlock ...>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding HasDelivered}" Value="True">
<Setter Property="Foreground" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>

Related

How to do this style while the variable is null?

I binded a string variable named FP to a textbox's text beaucase I want to show the FP in textbox.
And now i want to do this:
if the variable FP is null,change the textbox's background to red,and change textbox's text to "Warning!Your string is null".
How can I do it?Thank you!
You could use a Style with a DataTrigger:
<TextBox Text="{Binding FP, TargetNullValue='Warning!Your string is null'}">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding FP}" Value="{x:Null}">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Edit:
I tried,it works~but another question is:if the FP is empty but not null,it not works.How can I solve this?
Try this then:
<TextBox>
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Text" Value="{Binding FP}" />
<Style.Triggers>
<DataTrigger Binding="{Binding FP}" Value="">
<Setter Property="Text" Value="Warning! Your string is empty" />
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

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>

Eliminate duplicate DataTrigger logic

I have a status bar that, via data binding and triggers, shows whether a user is connected to a server. I'm styling two different elements to achieve this: the actual StatusBarItem to set a colored background (red, green, yellow), and a TextBlock inside to display the text ("Not Connected", "Connected" etc.) As I'm doing this in XAML, I have to duplicate the DataTrigger logic across two styles (to update the background in one and text in another), like so:
<StatusBarItem Grid.Column="0" HorizontalAlignment="Left" Padding="10,0,10,0">
<StatusBarItem.Style>
<Style TargetType="StatusBarItem">
<Setter Property="Background" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.NotConnected}">
<Setter Property="Background" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.Connected}">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.OfflineMode}">
<Setter Property="Background" Value="Goldenrod" />
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Style>
<TextBlock Width="Auto" Height="Auto">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="Not Connected" />
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.NotConnected}">
<Setter Property="Text" Value="Not Connected" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.Connected}">
<Setter Property="Text" Value="Connected to Perforce" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.OfflineMode}">
<Setter Property="Text" Value="Offline Mode" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StatusBarItem>
Question: is there a way to compress this code and not duplicate the DataTrigger logic?
Please note that I'm not interested in solutions that make the TextBlock fill out the entire StatusBarItem. Sure, that would solve this particular issue (I'd just style the TextBlock for both background color and text). But it doesn't address the issue at large (duplicate code that has to be updated in two places).
In this particular case you could set the Content property using the DataTriggers in the StatusBarItem style instead of using an explicit TextBlock as the Content:
<StatusBarItem Grid.Column="0" HorizontalAlignment="Left" Padding="10,0,10,0">
<StatusBarItem.Style>
<Style TargetType="StatusBarItem">
<Setter Property="Background" Value="Red" />
<Setter Property="Content" Value="Not Connected" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.NotConnected}">
<Setter Property="Background" Value="Red" />
<Setter Property="Content" Value="Not Connected" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.Connected}">
<Setter Property="Background" Value="Green" />
<Setter Property="Content" Value="Connected to Perforce" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ConnectionStatus}" Value="{x:Static local:EConnectionStatus.OfflineMode}">
<Setter Property="Background" Value="Goldenrod" />
<Setter Property="Content" Value="Offline mode" />
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Style>
</StatusBarItem>
Another option would be to define your own custom ControlTemplate for the StatusBarItem and use ControlTemplate.Triggers to change the background and the text in one place.

Change ListView item base on condition

I have ListView with my object and one of my object properties is of bool value:
<GridViewColumn Width="100" Header="FileCheck " DisplayMemberBinding="{Binding IsFileOK}" />
Instead of displaying this variable value (true or false) how can I replace this with my own text and my own color ?
For example:
File is OK // green color
File damage // red color
This is what i have try:
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFileOK}" Value="false">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding IsFileOK}" Value="true">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
Try this one
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFileOK}" Value="False">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding IsFileOK}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
Idea is to modify the background and text using Style and Triggers.
e.g.
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="Blue"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</ListView.Resources>
So you can replace Trigger with DataTrigger to use properties from view model.
Use below code to achieve this,
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="Blue"></Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsFileOK}" Value="True">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>

WPF listview. How to support simultaneously row background color and alternateIndex for this row

I have a listview that contains log messages. I want to set the background color for each row in listview according to the severity of its corresponding entry. I do this using DataTrigger (see the example).
I would also like to support AlternationIndex for listview.
How can I combine them in xaml DataTrigger abd Trigger for background color of row?
For set background color for row I use the following code:
<ListView ... >
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Severity} Value="Info">
<Setter
Property="Background"
Value="{Binding Path=Severity,
Converter=
{StaticResource msgSeverityToColorConverter}}"
/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Severity} Value="Error">
<Setter
Property="Background"
Value="{Binding Path=Severity,
Converter=
{StaticResource msgSeverityToColorConverter}}"
/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
And for AlternateIndex I have the following code:
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
</Style.Triggers>
I need that when row with message is not Info or Error, it will be of color from AlternationIndex property.
It's all due to order of declarations of triggers. First declare the alternation triggers and then the severity triggers.
<Style.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="LightBlue"></Setter>
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="2">
<Setter Property="Background" Value="LightGray"></Setter>
</Trigger>
<DataTrigger Binding="{Binding Path=Severity} Value="Info">
<Setter Property="Background"
Value="{Binding Path=Severity,
Converter="{StaticResource msgSeverityToColorConverter}}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Severity} Value="Error">
<Setter Property="Background"
Value="{Binding Path=Severity,
Converter="{StaticResource msgSeverityToColorConverter}}" />
</DataTrigger>
</Style.Triggers>

Resources