[英]In Winforms, can I configure the combobox to allow values not in the drop down list?
[英]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.