Change the Foreground of certain items in a ListBox, via Style, using a Converter?

1

I have ListBox where the data source is ObservableCollection<string> .

I would like the items that started with "WARNING" to have the red font.

I would be able to do this using a DataTemplate , a Converter and a template to apply to a Label or TextBlock .

But since I do not have DataTemplate it has changed the scenario. Would you like to add Binding and Convert to a Setter of style?

<ListBox x:Name="lstLog" Height="160" Width="775">
         <ListBox.ItemContainerStyle>
             <Style TargetType="ListBoxItem">
                  <Setter Property="Height" Value="19" />
             </Style>
          </ListBox.ItemContainerStyle>
 </ListBox>

Converting I know it would look something like this:

public class CorLogConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value.ToString().StartsWith("ATENÇÃO"))
             return new SolidColorBrush(Colors.Red);
        else
             return new SolidColorBrush(Colors.Black);
    }     
}
    
asked by anonymous 01.09.2016 / 19:47

2 answers

2

EDIT

The solution is to get a way to get the Path that represents the item being rendered.

Contrary to what I said this is possible.

Just do not indicate Path in the <Binding> tag or use <Binding Path="."> , the dot represents the path of the current source

<ListBox x:Name="lstLog" Height="160" Width="775">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Height" Value="19" />

            <Setter Property="Foreground">
                <Setter.Value>
                    <Binding>
                        <Binding.Converter>
                            <testeWpf:CorLogConverter/>
                        </Binding.Converter>
                    </Binding>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

----------------------------------------------- ------------------------------

I may be wrong but it is not possible.

To do the Binding you need a Path and then get Value . The problem is there, there is no way to get the Path to represent the item being rendered.

The only item you can access is the selected item.

The following example changes the text color of all items when one is selected that begins with WARNING:

<ListBox x:Name="lstLog" Height="160" Width="775" IsSynchronizedWithCurrentItem="True">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Height" Value="19" />

            <Setter Property="Foreground">
                <Setter.Value>
                    <Binding ElementName="lstLog" Path="Items/">
                        <Binding.Converter>
                            <testeWpf:CorLogConverter/>
                        </Binding.Converter>
                    </Binding>
                </Setter.Value>
            </Setter>

        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

Something similar can be obtained by using a DataTrigger :

<ListBox x:Name="lstLog" Height="160" Width="775" IsSynchronizedWithCurrentItem="True">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Height" Value="19" />

            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=lstLog, Path=Items/}" Value="ATENÇÃO">
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger>
            </Style.Triggers>

        </Style>
    </ListBox.ItemContainerStyle>
</ListBox> 
    
02.09.2016 / 00:40
0

I was able to resolve by continuing to use my ObservableCollection<string> without using a model , it was sufficient that no Binding left me blank. I was accustomed to using for example " Binding nomePropriedade, Converter = .... ". However I had to use the DataTemplate:

View

<ListBox x:Name="lstLog" Height="160" Width="775">
     <ListBox.ItemTemplate>
         <DataTemplate>
             <TextBlock Text="{Binding}" Foreground="{Binding Converter={StaticResource localConverterCorLog}}"  />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

View.cs

this.arrLog = new ObservableCollection<string>();
lstLog.ItemsSource = this.arrLog;

Converter

I actually needed red when I had "WARNING"

public class ConverterCorLog : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null && value.ToString().Contains("ATENÇÃO"))
            return new SolidColorBrush(Colors.Red);
        else
            return new SolidColorBrush(Colors.Black);

    }

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

App.xaml

<classes:ConverterCorLog x:Key="localConverterCorLog" />
    
02.09.2016 / 14:08