I am VERY new to WPF AND C#, so there may be a much better way to accomplish what I am attempting. Therefore, I am open to other methods.
As far as what I've got, I am trying to program a Digital VMB (Visual Management Board) for the maintenance department where I work. They want a section to display the number of days our plant has gone without an accident: "Days Safe". I successfully have the binding set for this TextBlock:
<TextBlock Text="{Binding DaysSafe}" FontSize="60" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" >
I have a series of DataTriggers to change the Foreground color of the text to a certain color, based on the value of the text. Basically, I want the DaysSafe text to be:
Red when 0
Orange when 1 and so on (you can see the colors in my code below):
<StackPanel VerticalAlignment="Center" >
<TextBlock Text="{Binding DaysSafe}" FontSize="60" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" >
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers >
<DataTrigger Binding="{Binding DaysSafe}" Value="0">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="1">
<Setter Property="Foreground" Value="OrangeRed" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="2">
<Setter Property="Foreground" Value="Orange" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="3">
<Setter Property="Foreground" Value="Yellow" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="4">
<Setter Property="Foreground" Value="Yellow" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="5">
<Setter Property="Foreground" Value="GreenYellow" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
This functions correctly, the colors change when the days are lower. HOWEVER, I would like for the foreground color to "Default" to green when the value of DaysSafe is over 5. Right now, any value above 5 is black when I want it to be green. I tried adding the foreground="green" attribute in the first TextBlock section, but this overrides the DataTriggers and the foreground is always green.
Any help with how I may create a default value for the foreground?
Thanks.
You could just add a setter that sets the default Foreground of the TextBlock to Green:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Green" />
<Style.Triggers >
<DataTrigger Binding="{Binding DaysSafe}" Value="0">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="1">
<Setter Property="Foreground" Value="OrangeRed" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="2">
<Setter Property="Foreground" Value="Orange" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="3">
<Setter Property="Foreground" Value="Yellow" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="4">
<Setter Property="Foreground" Value="Yellow" />
</DataTrigger>
<DataTrigger Binding="{Binding DaysSafe}" Value="5">
<Setter Property="Foreground" Value="GreenYellow" />
</DataTrigger>
</Style.Triggers>
</Style>
Related
I have this DataGrid and I have been playing with setting the background colour of selected cells:
<DataGridTextColumn Header="Next Study" Binding="{Binding NextStudy}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="25">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip" Value="{Binding NextStudyDescription}" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
It works as you can see:
But that is not really what I want. Instead I would like to highlight all cells where the value is greater than or equal to 18. So I tried:
<DataGridTextColumn Header="Next Study" Binding="{Binding NextStudy}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{NextStudy Converter={StaticResource IsEqualOrGreaterThanConverter}, ConverterParameter=18}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ToolTip" Value="{Binding NextStudyDescription}" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
It doesn't like: <DataTrigger Binding="{NextStudy
In addition, I would like to do this background test if the element comboActiveStudentAssignmentType selected index is 0, 1 or 2. Otherwise it does not need to do this highlighting.
Thanks.
You have a syntax error: Binding is the property name, you still have to declare it as a Binding
<DataTrigger Binding="{Binding NextStudy, Converter={StaticResource IsEqualOrGreaterThanConverter}, ConverterParameter=18}" Value="True">
As for the second part of the question, you can use a MultiDataTrigger. The conditions in the MultiDataTrigger have to ALL be true for the trigger to execute the setters. You will probably need to write another converter to transform your AssignmentType to True/False and you should be set.
Here's a quick example:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding NextStudy, Converter={StaticResource IsEqualOrGreaterThanConverter}, ConverterParameter=18}" Value="True"/>
<Condition Binding="{Binding comboActiveStudentAssignmentType, Converter={StaticResource YourOtherConverter}" Value="True"/>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Background" Value="Red"/>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
I'm trying to get up to speed on how to use DataTriggers on a DataGrid.
I have four columns in my datatable (Node, Name, Value, Flag). Flag is a hidden column in the datagrid.
I would the DataGridRow to have PaleGreen background when Flag = 2 but the Value column should be red. I know that I can create a style for the flag column as thats not vislible this isn't helpful.
Sorry if this is a newbie question. First foray into wpf from WinForms.
What I have so far:
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="2">
<Setter Property="Background" Value="PaleGreen" />
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding Flag}" Value="3">
<Setter Property="Background" Value="CadetBlue" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
Figured it out. Code for completeness
<UserControl.Resources>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="2">
<Setter Property="Background" Value="PaleGreen" />
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<DataTrigger Binding="{Binding Flag}" Value="3">
<Setter Property="Background" Value="CadetBlue" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="DataGridCell" x:Key="ValueColumn">
<Style.Triggers>
<DataTrigger Binding="{Binding Flag}" Value="2">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Node" Binding="{Binding Path=Node}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}"/>
<DataGridTextColumn MinWidth="300" Header="Value" Binding="{Binding Path=Value}" CellStyle="{StaticResource ValueColumn}"/>
<DataGridTextColumn Header="Flag" Binding="{Binding Path=Flag}" Visibility="Hidden" />
</DataGrid.Columns>
</DataGrid>
I have a question on this WPF-xaml code. Haven't used xaml alot but manage to get quite what I wanted with this code. But I feel that it isn't good practise at all. First, I would like to change the row from red to green or gray depending on some values in a certain cell. Do I really have to keep one trigger for each cell, or is there anyway to do the same trigger on the whole row? I would also like to set a specific color when a row is selected, but the style doesn't seem to support "IsSelected"...
<DataGrid AutoGenerateColumns="False" IsReadOnly="True" HorizontalAlignment="Stretch" Margin="200,50,5,5" ItemsSource="{Binding}" Name="dataGrid1" VerticalAlignment="Stretch" EnableRowVirtualization="True" SelectionChanged="dataGrid1_SelectionChanged" MouseDoubleClick="dataGrid1_MouseDoubleClick">
<DataGrid.Columns>
<DataGridTextColumn Width="1*" Header="File name" Binding="{Binding Path=Filename}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen"/>
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Weight" Binding="{Binding Path=Info1}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Rfid" Binding="{Binding Path=Info1}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Date/Time" Binding="{Binding Datetime, StringFormat=\{0:yyyy.MM.dd HH:mm:ss\}}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Width="1*" Header="Error code" Binding="{Binding Path=Errorcode}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="#68FF0000" />
<Style.Triggers>
<DataTrigger Binding="{Binding Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
I'm not very experienced with DataGrid, so this might not be the best option, but I think you can achieve what you're after by styling the Row, rather than the individual Columns:
<DataGrid <!-- Your settings here -->>
<!-- Your column definitions here -->
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Errorcode}" Value="0">
<Setter Property="Background" Value="LightGreen" />
<!-- Other Setters -->
</DataTrigger>
<DataTrigger Binding="{Binding Path=Filename}" Value="File not created">
<Setter Property="Background" Value="LightGray" />
</DataTrigger>
<!-- Other Triggers -->
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red" />
<!-- Other Setters -->
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
Good luck.
I want to make a button with this trigger.However this doesn't work .Even custom datatemplte doesn't. This fails with
{"Triggers collection members must be of type EventTrigger."}
<Button cal:Message.Attach="Switch" Width="55" HorizontalAlignment="Left"
Style="{StaticResource OrderProductButton}" Margin="6,4,0,7">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="literal" Foreground="White"
xml:space="preserve">€</TextBlock>
<TextBlock Foreground="White" xml:space="preserve"> / </TextBlock>
<TextBlock x:Name="percent" Foreground="Gray"> %</TextBlock>
</StackPanel>
<Button.Triggers>
<DataTrigger Binding="{Binding IsPercent}" Value="True">
<Setter Property="TextBlock.FontWeight" Value="Bold"
TargetName="percent" />
<Setter Property="TextBlock.Foreground" Value="White"
TargetName="percent" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPercent}" Value="false">
<Setter Property="TextBlock.FontWeight" Value="Bold"
TargetName="literal" />
<Setter Property="TextBlock.Foreground" Value="White"
TargetName="literal" />
</DataTrigger>
</Button.Triggers>
</Button>
Does using a style work for you?
<Style TargetType="Button"> <!-- use a key if you want to target only specific buttons -->
<Style.Triggers>
<DataTrigger Binding="{Binding IsPercent}" Value="True">
<Setter Property="TextBlock.FontWeight" Value="Bold"
TargetName="percent" />
<Setter Property="TextBlock.Foreground" Value="White"
TargetName="percent" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPercent}" Value="false">
<Setter Property="TextBlock.FontWeight" Value="Bold"
TargetName="literal" />
<Setter Property="TextBlock.Foreground" Value="White"
TargetName="literal" />
</DataTrigger>
</Style.Triggers>
</Style>
I currently have a couple buttons in a grid that have the same xaml image style and button style. I am trying to make a grid reference to call from the style feature of the button. I can do the button style work but I am having issues coding the image style so that it is one call (new to xaml). Thanks for your help in advance.
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source"
Value="edit_32.png" />
<Setter Property="Stretch"
Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditing}"
Value="True">
<Setter Property="Source"
Value="save_smallest.png" />
<Setter Property="Stretch"
Value="Uniform" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<Button.Style>
<Style TargetType="Button">
<Setter Property="IsEnabled"
Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding CanEdit}"
Value="True">
<Setter Property="IsEnabled"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
Figured out the answer to my question. This set of code allows me to use dual style setting while creating only one call for the button's style:
<!--SaveEditImageSwitch-->
<Image x:Key="SaveEditImage" x:Shared="False">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source"
Value="edit_32.png" />
<Setter Property="Stretch"
Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditing}"
Value="True">
<Setter Property="Source"
Value="save_smallest.png" />
<Setter Property="Stretch"
Value="Uniform" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
<!--ButtonEditSaveStyle-->
<Style TargetType="Button"
x:Key="ButtonEditSaveStyle">
<Setter Property="IsEnabled"
Value="False" />
<Setter Property="Content"
Value="{DynamicResource ResourceKey=SaveEditImage}" />
<Style.Triggers>
<DataTrigger Binding="{Binding CanEdit}"
Value="True">
<Setter Property="IsEnabled"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
<Button Width="32"
Height="22"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Name="gdEmployeeInfo_btnUpdateRecord"
Click="gdEmployeeInfo_btnUpdateRecord_Click"
Style="{DynamicResource ResourceKey=ButtonEditSaveStyle}">