- I have a
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; }
}
- I want to create a
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); }
}
}
- So, what's happening here is that I am changing the
Background
color of my displayedTextBlock
by binding it to a collapsedTexblock
, in which I bind theStressCheck
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>
- Now, my question 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?
Many many thanks.
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 otherTextBlock
: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):
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 extraTextBlock
or other mechanism (such as a converter) to translate between the text you put in the XAML and the actualenum
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.