【问题标题】:How can I remove the drop shadow from a ComboBox DropDown in WinForms?如何从 WinForms 中的 ComboBox DropDown 中删除阴影?
【发布时间】:2019-03-11 12:38:46
【问题描述】:

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

这就是现在的样子:

这就是我想要的样子:

我怎样才能做到这一点?

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

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);
    }
}

【问题讨论】:

  • 如果您将其设置为“平面”,则不应出现阴影
  • ListControl的类名是ComboLBox...
  • 恕我直言 Winforms 旨在为所有应用程序提供一致的外观和感觉。这些细节真的无法改变。如果您需要对外观和感觉进行更多控制,您可能应该切换到 WPF 或创建您自己的完整用户控件,在所有情况下都可以自行绘制。

标签: c# winforms combobox dropdown dropshadow


【解决方案1】:

可能有更好的方法来做到这一点,但可以通过 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 控件的样式。它具有强大的工具,可让您将视觉外观更改为您喜欢的任何内容。

【讨论】:

    猜你喜欢
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多