WPF:动作时设置相对于当前颜色的背景色

时间:2018-12-01 06:43:47

标签: c# wpf colors treeview

我有一个自定义WPF TreeView。其中TreeViewItem的背景颜色取决于其类型。我从TreeViewItem.Name获取了该信息,并使用了一个触发器,如下所示。

现在,当我选择或将鼠标悬停在TreeView中的某个元素上时,我希望该元素保持其颜色但要更亮一些。目前,如下所示,我为所有元素设置了相同的颜色。

如何更改代码以使悬浮颜色相对于元素具有的颜色,无论它是哪种?

<TreeView>
    <TreeView.Resources>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TreeViewItem">                                
                        <ControlTemplate.Triggers>

                            <Trigger Property="TreeViewItem.Name" Value="TypeA">
                                <Setter Property="Background" TargetName="Bd" Value="#8BADC5"/>
                            </Trigger>
                            <Trigger Property="TreeViewItem.Name" Value="TypeB">
                                <Setter Property="Background" TargetName="Bd" Value="#FFC3AF"/>
                            </Trigger>


                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" TargetName="Bd" Value="#A5243D"/>
                            </Trigger>
                            <Trigger Property="IsFocused" Value="True">
                                <Setter Property="Background" TargetName="Bd" Value="#A5243D"/>
                            </Trigger>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="Bd" Property="Background" Value="#A5243D"/>
                            </Trigger>

                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TreeView.Resources>
</TreeView>

2 个答案:

答案 0 :(得分:1)

我提出了妈妈建议的扩展版本,在该版本中,更容易制定IsMouseOver等触发器。它包括:

  • 一个多值转换器,用于根据基值和一些转换参数来计算要使用的背景画笔
  • 用于保存转换参数的附加属性
  • 在XAML中,是一种多绑定

作为一个简单的示例,假设要使用的颜色应由Color计算。再乘以由IsMouseOver等状态确定的因子。

多值转换器:

public class MultiplyColorConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var baseColor = ((SolidColorBrush)values[0]).Color;
        var factor = (float)values[1];
        return new SolidColorBrush(Color.Multiply(baseColor, factor));
    }

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

转换参数附加属性:

public class ColorTransform
{
    public static float GetFactor(DependencyObject obj)
    {
        return (float)obj.GetValue(FactorProperty);
    }

    public static void SetFactor(DependencyObject obj, float value)
    {
        obj.SetValue(FactorProperty, value);
    }

    public static readonly DependencyProperty FactorProperty =
        DependencyProperty.RegisterAttached("Factor", typeof(float), typeof(ColorTransform), 
            new FrameworkPropertyMetadata(1.0F,
                FrameworkPropertyMetadataOptions.AffectsRender));
}

XAML:

<local:MultiplyColorConverter x:Key="MultiplyColorConverter"/>
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="Template">
            <Setter.Value>
            <ControlTemplate TargetType="TreeViewItem">
                <Border x:Name="Bd">
                    <Border.Background>
                        <MultiBinding Mode="OneWay" Converter="{StaticResource MultiplyColorConverter}">
                            <Binding Path="BaseColor" Mode="OneWay"/>
                            <Binding RelativeSource="{RelativeSource Self}" Path="(local:ColorTransform.Factor)" Mode="OneWay"/>
                        </MultiBinding>
                    </Border.Background>
                    <TextBlock x:Name="Text" Text="{Binding}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="Bd" Property="local:ColorTransform.Factor" Value="0.5"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter TargetName="Bd" Property="local:ColorTransform.Factor" Value="0.5"/>
                    </Trigger>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="Bd" Property="local:ColorTransform.Factor" Value="0.3"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

答案 1 :(得分:0)

我会用一个值转换器来做。

public class ColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is SolidColorBrush) {
            // return the calculated new SolidColorBrush
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

在xaml资源部分中:

<ColorConverter x:Key="ColorConverter/>

和在xaml正文中:

<Setter TargetName="Bd" Property="Background" Value="{Binding Background, Converter={StaticResource ColorConverter}}"/>