代码之家  ›  专栏  ›  技术社区  ›  juergen d

WPF:On操作设置相对于当前颜色的背景色

  •  1
  • juergen d  · 技术社区  · 7 年前

    我有一个定制的WPF TreeView . 在那里 TreeViewItem 根据其类型具有背景色。我从报纸上得到这个信息 TreeViewItem.Name 并使用了一个触发器,如下所示。

    现在,当我选择或将鼠标悬停在 我希望元素保持其颜色,但更明亮一点。目前,如下图所示,我只是为所有元素设置了相同的颜色。

    如何更改代码,使悬停颜色相对于元素的颜色,而不管它是哪种颜色?

    <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 回复  |  直到 7 年前
        1
  •  1
  •   Klaus Gütter    7 年前

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

    • 在XAML中,一种多重绑定

    多值转换器:

    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>
    
        2
  •  0
  •   mami    7 年前

    我会用一个值转换器。

    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}}"/>