【问题标题】:How to create a color modifying option in WPF XAML ? - Something like an extension method如何在 WPF XAML 中创建颜色修改选项? - 类似扩展方法的东西
【发布时间】:2018-09-18 03:34:46
【问题描述】:

我刚刚开始学习 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);
    }
}

【问题讨论】:

    标签: c# wpf xaml colors extension-methods


    【解决方案1】:

    这就是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 语法与您的伪代码完全相同,只是您需要在属性之间提供逗号(,)。

    【讨论】:

    • 这是完美的。我怎么在搜索中错过了这个? - 我的 google-fu 一定很弱。谢谢!
    • 小问题:当我尝试运行它时,出现异常:“ArgumentException: 'Color [A=255, R=79, G=87, B=108]' is not a valid属性“颜色”的值。” - 我尝试将ProvideValue 的输出格式化为#FF4F576C 格式的字符串,但它也不会这样做。有什么想法吗?
    • @user1689175 当您遇到此异常时,您的 xaml 看起来如何?你从哪里得到这个例外?我在发布之前测试了我的代码并确认它可以工作。
    • 确保使用System.Windows.Media.Color而不是System.Drawing.Color。我这样说是因为Color.White 在媒体颜色类中不可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多