WPF binding: Set Listbox Item text color based on

2019-01-19 00:48发布

问题:

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?

回答1:

    <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