Изменение цвета текста у элемента в 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 шт):
Не используйте вложенные типы. Не нужно в 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>
Всё. Никаких конвертеров не нужно.