locked
How to change text foreground based on value ( C# + XAML App) RRS feed

  • Question

  • I have a simple text box inside a stackpanel as

    <DataTemplate x:Key="ItemTemplate">
                <Grid HorizontalAlignment="Left" Width="250" Height="250">
                    <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                        <StackPanel>
                            <TextBlock Text="{Binding Result}" Style="{StaticResource TextStyle1}" Height="30" Margin="5,0,5,0" Foreground="#00FFFF"/>
                        </StackPanel>
                    </Border>
                    
                </Grid>
            </DataTemplate>

    The possible values for 'Result'  is Late, Arrived and NA. I want to know how to accomplish below.

    If Result is A, make font color of above text block as Red, if B then Green, and If C then Yellow. I tried to look in existing questions and did not get a straight and simple answer. Is there a tutorial or blog published on how to accomplish this. Please note that the value of 'Result' is returned by a method when the page loads so there is button or selection etc needs to be done to make colors change, its purely based on data coming from backend when the page loads. Thanks much in advance.


    Jay

    Saturday, January 25, 2014 8:35 AM

Answers

  • You can create your converter in a separate class file.

    If you want to reuse your converter, add your converter in your Application Resources (App.xaml).

    <Application
        x:Class="App1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:localData="using:App1.Data">
    
        <Application.Resources>
            <!-- Application-specific resources -->
    
            <local:ResultToBrushConverter x:Key="ResultToBrushConverter"/>
            <x:String x:Key="AppName">App1</x:String>
    
        </Application.Resources>
    </Application>
    

    Some informations about ResourceDictionary and StaticResource :

    http://msdn.microsoft.com/en-us/library/windows/apps/hh758287.aspx

    http://msdn.microsoft.com/en-us/library/windows/apps/hh700351.aspx

    • Marked as answer by Jay JP Saturday, January 25, 2014 11:28 PM
    Saturday, January 25, 2014 10:19 PM

All replies

  • One way to achieve this is to use a converter :

    1. Create a converter with your own logic.

    public class ResultToBrushConverter : IValueConverter
        {
            // This converts the result object to the foreground.
            public object Convert(object value, Type targetType,
                object parameter, string language)
            {
                // Retrieve the format string and use it to format the value.
                string text = value as string;
                
                switch(text)
                {
                        //Implement your logic here
                    case "Late":
                        return new SolidColorBrush(Colors.Red);
                    case "Arrived":
                        return new SolidColorBrush(Colors.Green);
                    case "NA":
                        return new SolidColorBrush(Colors.Yellow);
                    default:
                        return new SolidColorBrush(Colors.Black);
                }
            }
    
            // No need to implement converting back on a one-way binding 
            public object ConvertBack(object value, Type targetType,
                object parameter, string language)
            {
                throw new NotImplementedException();
            }
        }

    2. Declare a converter in your page resources :

        <Page.Resources>
            <local:ResultToBrushConverter x:Key="ResultToBrushConverter"/>
        </Page.Resources>

    3. Use it in your datatemplate: 

    <DataTemplate x:Key="ItemTemplate">
                <Grid HorizontalAlignment="Left" Width="250" Height="250">
                    <Border Background="{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
                        <StackPanel>
                            <TextBlock Text="{Binding Result}" Style="{StaticResource TextStyle1}" 
                                       Height="30" Margin="5,0,5,0" 
                                       Foreground="{Binding Result, Converter={StaticResource ResultToBrushConverter}}"/>
                        </StackPanel>
                    </Border>
                </Grid>
            </DataTemplate>

    Let me know if you need more explanations.

    Saturday, January 25, 2014 2:14 PM
  • When I write below in standardStyles.xaml, it says The attachable property 'Resources' was not found in type page.

    <Page.Resources>
            <local:ResultToBrushConverter x:Key="ResultToBrushConverter"/>
        </Page.Resources>
    I did change xaml in mypage.xaml BUT not sure where should I create this class (inside mypage.xaml.cs or as a separate class file)... or should I be putting it to common folder under root folder.

    Jay

    Saturday, January 25, 2014 7:05 PM
  • You can create your converter in a separate class file.

    If you want to reuse your converter, add your converter in your Application Resources (App.xaml).

    <Application
        x:Class="App1.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:localData="using:App1.Data">
    
        <Application.Resources>
            <!-- Application-specific resources -->
    
            <local:ResultToBrushConverter x:Key="ResultToBrushConverter"/>
            <x:String x:Key="AppName">App1</x:String>
    
        </Application.Resources>
    </Application>
    

    Some informations about ResourceDictionary and StaticResource :

    http://msdn.microsoft.com/en-us/library/windows/apps/hh758287.aspx

    http://msdn.microsoft.com/en-us/library/windows/apps/hh700351.aspx

    • Marked as answer by Jay JP Saturday, January 25, 2014 11:28 PM
    Saturday, January 25, 2014 10:19 PM
  • Great, many thanks, that worked like charm. Let me recap what I did so that it helps others as well. All kudos to @Guillaume Salles !

    MyPage.XML will have below tag, which in plain English says that text color (foreground) depends on resource name as ResultToBrushConverter

     <TextBlock Text="{Binding result}" Foreground="{Binding result, Converter={StaticResource ResultToBrushConverter}}"/>
    

    The App.xaml have below code, which defines that this ResultToBrushConverter is a local resource

    <!-- Application-specific resources -->
                <local:ResultToBrushConverter x:Key="ResultToBrushConverter"/>
                <x:String x:Key="AppName">Data Quality Tool</x:String>

    The class file have below have same binding to variable result in case statement. So you see all three of them are connected to each other now and work.

    using System;
    using Windows.UI;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Media;
    
    
    namespace MyApp
    {
        public class ResultToBrushConverter : IValueConverter
        {
            // This converts the result object to the foreground.
            public object Convert(object value, Type targetType,
                object parameter, string language)
            {
                // Retrieve the format string and use it to format the value.
                string result= value as string;
    
                switch (result)
                {
                    //Implement your logic here
                    case "Arrived":
                        return new SolidColorBrush(Colors.Green);
                    case "Late":
                        return new SolidColorBrush(Colors.IndianRed);
                    case "OntheWay":
                        return new SolidColorBrush(Colors.Yellow);
                    default:
                        return new SolidColorBrush(Colors.Black);
                }
            }
    
            // No need to implement converting back on a one-way binding 
            public object ConvertBack(object value, Type targetType,
                object parameter, string language)
            {
                throw new NotImplementedException();
            }
        }
    }
    


    Jay

    Saturday, January 25, 2014 11:28 PM