c# - WPF:在动作上设置相对于当前颜色的背景颜色
问题描述
我有一个自定义 WPF TreeView
。在那里 aTreeViewItem
有一个背景颜色,具体取决于它的类型。我从 中获取该信息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>
解决方案
我提出了 mami 建议的扩展版本,其中更容易制定 IsMouseOver 等触发器。它包括:
- 一个多值转换器,用于根据基值和一些转换参数计算要使用的背景画笔
- 用于保存转换参数的附加属性
- 在 XAML 中,一个多重绑定
作为一个简单的例子,假设要使用的颜色应通过 Color.Multiply 与 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>
推荐阅读
- python - AWS S3 ValueError:整数列在第 63 列中有 NA 值
- xpath - xpath //li[div]/descendant::a[2] 和 //li[div]//a[2] 有什么区别?
- javascript - 带有可选参数的路由会阻止其他路由加载
- java - 在数据库之间循环导致不关闭的泄漏连接导致“连接过多”
- android - Android NDK 尝试将库与 pthread 链接,即使我没有添加它
- ios - 在 Firestore 中使用降序时间戳进行分页
- oracle - 启动 Spring-boot/JPA 应用程序时出现 Broken Pipe 错误 - 立即测试查询成功
- doctrine-odm - 如何在控制器中获取特定的文档管理器?
- r - 应用 rollmean,但如果公司没有 k > 2,则保留单个值
- php - Sonata 管理员在 ajax 调用后存储一条消息