首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Winforms ToolStrip.BackColor返回错误的颜色

Winforms ToolStrip.BackColor返回错误的颜色
EN

Stack Overflow用户
提问于 2019-06-14 08:32:16
回答 1查看 1.4K关注 0票数 1

我问题的根源

我使用winforms在C#中创建了一个非常简单的虚拟应用程序。它只包含一个ToolStrip和一个TrackBar在该ToolStrip中。TrackBar应该具有与ToolStrip相同的BackColor,但似乎属性ToolStrip.BackColor没有返回实际的背景色。

代码语言:javascript
复制
public Form1()
{
    //// Here the ToolStrip is created.
    //// This code is generated by the designer.
    this.InitializeComponent();
    //// Here the the TrackBar is created.
    //// I think this is impossible to do via the Designer.
    this.CreateSpeedSlider();
}

private void CreateSpeedSlider()
{
    this.toolStrip.SuspendLayout();
    this.speedSlider = new TrackBar
    {
        TickStyle = TickStyle.None,
        AutoSize = false,
        Height = this.toolStrip.Height,
        Minimum = 0,
        Maximum = 10,
        BackColor = this.toolStrip.BackColor,
    };

    this.toolStrip.Items.Add(new ToolStripControlHost(this.speedSlider));
    this.toolStrip.ResumeLayout();
}

结果是在淡灰色的TrackBar上有一个白色的ToolStrip。所以看起来

代码语言:javascript
复制
this.toolStrip.BackColor

不返回实际用于绘制它的ToolStrip的背景色。

然而..。

如果我将我的功能更改为

代码语言:javascript
复制
private void CreateSpeedSlider()
{
    this.toolStrip.BackColor = this.toolStrip.BackColor;
    ...
}

我在白色ToolStrip上得到了一个白色滑块。所以..。将属性的值赋值给自己实际上会将颜色从浅灰色更改为白色?

所以问题是..。

没有这样的“黑客”,有什么好的方法来检索正确的ToolStrip背景色吗?

这种行为是故意的还是我遗漏了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-14 10:32:13

BackColor是一个环境属性

Control.BackColor是一个环境属性:

BackColor属性是一个环境属性。环境属性是一个控件属性,如果没有设置,则从父控件中检索该属性。例如,默认情况下,按钮将具有与其父窗体相同的BackColor。有关环境属性的详细信息,请参阅AmbientProperties类或Control概述。

这意味着它的实现方式如下(来源):

代码语言:javascript
复制
public virtual Color BackColor
{
     get
     {
          Color c = RawBackColor; // inheritedProperties.BackColor
          if (!c.IsEmpty)
          {
               return c;
          }
          Control p = ParentInternal;
          if (p != null && p.CanAccessProperties)
          {
               c = p.BackColor;
               if (IsValidBackColor(c))
               {
                    return c;
               }
          }
          ...

有一个内部属性RawBackColor,它是为该特定控件显式设置的颜色。BackColor本身是计算出来的-如果没有为该控件显式设置颜色,它将尝试返回其父控件的BackColor

ToolStrip的呈现方式不同。

要为菜单实现不同的样式,ToolStrip支持可配置的渲染

ToolStrip类实现了与其他Windows控件显著不同的呈现方案。使用此方案,您可以轻松地应用样式和主题。

它的意思是,ToolStrip有一个Renderer,渲染器的初始化取决于系统设置。因此,一般来说,要获得工具条的背景色并没有简单的方法。

默认情况下使用ToolstripProfessionalRenderer的可能性很大。这种类型的渲染器实际上用渐变绘制背景。它有一个ColorTable属性,依次定义MenuStripGradientBeginMenuStripGradientEnd

因此,在大多数情况下(但不是所有情况下),您可以这样确定toolstip的默认背景色:

代码语言:javascript
复制
var renderer = (ToolStripProfessionalRenderer)toolStrip.Renderer;
Console.WriteLine(renderer.ColorTable.MenuStripGradientBegin);
Console.WriteLine(renderer.ColorTable.MenuStripGradientEnd);

如果您试图托管一个具有均匀绘制背景的控件,比如TrackBar,它可能会突出在一个渐变填充的工具条中。

ToolStripRenderer考虑到了明确的设置颜色

我在任何地方都找不到这种行为,但是根据来源的说法,只有当工具条的RawBackColor没有设置时,背景才会被绘制(填充梯度):

代码语言:javascript
复制
internal bool ShouldPaintBackground(Control control)
{
    return (control.RawBackColor == Color.Empty && control.BackgroundImage == null);
}

因此,如果您显式地将ToolStrip.BackColor设置为任何颜色,那么渲染器将只使用此颜色作为背景色。这种令人困惑的行为解释了为什么:

代码语言:javascript
复制
toolStrip.BackColor = toolStrip.BackColor;

有实际效果。

现在该怎么办?

我能看到多条前进的路,没有一条是好的:

  1. 将工具条和跟踪条的BackColor设置为已知颜色。这将扼杀工具条背景中美丽的渐变。如果你不太关心梯度,那是最简单的方法。
  2. 使托管控件透明,使工具条的背景显示出来。这将不适用于TrackBar,因为出于某种原因,它不支持透明背景。关于可能的选项(我没有尝试其中的任何选项),请参见这个问题:TabControl中的跟踪条背景
  3. 覆盖跟踪栏的OnPaint并用梯度填充它,使其与工具条的背景混合在一起。这听起来有问题,但可行。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56594382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档