Search code examples
c#wpflistboxstylesitemcontainerstyle

Override the background color when ListBox is disabled/inactived


I want to have everything of the ListBox background transparent. Not focused/focused/whatever...

I override the style of the ListBox and its ItemContainerStyle but I still have a background color on the ListBox when it is disabled by another element...

<Style TargetType="{x:Type ListBox}" x:Key="MyListBoxStyle">
    <Setter Property="Background" Value="{DynamicResource TransparentBackgroundBrush}"/>
    <Setter Property="BorderBrush" Value="{DynamicResource TransparentBackgroundBrush}"/>
    <Setter Property="SelectionMode" Value="Single"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="ItemContainerStyle" Value="{DynamicResource MyListBoxItemStyle}"/>
</Style>



<Style TargetType="{x:Type ListBoxItem}" x:Key="MyListBoxItemStyle">
    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{DynamicResource TransparentColor}" />
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="{DynamicResource TransparentColor}"/>
    </Style.Resources>
</Style>

I also tried by setting the FocusVisualStyle to null (see this answer) ; to set some "inactive" colors brushSystem.Colors to transparent and to set the ScrollBar colors to transparent (see this link) but nothing is working...

  • What am I missing ?
  • Do you know which color can be the problem (see this post) ?
  • What will be is state ? Disable ? Inactive ?

Solution

  • It's hard to do by changing a colour globally because you get confounding effects from other controls.

    Changing the background colour of a list box to match a given state, like inactive or disabled can be approached by getting a plain-vanilla list box template like this one...

     <Style x:Key="{x:Type ListBox}" TargetType="ListBox">
            <Setter Property="SnapsToDevicePixels"  Value="true" />
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
            <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
            <Setter Property="MinWidth" Value="120" />
            <Setter Property="MinHeight" Value="95" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBox">
                        <Border Name="Border" BorderThickness="1" CornerRadius="2">
                            <Border.Background>
                                <SolidColorBrush Color="{StaticResource ControlLightColor}" />
                            </Border.Background>
                            <Border.BorderBrush>
                                <SolidColorBrush Color="{StaticResource BorderMediumColor}" />
                            </Border.BorderBrush>
                            <ScrollViewer Margin="0" Focusable="false">
                                <StackPanel Margin="2" IsItemsHost="True" />
                            </ScrollViewer>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter TargetName="Border" Property="Background">
                                    <Setter.Value>
                                        <SolidColorBrush Color="{StaticResource DisabledControlLightColor}" />
                                    </Setter.Value>
                                </Setter>
                                <Setter TargetName="Border" Property="BorderBrush">
                                    <Setter.Value>
                                        <SolidColorBrush Color="{DynamicResource DisabledBorderLightColor}" />
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                            <Trigger Property="IsGrouping" Value="true">
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
            <Setter Property="SnapsToDevicePixels" Value="true" />
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border x:Name="Border" Padding="2" SnapsToDevicePixels="true">
                            <Border.Background>
                                <SolidColorBrush Color="Transparent" />
                            </Border.Background>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected" />
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                                <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource SelectedBackgroundColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SelectedUnfocused">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                                <EasingColorKeyFrame KeyTime="0"
                                         Value="{StaticResource SelectedUnfocusedColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ContentPresenter />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    ...and adding it to your window resources. Note that the template refers to a set of colours which get defined further up the object graph as...

        <Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
        <Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
        <Color x:Key="DisabledForegroundColor">#FF888888</Color>
        <Color x:Key="ControlLightColor">White</Color>
        <Color x:Key="ControlMediumColor">#FF7381F9</Color>
        <Color x:Key="ControlDarkColor">#FF211AA9</Color>
        <Color x:Key="BorderLightColor">#FFCCCCCC</Color>
        <Color x:Key="BorderMediumColor">#FF888888</Color>
        <Color x:Key="BorderDarkColor">#FF444444</Color>
        <Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
        <Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
    

    ... these can be replaced with the WPF value for Transparent, which is #00FFFFFF. This will change ALL colours to transparent where ever the references exist in the template. The StoryBoard colours refer to system colours and will need to be changed individually. Or delete the story boards altogether.

    Once you get a working model for your desired styling you can add a key to the resource and style list boxes selectively.

    As posted, this all compiled and ran clean under 4.5...

    Interesting links are...

    ListBox Styles and Templates

    Color values

    And a very useful utility for inspecting templates in the WPF dll's: http://www.sellsbrothers.com/tools/ShowMeTheTemplate.zip