簡體   English   中英

如何從 WinForms 中的 ComboBox DropDown 中刪除陰影?

[英]How can I remove the drop shadow from a ComboBox DropDown in WinForms?

我到處搜索並嘗試了我所知道的一切,但似乎無法找到一種方法來擺脫 ComboBox 控件的 DropDown 彈出窗口中嵌入的 CS_DROPSHADOW。

這是它現在的樣子:

在此處輸入圖片說明

這就是我想要的樣子:

在此處輸入圖片說明

我怎樣才能做到這一點?

更新:我嘗試了所有屬性組合,但沒有設法解決它。 現在如何設置:

DropDownStyle = DropDownList

平面樣式 = 平面

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

可能有更好的方法來做到這一點,但可以使用 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 控件的樣式。 它具有強大的工具,可讓您將視覺外觀更改為您喜歡的任何內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM