ListViewItem не меняет цвет переднего плана с привязанным IValueConverter
Моя проблема в том, что я хочу, чтобы мой WPF ListView отображал ListViewItems разными цветами в соответствии с привязанными к ним элементами. Ниже приведен весь код для воспроизведения проблемы. В приложении есть виджеты, которые "есть в наличии" или нет. Если они есть в наличии, они должны иметь зеленый текст в ListView, иначе красный. Раскраска выполняется моим BoolToColorConverter (преобразование Widget.InStock в Colors.Green или Colors.Red). Точки останова уверяют меня, что Convert() находится под ударом. Я, вероятно, делаю что-то явно не так, но я в растерянности, так как жесткое программирование цвета переднего плана работает, как и ожидалось. Заранее спасибо.
MainWindow.xaml
<Window x:Class="ListViewItemColors.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ListViewItemColors" Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:WidgetsViewModel />
</Window.DataContext>
<Window.Resources>
<local:BoolToColorConverter x:Key="BoolToColor" />
</Window.Resources>
<DockPanel >
<ListView ItemsSource="{Binding Path=Widgets }">
<ListView.View>
<GridView>
<GridViewColumn Width="150" Header="Widget Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" Foreground="{Binding Path=InStock, Converter={StaticResource BoolToColor}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="50" Header="Size" DisplayMemberBinding="{Binding Size}"></GridViewColumn>
<GridViewColumn Width="75" Header="In Stock?" DisplayMemberBinding="{Binding InStock}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</DockPanel>
BoolToColorConverter.cs
public class BoolToColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = (bool)value;
return val ? Colors.Green : Colors.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
WidgetsViewModel.cs
public class WidgetsViewModel
{
public WidgetsViewModel()
{
Widgets = new Widgets
{
new Widget {InStock = true, Name = "Flipper", Size = 10},
new Widget {InStock = false, Name = "Gizmo", Size = 6},
new Widget {InStock = true, Name = "Gizmo", Size = 8},
new Widget {InStock = true, Name = "Whirlygig", Size = 15},
new Widget {InStock = false, Name = "Gutter", Size = 1},
new Widget {InStock = false, Name = "Gutter", Size = 2}
};
}
public Widgets Widgets { get; set; }
}
Widget.cs
public class Widget : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged("Name");
}
}
private int _size;
public int Size
{
get { return _size; }
set
{
if (_size == value) return;
_size = value;
OnPropertyChanged("Size");
}
}
private bool _inStock;
public bool InStock
{
get { return _inStock; }
set
{
if (_inStock == value) return;
_inStock = value;
OnPropertyChanged("InStock");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
}
Widgets.cs
public class Widgets : ObservableCollection<Widget> { }
2 ответа
Свойство TextBlock.Foreground принимает Brush
не Color
, Измените свой конвертер, чтобы он возвращал SolidColorBrush
Например:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var val = (bool)value;
return new SolidColorBrush(val ? Colors.Green : Colors.Red);
}
Это сработало для меня:
enter code here
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Foreground"
Value="{Binding FColor,Mode=OneWay,UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ColorConverter}}"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Header="Category"
DisplayMemberBinding="{Binding CatDesc,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"
Width="450"/>
</GridView>
</ListView.View>