Search code examples
wpfxamlcolorssetter

Binding value of a setter property to a Code Behind Property Color


I'm struggling to find a way to set a Setter.Value with my own property (SelectedRowBackColor). This line of XAML doesn't work:

<SolidColorBrush Color="{Binding XPath=SelectedRowBackColor}"></SolidColorBrush>

Can someone help me out? Thanks.

<UserControl x:Class="LogManagerWPF.LogManager"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:LogManagerWPF"
             mc:Ignorable="d" 
             d:DesignHeight="192" d:DesignWidth="400">
    <UserControl.Resources>
        <DataTemplate x:Key="DisplayImage">
            <Image Source="{Binding ImageIcon}" Width="16" Height="16"/>
        </DataTemplate>
    </UserControl.Resources>
    <ListView Margin="0" x:Name="m_lvLog" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Loaded="m_lvLog_Loaded" SizeChanged="m_lvLog_SizeChanged"  ContextMenuOpening="m_lvLog_ContextMenuOpening" SelectionChanged="m_lvLog_SelectionChanged">
        <ListView.Resources>
            <Style TargetType="{x:Type ListViewItem}">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background">
                            <Setter.Value>
                                <SolidColorBrush Color="{Binding XPath=SelectedRowBackColor}"></SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="BorderBrush">
                            <Setter.Value>
                                <SolidColorBrush Color="{Binding XPath=SelectedRowBackColor}"></SolidColorBrush>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListView.Resources>
        <ListView.View>
            <GridView x:Name="m_gvLog" AllowsColumnReorder="False">
                <GridViewColumn x:Name="m_icon" Width="28" Header="" CellTemplate="{StaticResource DisplayImage}"/>
                <GridViewColumn x:Name="m_time" Width="Auto" Header="Timestamp" DisplayMemberBinding="{Binding Timestamp}">
                    <GridViewColumn.HeaderContainerStyle>
                        <Style TargetType="{x:Type GridViewColumnHeader}">
                            <Setter Property="Foreground" Value="#FF042271" />
                            <Setter Property="HorizontalContentAlignment" Value="Left" />
                            <Setter Property="Padding" Value="10,0,0,0" />
                        </Style>
                    </GridViewColumn.HeaderContainerStyle>
                </GridViewColumn>
                <GridViewColumn x:Name="m_messages" Width="100000" Header="Message" DisplayMemberBinding="{Binding Message}">
                    <GridViewColumn.HeaderContainerStyle>
                        <Style TargetType="{x:Type GridViewColumnHeader}">
                            <Setter Property="Foreground" Value="#FF042271" />
                            <Setter Property="HorizontalContentAlignment" Value="Left" />
                            <Setter Property="Padding" Value="10,0,0,0" />
                        </Style>
                    </GridViewColumn.HeaderContainerStyle>
                </GridViewColumn>
            </GridView>
        </ListView.View>
        <ListView.ContextMenu>
            <ContextMenu x:Name="m_contextMenu">
                <MenuItem x:Name="m_menuAutoScroll" Header="Autoscroll" Click="m_menuAutoScroll_Click" IsCheckable="True" />
                <MenuItem x:Name="m_menuClear" Header="Clear Log" Click="m_menuClear_Click"/>
                <MenuItem x:Name="m_menuCopy" Header="Copy to Clipboard" Click="m_menuCopy_Click"/>
                <MenuItem x:Name="m_menuVerbosity" Header="Set Verbosity">
                    <MenuItem x:Name="m_menuVerbosityLow" Header="Low" Click="m_menuVerbosityLow_Click" IsCheckable="True"/>
                    <MenuItem x:Name="m_menuVerbosityStandard" Header="Standard" Click="m_menuVerbosityStandard_Click" IsCheckable="True"/>
                    <MenuItem x:Name="m_menuVerbosityHigh" Header="High" Click="m_menuVerbosityHigh_Click" IsCheckable="True"/>
                    <MenuItem x:Name="m_menuVerbosityDebug" Header="Debug" Click="m_menuVerbosityDebug_Click" IsCheckable="True"/>
                </MenuItem>
            </ContextMenu>
        </ListView.ContextMenu>
    </ListView>
</UserControl>

This is the property:

private System.Windows.Media.Color? m_SelectedRowBackColor = System.Windows.Media.Color.FromArgb(255, 0x0A, 0x24, 0x6A);    //Colore di selezione originale

[Category("Properties")]
[Description("Selected Row Background Color")]
public System.Windows.Media.Color? SelectedRowBackColor
{
    get
    {
        return m_SelectedRowBackColor;
    }
    set
    {
        m_SelectedRowBackColor = value;
    }
}

EDIT: I noticed this solution works but only on Windows 10, it fails to set the color on Windows 7:

<SolidColorBrush Color="{Binding SelectedRowBackColor, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"></SolidColorBrush>

Solution

  • I understood Windows 7 and 10 use different methods, so I implemented both to achieve a similar result in both:

    <ListView.Resources>
        <!-- Windows 7 -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="{Binding SelectedRowBackColor, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" />
        <SolidColorBrush x:Key="{x:Static SystemColors.ActiveBorderBrushKey}" Color="{Binding SelectedRowBackColor, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" />
        <!-- Windows 10 -->
        <Style TargetType="{x:Type ListViewItem}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background">
                        <Setter.Value>
                            <SolidColorBrush Color="{Binding SelectedRowBackColor, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"></SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                    <Setter Property="BorderBrush">
                        <Setter.Value>
                            <SolidColorBrush Color="{Binding SelectedRowBackColor, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"></SolidColorBrush>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListView.Resources>