如何从WinForms中的ComboBox DropDown中删除阴影?

时间:2019-03-11 12:38:47

标签: c# winforms combobox dropdown dropshadow

我到处搜索并尝试了我所知道的一切,但是似乎找不到摆脱ComboBox控件中DropDown弹出窗口中嵌入的CS_DROPSHADOW的方法。

这是现在的样子:

enter image description here

这就是我想要的样子:

enter image description here

我该如何实现?

更新: 我尝试了每种属性组合,但都没有设法解决。 现在如何设置它们:

DropDownStyle = DropDownList

FlatStyle =扁平

DrawMode = OwnerDrawFixed

这是DrawItem的实现方式:

if (sender is ComboBox cbx)
{
    e.DrawBackground();

    if (e.Index >= 0)
    {
        StringFormat sf = new StringFormat
        {
            LineAlignment = StringAlignment.Center + 1,
            Alignment = StringAlignment.Center
        };

        if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
            e.Graphics.FillRectangle(new SolidBrush(Color.Gainsboro), e.Bounds);
        else
            e.Graphics.FillRectangle(new SolidBrush(cbx.BackColor), e.Bounds);

    e.Graphics.DrawString(cbx.Items[e.Index].ToString(), cbx.Font, new SolidBrush(cbx.ForeColor), e.Bounds, sf);
    }
}

1 个答案:

答案 0 :(得分:0)

可能有更好的方法来执行此操作,但是可以通过WinAPI调用+反射来删除阴影。我没有看到任何允许我访问下拉窗口的属性,因此我使用了反射来获取它。我想该句柄是一个短暂的对象,因此对用户是隐藏的。无论如何,一旦获得句柄,就可以使用SetClassLongPtr32函数更改窗口类样式(对于64位,您可能需要使用此函数的其他版本,请查看文档)。

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace TestComboBox
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            comboBox1.DropDown += ComboBox1_DropDown;
        }

        private void ComboBox1_DropDown(object sender, EventArgs e)
        {
            var fieldInfo = comboBox1.GetType().GetField("dropDownHandle", BindingFlags.Instance | BindingFlags.NonPublic);
            var dropDownHandle = (IntPtr)fieldInfo.GetValue(comboBox1);

            const uint CS_DROPSHADOW = 0x00020000;
            const int GCL_STYLE = -26;
            uint currentWindowClassStyle = GetClassLongPtr32(new HandleRef(comboBox1, dropDownHandle), GCL_STYLE);
            uint expectedWindowClassStyle = currentWindowClassStyle & (~CS_DROPSHADOW);
            SetClassLongPtr32(new HandleRef(comboBox1, dropDownHandle), GCL_STYLE, expectedWindowClassStyle);
        }

        [DllImport("user32.dll", EntryPoint = "GetClassLong")]
        public static extern uint GetClassLongPtr32(HandleRef hWnd, int nIndex);
        [DllImport("user32.dll", EntryPoint = "SetClassLong")]
        public static extern uint SetClassLongPtr32(HandleRef hWnd, int nIndex, uint dwNewLong);
    }
}

作为旁注,我宁愿使用WPF来设置UI控件的样式。它具有强大的工具,可让您将视觉外观更改为所需的任何外观。

相关问题