struct
class that records a value and a check, which simply says whether it is good or bad. public enum StressCheck
{
Good,
Bad
}
public struct Stress
{
public Stress(double stressValue, StressCheck check)
{
StressValue = stressValue;
Check = check;
}
public double StressValue { get; set; }
public StressCheck Check { get; set; }
}
TextBlock
whose background becomes red when the value is 'Bad'. This is what I am doing at the moment in the XAML of my user control.<UserControl x:Class="ScienceProgram.UserControls.DataCellCheck"
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"
x:Name="parent">
<UserControl.Resources>
<Style x:Key="CheckStress" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=TB,Path=Text}" Value="Good">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=TB,Path=Text}" Value="Bad">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid Margin="1" DataContext="{Binding ElementName=parent}" Width="100">
<TextBlock Style="{StaticResource CheckStress}" Text="{Binding Path=Value}" />
<TextBlock x:Name="TB" Text="{Binding Path=Check}" Visibility="Collapsed"/>
</Grid>
and the standard code-behind for dependency objects "Value" and "Check"
public partial class DataCellCheck : UserControl
{
public DataCellCheck()
{
InitializeComponent();
}
public static readonly DependencyProperty ValueProp =
DependencyProperty.Register("Value", typeof(string),
typeof(DataCellCheck), new PropertyMetadata(""));
public string Value
{
get { return GetValue(ValueProp) as String; }
set { SetValue(ValueProp, value); }
}
public static readonly DependencyProperty StatusProp =
DependencyProperty.Register("Check", typeof(string),
typeof(DataCellCheck), new PropertyMetadata(""));
public string Check
{
get { return GetValue(StatusProp) as String; }
set { SetValue(StatusProp, value); }
}
}
Background
color of my displayed TextBlock
by binding it to a collapsed Texblock
, in which I bind the StressCheck
value from the viewModel in the following manner. public class TestViewModel : BindableBase
{
public Stress MyFirstStress { get; set; }
public TestViewModel()
{
MyFirstStress = new Stress(1245, StressCheck.Fail);
}
public double DisplayStressValue => MyFirstStress.StressValue;
public string DisplayStressCheck => MyFirstStress.Check.ToString();
}
and in XAML
<UserControl x:Class="ScienceProgram.Views.TestView"
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:ScienceProgram.Views"
xmlns:uc="clr-namespace:ScienceProgram.UserControls"
mc:Ignorable="d"
d:DesignHeight="1200" d:DesignWidth="811">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="65"/>
</Grid.RowDefinitions>
<StackPanel>
<uc:DataCellCheck Value="{Binding Path=DisplayStressValue }" Check="{Binding Path=DisplayStressCheck}"/>
</StackPanel>
</Grid>
</UserControl>
StressCheck
and hide it in another textblock?Many many thanks.
is there a better way to trigger the color change in the displayed textblock, without having to bind StressCheck and hide it in another textblock?
I should hope so. The way you're doing it now is very kludgy.
Without a Minimal, Complete, Verifiable code example, it's impossible to confirm that this would work in your exact scenario, but it should. You can just bind to the Check
property in the trigger instead of the other TextBlock
:
<Style x:Key="CheckStress" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Check}" Value="Good">
<Setter Property="Background" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding Check}" Value="Bad">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
For what it's worth, I prefer to include a setter for one value and use triggers for the other (or others, if there are multiple):
<Style x:Key="CheckStress" TargetType="TextBlock">
<Setter Property="Background" Value="Green"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Check}" Value="Bad">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
Either way, WPF handles enum
types implicitly, parsing a provided text value as the actual enum value and using it for the trigger's comparison. You don't need the extra TextBlock
or other mechanism (such as a converter) to translate between the text you put in the XAML and the actual enum
values.
If the above doesn't address your problem, please improve the question by providing a good MCVE so that the full context of your scenario can be understood.