3

I'm searching how to change the background color of my WPF Listbox, nothing worked... I don't want to change the background of the Item Template, but of the ListBox himself.
I tried the differents solutions answered here Answers
Here is my Listbox :

<ListBox Name="myListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="myListBox_SelectionChanged" Background="#FFC3DDF7" Margin="0,0,0,10">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Value.IsOk}" Value="True">
                                <Setter Property="Background" Value="Green"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ListBox.ItemContainerStyle>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <StackPanel Width="200">
                                <TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Key}" />
                                <TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap">
                                    <TextBlock.Text>
                                        <MultiBinding StringFormat="{}{0} {1} {2}">
                                            <Binding Path="Value.TextA" />
                                            <Binding Path="Value.TextB" />
                                            <Binding Path="Value.TextC" />
                                        </MultiBinding>
                                    </TextBlock.Text>
                                </TextBlock>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

Maybe the item template is on the foreground ?

Tried these codes :

<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Blue"/>
    </Style.Resources>
</Style>

and

 <ListBox>
    <ListBox.Style>
        <Style TargetType="{x:Type ListBox}">
            <Style.Triggers>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Background" Value="Blue" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.Style>
</ListBox>

Not working. The down right corner, between the two scrollbars, became blue... But that's all !

betsou
  • 143
  • 3
  • 16
  • Possible duplicate of [WPF ListBox, how to hide border and change selected item background color?](https://stackoverflow.com/questions/3351904/wpf-listbox-how-to-hide-border-and-change-selected-item-background-color) – Clint Jul 05 '17 at 16:19
  • Not relater, on the answer you link the listbox items are concerned, my problem is with the listbox himself. – betsou Jul 05 '17 at 16:25
  • Where did you try to change it? I only see the items's style here... – Mishka Jul 05 '17 at 16:28
  • I will change my Question with my trys – betsou Jul 05 '17 at 16:33

3 Answers3

3

The reason why your linked answer does not work is because you have the background of the listbox set to #FFC3DDF7 on the element itself. If you wish to change the initial background color of your listbox this would need to be moved into the style. If you do not move this then the rule for "closest" defined value would be the one on the element itself and the style can't override this.

<ListBox Name="myListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="myListBox_SelectionChanged" Margin="0,0,0,10">
        <ListBox.Style>
            <Style TargetType="{x:Type ListBox}">
                <Setter Property="Background" Value="#FFC3DDF7"/>

                <Style.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Foreground" Value="LightGray" />
                        <Setter Property="Background" Value="LightGray" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.Style>

        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Value.IsOk}" Value="True">
                        <Setter Property="Background" Value="Green"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ListBox.ItemContainerStyle>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <StackPanel Width="200">
                        <TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Key}" />
                        <TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap">
                            <TextBlock.Text>
                                <MultiBinding StringFormat="{}{0} {1} {2}">
                                    <Binding Path="Value.TextA" />
                                    <Binding Path="Value.TextB" />
                                    <Binding Path="Value.TextC" />
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
Anthony M.
  • 363
  • 4
  • 6
2

As Anthony pointed out, your style trigger will never set the Background of your ListBox because you have set a local value. It's called "Dependency Property Precedence". Take a look at this link: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence.

"Local" values have higher precedence over "style trigger" values. However, "style trigger" values have higher precedence over "style setter" values. This means that if you want to have an initial value for the property and change it based on a trigger, just set it in the style initially, instead of setting it locally like your code does.

Daniel Marques
  • 683
  • 8
  • 17
1

First off all - this msdn link ListBox Styles and Templates will help you the most. You can check this way - what applies where in a ListBox and a ListBoxItem.

If you check the Style of the ListBoxItem you will see that the ContentPresenter gets no Foreground applied.

  <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid Background="{TemplateBinding Background}">
                            <ContentPresenter   x:Name="contentPresenter"
                                                Content="{TemplateBinding Content}"
                                                ContentTemplate="{TemplateBinding ContentTemplate}"
                                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                Margin="{TemplateBinding Padding}"/><!-- No foreground gets applied. -->
                            <Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Anyway here is your solution:

    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" 
                        Width="200">
                <TextBlock VerticalAlignment="Center" 
                               FontSize="10" 
                               TextWrapping="Wrap">

                        <Run FontWeight="Bold" Text="{Binding Path=Key}" />
                        <LineBreak />
                        <Run>
                            <Run.Text>
                                <MultiBinding StringFormat="{}{0} {1} {2}">
                                    <Binding Path="Value.TextA" />
                                    <Binding Path="Value.TextB" />
                                    <Binding Path="Value.TextC" />
                                </MultiBinding>
                            </Run.Text>
                        </Run>
                    <TextBlock.Style>
                        <Style TargetType="{x:Type TextBlock}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsOk}" Value="True" >
                                    <Setter Property="Foreground" Value="Green"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </TextBlock.Style>
                </TextBlock>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>

The TextBlock now listens to isOk and will applys the Foreground.

Peter
  • 1,655
  • 22
  • 44