user3587624 user3587624 - 1 month ago 16
C# Question

How to change color of text when UI gets updated in WPF MVVM

I have the following XAML

<UserControl x:Class="DomainExperience.Pane.DomainFile.DomainAnalysisPaneResultsControl"
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:domainExperience="clr-namespace:DomainExperience"
xmlns:domainFile="clr-namespace:DomainExperience.Pane.DomainFile"
Background="{DynamicResource VsBrush.Window}"
Foreground="{DynamicResource VsBrush.WindowText}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Name="MyToolWindow">

<UserControl.Resources>
<domainFile:StatusColoredDataTemplateClass x:Key="StatusColoredDataTemplate" />
</UserControl.Resources>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>

<ListView Grid.Row="0" ItemsSource="{Binding Path=Results}">

<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Status" DisplayMemberBinding="{Binding Status}" CellTemplateSelector="{DynamicResource StatusColoredDataTemplate}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>


And then, I created the following class

using System.Windows;
using System.Windows.Controls;

namespace DomainExperience.Pane.DomainFile
{
public class StatusColoredDataTemplateClass : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// Some logic here that I haven't defined yet...
}
}
}


The intention here is to change the color of the text that goes into the Status column depending on its content. I want to have Green text when the result is Passed and red text when it is Failed.

I've read that I should create a class that implements a DataTemplateSelector. However, I am not able to hit a breakpoint in this class whenever the Panel that is related to this XAML gets updated.


  1. What is wrong in my XAML logic?

  2. Am I missing something else maybe on my ViewModel logic?

  3. What sort of code do I need to implement in my class to change the color of the text?



Thanks!

UPDATE: The Results property is associated to the following class

public class ResourceStaticAnalysisResults
{
public string Name { get; set; }
public List<string> ErrorList { get; set; }
public string Status { get; set; }
}

Answer

A DataTemplateSelector is overkill because you don't need to change the DataTemplate itself, just a property of one of its controls. Instead, you can define a single, fixed DataTemplate for that column and manage the change of color with a style:

<DataTemplate x:Key="StatusColoredDataTemplate" DataType="{x:Type system:Boolean}">
    <TextBlock Text="{Binding}">
        <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Foreground" Value="Green" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding}" Value="False">
                        <Setter Property="Foreground" Value="Red" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</DataTemplate>

And the column:

<GridViewColumn
    Header="Status"
    DisplayMemberBinding="{Binding Status}"
    CellTemplate="{StaticResource StatusColoredDataTemplate}" />