Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

c# - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
    <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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...