更改ComboBox边框轮廓颜色

8
我正在尝试管理ComboBox的颜色。虽然可以更改背景颜色,但我找不到边框轮廓的属性。
只是画一个方形作为边框在暗主题中行不通,因为有箭头。这让我得出结论,这个边框可能是一个实际的图像文件。
能否替换它?

enter image description here

更新: 我已经实现了@AhmedAbdelhameed的解决方案-现在看起来好多了。但是对于平面风格,我不得不像下面这样调整矩形:

using (var p = new Pen(this.BorderColor, 1))
{
    g.DrawRectangle(p, 0, 0, Width - buttonWidth - 1, Height - 1);
}

我还将“BorderColor”更改为与我的用户界面其他部分相匹配:
public CustomComboBox()
{
    BorderColor = Color.Gray;
} 

这是目前的结果: 在此输入图片描述 在此输入图片描述 现在我想要做的是,在暗色主题下仅更改下拉按钮(可能使用叠加的png)。
更新: 我已经能够通过以下代码向自定义控件添加picturebox:
using (var g = Graphics.FromHwnd(Handle))
{
    using (var p = new Pen(this.BorderColor, 1))
    {
        g.DrawRectangle(p, 0, 0, Width - buttonWidth - 1, Height - 1);
    }
    if (Properties.Settings.Default.Theme == "Dark")
    {
        g.DrawImageUnscaled(Properties.Resources.dropdown, new Point(Width - buttonWidth - 1));
    }
}

看起来很棒!有点巧合的是,当我在主题下拉框中更改主题时,暗色下拉按钮甚至会消失,这一点我不理解。

之前 - 之后比较: 输入图像描述 输入图像描述


有一个名为 BackColor 的属性。更多信息,请在此处阅读 - dbvega
6
@dbvega 这不是问题所在。 - LarsTech
1
请查看这个问题,或者也可以查看这个问题 - 41686d6564 stands w. Palestine
2个回答

7

这个答案的帮助下,我得出了以下结论:

首先,在表单中添加以下内容以避免闪烁:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams handleParam = base.CreateParams;
        handleParam.ExStyle |= 0x02000000;      // WS_EX_COMPOSITED
        return handleParam;
    }
}

现在,请将以下类添加到您的项目中:
public class CustomComboBox : ComboBox
{
    private const int WM_PAINT = 0xF;
    private int buttonWidth = SystemInformation.HorizontalScrollBarArrowWidth;
    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if (m.Msg == WM_PAINT)
        {
            using (var g = Graphics.FromHwnd(Handle))
            {
                // Uncomment this if you don't want the "highlight border".
                /*
                using (var p = new Pen(this.BorderColor, 1))
                {
                    g.DrawRectangle(p, 0, 0, Width - 1, Height - 1);
                }*/
                using (var p = new Pen(this.BorderColor, 2))
                {
                    g.DrawRectangle(p, 2, 2, Width - buttonWidth - 4, Height - 4);
                }
            }
        }
    }

    public CustomComboBox()
    {
        BorderColor = Color.DimGray;
    }

    [Browsable(true)]
    [Category("Appearance")]
    [DefaultValue(typeof(Color), "DimGray")]
    public Color BorderColor { get; set; }
}

重建项目,用新的CustomComboBox替换下拉框控件,将BorderColor属性设置为任意颜色,就可以开始使用了。

结果:

ComboBox_BorderColor

更新:

使用以下数值似乎会得到更好的效果(尤其是在单击下拉按钮时),但您可能仍需要绘制第一个矩形(上面已注释)以避免仅在按钮周围显示“突出边框”:

using (var p = new Pen(this.BorderColor, 3))
{
    g.DrawRectangle(p, 1, 1, Width - buttonWidth - 3, Height - 3);
}

1
我想我得感谢你链接了我之前发布的那个丑陋的答案。我已经更新了它(至少不再泄漏)。我自己制作了一个类,基于Reza Aghaei的答案。这是我为另一个网站发布的PasteBin,其中包含相关部分。我认为在构造函数中需要添加一件事情:SetStyle(ControlStyles.ResizeRedraw, true)。如果我没记错的话,这会有所帮助。 - Jimi
1
@Jimi,实际上我最初选择的是SetStyle,但它在这种特定情况下似乎无法消除闪烁(原因不明!)。这就是为什么我用在表单级别重写CreateParams属性来替换它,而这对我来说每次都有效。 - 41686d6564 stands w. Palestine
是的,当我说它有帮助时,我指的是在表单设计器中,根据实际实现,在调整控件大小时可以正确绘制。闪烁是另一回事;我知道以这种方式设置CreateParams是这种情况下的一个好解决方法。 - Jimi
你好Ahmed,感谢你的回答,这已经帮了我很多。你认为有没有可能在Combobox右侧用一个三角形覆盖PNG来使这个方块变暗?我会实现你的解决方案并更新我的问题。 - julian bechtold
如果您使用SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true)修改控件样式,那么将会触发Paint事件,您可以在按钮区域内绘制任何内容。不过需要进行更多的工作。WndProc WM_PAINT重写可以移动到Paint事件中。所有控件的NC区域设计都由您来完成。 - Jimi
@Jimini,我已经更新了我的问题 ;) 我稍微做了一点"简单",但它运行得非常好! - julian bechtold

0

为了给组合框添加全宽的边框,您必须从绘制中删除按钮宽度。在我的情况下,我只想改变边框的颜色,所以1像素就足够了。

using (var p = new Pen(this.BorderColor, 1))
{
    g.DrawRectangle(p, 0, 0, Width - 1, Height - 1);
}

那意味着自定义组合框的行为与通用组合框完全相同,例如在悬停时等等。

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