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



我刚刚开始学习 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插件可以帮助解决这个问题,但我错过了MakeLight和MakeDarker的能力。

问题:

有没有办法在 XAML 中创建类似的 MakeLight 和 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);
}
}

这就是标记扩展派上用场的地方。就像我们有实例的扩展方法一样,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 语法与您的伪代码完全相同,只是您需要在项目之间提供逗号(,)。

最新更新