如何在 WPF XAML 中创建颜色修改选项? - 类似于扩展方法

How to create a color modifying option in WPF XAML ? - Something like an extension method

我刚刚开始学习 WPF 和 XAML,并且很好奇我可以在 XAML 中操作属性的方法。我仍在努力学习一些基础知识,例如转换器和绑定等。我可以使用本机 C# 做的一件非常好的事情是创建扩展方法来简化某些任务。我想知道是否可以为 XAML 创建类似的东西。

具体...

使用 C# 扩展方法,我创建了几个函数来修改颜色 - "MakeLighter" 和 "MakeDarker"。事实证明,这些对于轻松调整颜色的深浅非常方便。例如,我可以写:

var myBackgroundColor = Color.AntiqueWhite.MakeLighter(0.10); // Makes color 10% lighter.
var myForegroundColor = Color.DarkSlateBlue.MakeDarker(0.15); // Makes color 15% darker.

这使得调整颜色阴影变得非常简单,因为您可以根据需要使它们变亮或变暗。与灰色人一起工作特别愉快:

var shadow1 = Color.Gray.MakeDarker(0.20);
var shadow2 = Color.Gray.MakeDarker(0.24);
var shadow3 = Color.Gray.MakeDarker(0.28);

在 XAML 中,我发现使用颜色有点烦人。我知道有很多颜色选择器选项和 VS 插件可以帮助解决这个问题,但我想念 MakeLighter 和 MakeDarker 的功能。

问题:

有什么方法可以在 XAML 中创建类似的 MakeLighter 和 MakeDarker 颜色操纵器吗?也许有值转换器或类型转换器? - 我不知道有什么可能。

后面可以有C#代码,不需要是纯的XAML,但应该类似于扩展方法,可以在任何使用颜色的地方使用。

例如,理想情况下我希望能够做这样的事情:

 <LinearGradientBrush x:Key="WindowClientAreaColor" StartPoint="1,1" EndPoint="0,0">
     <GradientStop Color="{MyColor Base=#FF414758 MakeLighter=0.03}" Offset="0" />
     <GradientStop Color="{MyColor Base=#FF555E75 MakeDarker=0.07}" Offset="1.0" />
 </LinearGradientBrush>

...或者类似的东西。理想情况下,某种类型的内联语句允许在分配颜色的任何地方修改颜色。

欢迎任何开箱即用的想法。谢谢!!

编辑:

如果有人需要,这里是扩展方法代码:

using System.Windows.Media;  // Do not use System.Drawing for WPF Color
public static class clsExtension_Color
{
    public static Color MakeLighter(this Color thisColor, double lightnessPercent)
    {
        lightnessPercent = lightnessPercent.ForceBounds(0, 1);
        return Blend(thisColor, Color.FromRgb(255,255,255), lightnessPercent);
    }

    public static Color MakeDarker(this Color thisColor, double darknessPercent)
    {
        darknessPercent = darknessPercent.ForceBounds(0, 1);
        return Blend(thisColor,  Color.FromRgb(0,0,0), darknessPercent);
    }

    public static Color Blend(this Color thisColor, Color blendToColor, double blendToPercent)
    {
        blendToPercent = (1 - blendToPercent).ForceBounds(0, 1);

        byte r = (byte)((thisColor.R * blendToPercent) + blendToColor.R * (1 - blendToPercent));
        byte g = (byte)((thisColor.G * blendToPercent) + blendToColor.G * (1 - blendToPercent));
        byte b = (byte)((thisColor.B * blendToPercent) + blendToColor.B * (1 - blendToPercent));

        return Color.FromArgb(255, r, g, b);
    }
}

这就是 Markup Extensions 派上用场的地方。就像我们有实例的扩展方法一样,xaml 有标记扩展。

如下创建标记扩展。

public class ShadedColorExtension : MarkupExtension
{
    public Color BaseColor { get; set; }
    public double Lighter { get; set; }
    public double Darker { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (Lighter > 0d)
        {
            return BaseColor.MakeLighter(Lighter);
        }
        if (Darker > 0d)
        {
            return BaseColor.MakeDarker(Darker);
        }
        return BaseColor;
    }
}

ProvideValue 方法将在 属性 需要值时调用。您可以根据需要修改 ProvideValue 方法。

然后在xaml

中使用如下
<LinearGradientBrush x:Key="WindowClientAreaColor" StartPoint="1,1" EndPoint="0,0">
  <GradientStop Color="{yourNamespace:ShadedColor BaseColor=Red, Lighter=0.03}" Offset="0" />
  <GradientStop Color="{yourNamespace:ShadedColor BaseColor=#FF555E75, Darker=0.07}" Offset="1.0" />
</LinearGradientBrush>

您会注意到上面的 xaml 语法与您的伪代码完全相同,只是您需要在属性之间提供逗号 (,)。