C# 使用展开样式更改ToolStripComboBox的边框

C# 使用展开样式更改ToolStripComboBox的边框,c#,.net,winforms,combobox,toolstrip,C#,.net,Winforms,Combobox,Toolstrip,我希望能够在我的一些toolstrips中更改ToolStripComboBox控件的边框颜色,因为与平面样式一起使用时,ComboBox的默认边框颜色是SystemColor.Window,相对于toolstrips的默认控件颜色,它基本上是不可见的。在Reflector中进行了大量的挖掘之后,我看不到任何明显的方法可以做到这一点,因为ComboBox渲染背后的所有基础设施都在内部和私有接口后面得到了高度保护 在ToolStrips之外,我所看到的固定组合框边框颜色的常见解决方案是子类化组合框

我希望能够在我的一些toolstrips中更改ToolStripComboBox控件的边框颜色,因为与平面样式一起使用时,ComboBox的默认边框颜色是SystemColor.Window,相对于toolstrips的默认控件颜色,它基本上是不可见的。在Reflector中进行了大量的挖掘之后,我看不到任何明显的方法可以做到这一点,因为ComboBox渲染背后的所有基础设施都在内部和私有接口后面得到了高度保护

在ToolStrips之外,我所看到的固定组合框边框颜色的常见解决方案是子类化组合框,覆盖WndProc,并手动绘制边框。这对ToolStripComboBox控件不起作用,因为内部ComboBox控件是它自己的ComboBox私有子类,我看不到替换该控件实例的方法

我正在考虑的另一个解决方案是将一个扩展的ComboBox对象放入ToolStripControlHost中,这允许我绘制边框,但随后我不得不放弃一些专业的渲染器调整。我注意到的第二个缺点是在鼠标悬停时偶尔会出现闪烁

将我的设计转换为WPF不是一个可接受的解决方案。在图形边框的父控件中包装控件也是不可接受的,因为这与ToolStripControlHost替代方案相比没有任何好处


是否有人有一个聪明的解决方案来解决这个问题,或者是否有一个现有的(经许可的)ComboBox平面样式渲染堆栈的重新实现,它修复了现有实现中的一些缺点?

下面是一个使其工作的方法。。。有点像:)

为的事件创建事件处理程序。然后循环遍历所有的对象,并在其周围绘制一个矩形

    private Color cbBorderColor = Color.Gray;
    private Pen cbBorderPen = new Pen(SystemColors.Window);

    private void toolStrip1_Paint(object sender, PaintEventArgs e)
    {            
        foreach (ToolStripComboBox cb in toolStrip1.Items)
        {
            Rectangle r = new Rectangle(
                cb.ComboBox.Location.X - 1,
                cb.ComboBox.Location.Y - 1,
                cb.ComboBox.Size.Width + 1,
                cb.ComboBox.Size.Height + 1);

            cbBorderPen.Color = cbBorderColor;
            e.Graphics.DrawRectangle(cbBorderPen, r);
        }
    }
下面是它的外观(请注意,您可能需要调整ToolStrip的高度,以防止绘制的边框被切断):


改进: 检查toolstrip项目的类型, 例如,如果是toolstipLabel,那么程序将不会崩溃。

}

这将设置组合框周围的默认OS样式边框。它是Windows 10上的浅灰色薄边框。不过,根据背景的不同,这可能不会显示。在这种情况下,您可以尝试其他选项,如
FlatStyle.Popup


如果预设不是您想要的,其他答案允许您绘制自定义边框。但是,由于矩形是以+1像素大小围绕组合框绘制的,因此边框比组合框大1像素。删除+1和-1也不起作用。

如果(项目是ToolStripComboBox cb),也可以使用
而不是
作为
!=空
foreach (var item in toolStrip1.Items)
{
      var asComboBox = item as ToolStripComboBox;
      if (asComboBox != null)
      {
          var location = asComboBox.ComboBox.Location;
          var size = asComboBox.ComboBox.Size;
          Pen cbBorderPen = new Pen(Color.Gray);
          Rectangle rect = new Rectangle(
                  location.X - 1,
                  location.Y - 1,
                  size.Width + 1,
                  size.Height + 1);

          e.Graphics.DrawRectangle(cbBorderPen, rect);
       }
toolStrip1.ComboBox.FlatStyle = FlatStyle.System;