基于布尔值调用覆盖值(C#、WinForms)

问题描述 投票:0回答:1

也许这是一个愚蠢的问题,但我找不到清晰直接的线索。我使用 2 个类来表示

ToolStripProfessionalRenderer
ProfessionalColorTable
。这是因为我正在为菜单设置颜色更改。现在我已经可以工作了,但我想编写更好的代码,如果可能的话并且简单地完成。我现在正在做的是这样的:

    class MenuColorTable : ProfessionalColorTable
    {
        bool dark = false;
        public MenuColorTable(string color)
        {
            if (color == "dark")
            {
                dark = true;
                base.UseSystemColors = false;
            }
            else
            {
                base.UseSystemColors = true;
            }
        }
        public override Color MenuItemSelectedGradientBegin
        {
            get { return dark ? Color.FromArgb(12, 46, 73) : base.MenuItemPressedGradientBegin; }
        }
        public override Color MenuItemSelectedGradientEnd
        {
            get { return dark ? Color.FromArgb(12, 46, 73) : base.MenuItemSelectedGradientEnd; }
        }
    }


    private class SkinRenderer : ToolStripProfessionalRenderer
    {
        public SkinRenderer(MenuColorTable colorTable) : base(colorTable) { }
    }

然后在代码中,为了测试,我用

调用所有这些
menu.Renderer = new SkinRenderer(new MenuColorTable("dark"));

但我宁愿在颜色表中以另一种更优雅的方式处理这个问题。问题是我意识到,基本上,只有深色和默认颜色,

base.UseSystemColors
就足够了,我不需要在覆盖中传递默认值。因此,我不知道如何做是仅在 dark 为 true 时调用这些覆盖颜色,而不是无论如何调用它们,然后处理返回值。就像“如果黑暗,覆盖”一样,所以如果黑暗为假,则不会调用覆盖。

c# winforms overriding
1个回答
0
投票

重写方法是一个编译时操作,你无法从运行时控制它 - 但是,你可以用更好的方式编写你的类:

首先,您应该将此类的用户限制为特定主题,否则您可能会遇到意外行为,并且您应该避免使用“魔术字符串”,因此让您的构造函数接受

string color
的成员,而不是
Theme
枚举。

其次,您不想每次有人调用您的属性时都执行条件,因此您添加一个显式支持字段并将其填充到构造函数中:

enum Theme
{
    Dark,
    // Light, // You might want to add this here
    SystemDefault
}

class MenuColorTable : ProfessionalColorTable
{

    private Color menuItemPressedGradientBegin, menuItemSelectedGradientEnd;

    public MenuColorTable(Theme theme)
    {
        switch (theme)
        {
            case Theme.Dark:
                // If you have many properties with the same color, 
                // consider using a variable for it:
                var dark = Color.FromArgb(12, 46, 73);
                menuItemPressedGradientBegin = dark;
                menuItemSelectedGradientEnd = dark;
                base.UseSystemColors = false;
                break;


            // If you decide to implement a light theme
            //case Theme.Light:
            //    var light = Color.FromArgb(112, 146, 173);
            //    menuItemPressedGradientBegin = light;
            //    menuItemSelectedGradientEnd = light;
            //    base.UseSystemColors = false;
            //    break;

            case Theme.SystemDefault:

                menuItemPressedGradientBegin = base.MenuItemPressedGradientBegin;
                menuItemSelectedGradientEnd = base.MenuItemSelectedGradientEnd;
                base.UseSystemColors = true;
                break;
        }
    }

    public override Color MenuItemSelectedGradientBegin => menuItemPressedGradientBegin;

    public override Color MenuItemSelectedGradientEnd => menuItemSelectedGradientEnd;
}
© www.soinside.com 2019 - 2024. All rights reserved.