Изменение цвета текста у элемента в ListBox в зависимости от значения enum

Смысл таков, по мере работы программы, она добавляется новый элемент в коллекцию Items. Например если всё нормально - выводится сообщения с типом Default. Если возникла ошибка - на экране в ListBox появлется новый элемент с красным текстом о том, что что-то не получилось. Если есть другие способы, то я не против их использовать. Т.е на экране будет своеобразная "радуга" из текста.

Есть Model:

class Model
{
    public enum State
    {
        Default = 0x000000, //black
        Success = 0x00FF00, //green
        Warning = 0xFFA500, //orange
        Error = 0xFF0000, //red
    }
    public State LogState { get; set; }

    public string Message { get; set; }
}

Есть xaml:

<Window.Resources>
     <local:StateToColorConverter x:Key="StateToColor"></local:StateToColorConverter>
</Window.Resources>

<!-- Не работает, а надо, чтобы работало -->
<ListBox ItemsSource="{Binding Items}" Foreground="{Binding Items/LogState, Converter=StateToColor}"/> 

Есть VM

class ViewModel
{
    
    public ObservableCollection<Model> Items {get; set;}

    public ViewModel()
    {
        Items = new ObservableCollection<Model>();
        Items.Add(new Model { LogState = Model.State.Error, Message = "Ошибка" });
    }
}

Так же реализовал IValueConverter, но как его применить через <Window.Resources> коллекции не знаю.

class StateToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Model.State status = (Model.State)value;
        var color = new SolidColorBrush(Colors.White);

        switch (status)
        {
            case Model.State.Error:
                    color = new SolidColorBrush(Color.FromRgb(255, 0, 0));
                    break;
            case Model.State.Success:
                    color = new SolidColorBrush(Color.FromRgb(0, 255, 0));
                    break;

        }

        return color;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Ответы (1 шт):

Автор решения: aepot

Не используйте вложенные типы. Не нужно в Enum зашивать цвета, за это должна не модель отвечать, а UI

public enum Severity
{
    Default,
    Success,
    Warning,
    Error
}

public class LogMessage
{
    public Severity Severity { get; set; }

    public string Message { get; set; }
}

Использовать это точно так же

public class ViewModel
{
    public ObservableCollection<LogMessage> Items { get; }

    public ViewModel()
    {
        Items = new ObservableCollection<LogMessage>();
        Items.Add(new LogMessage { Severity = Severity.Error, Message = "Ошибка" });
    }
}

А все фокусы с раскрашиванием реализуются в UI XAML. Кстати, зачем вам ListBox вы выбирать сообщение хотите или только смотреть?

<ScrollViewer VerticalScrollBarVisibility="Auto">
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Message}">
                    <TextBlock.Style>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Foreground" Value="Black"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Severity}" Value="Success">
                                    <Setter Property="Foreground" Value="Green"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Severity}" Value="Warning">
                                    <Setter Property="Foreground" Value="Orange"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding Severity}" Value="Error">
                                    <Setter Property="Foreground" Value="Red"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBlock.Style>
                </TextBlock>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ScrollViewer>

Всё. Никаких конвертеров не нужно.

→ Ссылка