ToolStrip.Background 只能改变按钮的背景 (C#/.NET/WinForms)

3

当一个项目未被保存时,我希望我的ToolStrip背景能够改变。

为了渲染ToolStrip的背景,我使用自己的渲染器:

    class ToolStripRenderer : ToolStripProfessionalRenderer
    {
        private MenuBarForm parent;

        public ToolStripRenderer(MenuBarForm Parent)
        {
            parent = Parent;
        }

        protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
        {
            if (parent.controlItems.Last().Unsaved)
                e.Graphics.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(e.ToolStrip.ClientRectangle, SystemColors.ControlLightLight, Color.Red, 90, true), e.AffectedBounds);
            else
                e.Graphics.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(e.ToolStrip.ClientRectangle, SystemColors.ControlLightLight, SystemColors.ControlDark, 90, true), e.AffectedBounds);
        }
    }

工具栏第一次呈现时,它的设计是灰色到深灰色的,呈现正确:CorrectToolstrip。但当工具栏应该变成红色时,只有鼠标悬停在按钮上时才会变成红色:IncorrectToolstrip。我希望整个工具栏能够立即变成红色。我已经尝试将e.AffectedBounds更改为e.ToolStrip.Bounds,但没有成功。

1
听起来好像不需要更新控件。你尝试在工具栏上调用Invalidate()方法了吗?这会强制它进行更新。 - MrApnea
谢谢您的答复。我已将其添加到问题中。 - Maiko Kingma
请不要将答案作为问题的一部分发布。这会让未来的读者感到困惑。请将答案作为一个回答发布。 - Reza Aghaei
不要通过绘图来改变背景颜色,可以创建一个新的颜色表,并覆盖相关属性来改变背景颜色,然后在“未保存”更改时使用它。 - Reza Aghaei
听起来很有趣。我不熟悉颜色表。您能否提供一个示例代码,使用您的颜色表根据属性更改工具栏背景颜色。 - Maiko Kingma
是的,我会为您发布一个答案。 - Reza Aghaei
2个回答

2
你可以创建一个自定义的颜色表,继承 ProfessionalColorTable 并覆盖相关属性来改变背景颜色:
public class CustomColorTable : ProfessionalColorTable
{
    public override Color ToolStripGradientBegin
    {
        get { return Color.Red; }
    }
    public override Color ToolStripGradientMiddle
    {
        get { return Color.Red; }
    }
    public override Color ToolStripGradientEnd
    {
        get { return SystemColors.ControlLightLight; }
    }
}

要更改ToolStrip的背景,请分配一个新的ToolStripProfessionalRenderer,该渲染器使用您自定义的颜色表来ToolStripManager.Renderer

ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable());

设置原始的专业渲染器:

ToolStripManager.Renderer = new ToolStripProfessionalRenderer();

谢谢您的快速回复。不幸的是,这个解决方案对我没有用。我尝试使用以下代码添加了您的CustomColorTable来更改渲染器: 如果(controlItems.Last().Unsaved) ToolStripManager.Renderer = new ToolStripProfessionalRenderer(); else ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable()); - Maiko Kingma
为了测试解决方案,只需将 ToolStripRenderMode 属性设置为 ManagerRenderMode,然后在需要时更改 ToolStripManager.Renderer 即可。要从您的 UnSaved 属性进行独立测试,可以在按钮单击中调用 ToolStripManager.Renderer = new ToolStripProfessionalRenderer(new CustomColorTable()); 以确保它正常工作。 - Reza Aghaei
如果您在应用答案时遇到任何问题,请告诉我。它已经经过测试并且正常工作。 - Reza Aghaei
在我的先前解决方案中,我没有使用 ToolStripManager。这个工具栏管理器是否需要与 ToolStrip 相连接才能正常工作?我的 ToolStrip 也位于一个 ToolStripContainer 中,这可能会干扰 ToolStripManager 的工作吗? - Maiko Kingma
如果您将 ToolStripRenderMode 属性设置为 ManagerRenderMode,则您的 ToolStrip 将使用管理器。这是美化 ToolStrip 的主要机制。 - Reza Aghaei

0

我是通过FSDaniel的评论找到了解决方案:

OnRenderToolStripBackground的末尾添加Invalidate()确实使工具栏变成完全红色,但也导致应用程序陷入无限循环。我通过创建一个事件来解决这个问题,该事件由更改UnSaved属性触发。具有工具栏的窗体然后订阅了这个事件,并调用toolstrip.Invalidate()的方法。这样,只有在必要时才使用Invalidate()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接