Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF binding: Set Listbox Item text color based on property

I'm sure this is probably something basic in WPF but I'm new to XAML syntax I'm trying to wrap my head around it.

The Setup

I have a LogItem Type -- just a POCO:

public class LogItem
{ 
    public string Message {get;set;}
    public Color MessageColor {get;set;}
}

and a List of LogItem in my ViewModel:

    private ObservableCollection<LogItem> _logItems; 
    public ObservableCollection<LogItem> LogItems
    {
        get { return _logItems; }
        set
        {
            if (value != _logItems)
            {
                _logItems = value;
                OnPropertyChanged("LogItems");
            }
        }
    }

My viewmodel is bound to the view so that I can do the following:

<ListBox Grid.Row="0" Margin="0,10,0,0" Grid.ColumnSpan="3" Height="150" ItemsSource="{Binding LogItems}">

(Obviously I still have to set the display text binding, etc.)

The Question

Given that I have a Message and MessageColor property in LogItems, what is the correct XAML syntax to bind the color of the item text to the color I specify?

like image 391
SeanKilleen Avatar asked Sep 24 '13 12:09

SeanKilleen


1 Answers

    <ListBox Grid.Row="0" Margin="0,10,0,0" Grid.ColumnSpan="3" Height="150" ItemsSource="{Binding LogItems}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Message}" Foreground="{Binding MessageColor}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

TextBlock Foreground expects a Brush not a Color. Like a lot of things in WPF, There are lot's of ways to approch this. Here is a couple:

  1. Change to MessageColor property in your viewModel to Brush

    Brush MessageColor {get;set;}
    
  2. Create a SolidColorBrush and bind it to your color

      <TextBlock Text="{Binding Message}">
          <TextBlock.Foreground>
             <SolidColorBrush Color="{Binding MessageColor}"/>
          </TextBlock.Foreground>
      </TextBlock>
    
  3. Create a ColorToBrushConverter

    public class ColorToBrushConverter : IValueConverter
    {
          #region IValueConverter Members
    
          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
                 if (value == null) return Brushes.Black; // Default color
    
                 Color color = (Color)value;
    
                 return new SolidColorBrush(color);
          }
    
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
                 throw new NotImplementedException();
          }
    
          #endregion
    }
    

In xaml, create the converter as static resource

<Window.Resources>
    <local:ColorToBrushConverter x:Key="colorToBrushConverter"/>
</Window.Resources>

use it in the binding

<TextBlock Text="{Binding Message}" Foreground="{Binding MessageColor, Converter={StaticResource colorToBrushConverter}"/>

Good luck

like image 88
Omri Btian Avatar answered Sep 21 '22 03:09

Omri Btian