gpt4 book ai didi

.net - 无法设置 ComboBox 的 DropDownHeight

转载 作者:行者123 更新时间:2023-12-04 11:14:15 28 4
gpt4 key购买 nike

我无法正确设置 ComboBox 的 DropDownHeight 以显示所有项目。

我正在使用从 ComboBox 继承的控件。我已经覆盖了 OnDrawItem 和 OnMeasureItem 方法,以便在需要时在列中创建多列和文本换行。这一切正常。

当我尝试设置 DropDownHeight 时会出现问题。我将 DropDownHeight 设置为一个任意大的值,比项目列表大一点。 ComboBox 控件似乎会自动截断任何大于列表中所有显示项目大小的 DropDownHeight 值。 (假设您将 MaxDropDownItems 属性设置为高于项目数,我就是这样做的。)通常这种行为可以完美运行,如下所示:
alt text http://www.freeimagehosting.net/uploads/dd09404697.png

不,那不是我在下拉框中的真实数据。

当我在下拉列表中有一个条目需要换行以显示全文时,就会出现问题。此条目显示正常,但是 ComboBox 正在计算 DropDownHeight,它忽略了一个条目是正常高度两倍的事实,因此您必须向下滚动一行才能到达下拉列表中的最后一个条目。
alt text http://www.freeimagehosting.net/uploads/d0ef715f83.png

这是我用来确定一个项目是否需要文本换行和设置每个项目的高度的代码:

 Protected Overrides Sub OnMeasureItem(ByVal e As System.Windows.Forms.MeasureItemEventArgs)
MyBase.OnMeasureItem(e)
//Determine the proper height of the current row in the dropdown based on
//the length of the OptionDescription string.
Dim tmpStr As String = FilterItemOnProperty(Items(e.Index), "OptionDescription")
Dim lng As Single = e.Graphics.MeasureString(tmpStr, Me.Font).Width
//Use the length of the item and the width of the column to calculate if wrapping is needed.
Dim HeightMultiplier As Integer = Math.Floor(lng / _ColumnWidths(1)) + 1
e.ItemHeight = e.ItemHeight * HeightMultiplier

End Sub

我无法确定如何强制 DropDownHeight 属性恰好为我想要的值,或者如何让 ComboBox 控件知道列表中的一个(或多个)项目高于正常值。

我试图覆盖 DropDownHeight 属性的阴影,但这似乎没有影响。

编辑:
切换到 WPF 会让这个问题消失吗? (标准 WPF 控件是否具有足够的可定制性,以便我不需要为 3 列可变高度组合框编写自定义控件?)

最佳答案

我正在尝试为我正在从 VB6 迁移到 VB.NET 的应用程序解决这个完全相同的问题。我在 VB6 中的自绘组合控件通过 SetWindowPos API 调用设置下拉的高度以响应组合控件上的 WM_CTLCOLORLISTBOX 消息,这使我们可以访问组合下拉列表的 HWnd控制。以下代码已添加到我从 ComboBox 继承的类中,似乎可以解决问题,但仍需要测试。我也不确定这是否是最优雅的方式。显然,您需要更改设置 newHeight 变量的行,但这应该会给您一个总体思路。

Private Structure RECT
Public Left As Integer 'x position Of upper-left corner
Public Top As Integer 'y position Of upper-left corner
Public Right As Integer 'x position Of lower-right corner
Public Bottom As Integer 'y position Of lower-right corner
End Structure

Private Declare Function GetWindowRect Lib "user32" _
(ByVal hwnd As Integer, ByRef lpRect As RECT) As Integer

Private Declare Sub SetWindowPos Lib "user32" _
(ByVal hwnd As Integer, ByVal hWndInsertAfter As Integer, _
ByVal X As Integer, ByVal Y As Integer, _
ByVal cx As Integer, ByVal cy As Integer, _
ByVal wFlags As Integer)

Private Const SWP_NOZORDER As Integer = &H4
Private Const SWP_NOACTIVATE As Integer = &H10
Private Const SWP_FRAMECHANGED As Integer = &H20
Private Const SWP_NOOWNERZORDER As Integer = &H200

Private _hwndDropDown As Integer = 0

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const WM_CTLCOLORLISTBOX As Integer = &H134

If m.Msg = WM_CTLCOLORLISTBOX Then
If _hwndDropDown = 0 Then
_hwndDropDown = m.LParam.ToInt32

Dim r As RECT
GetWindowRect(m.LParam.ToInt32, r)

'height of four items plus 2 pixels for the border in my test
Dim newHeight As Integer = 4 * MyBase.ItemHeight + 2

SetWindowPos(m.LParam.ToInt32, 0, _
r.Left, _
r.Top, _
MyBase.DropDownWidth, _
newHeight, _
SWP_FRAMECHANGED Or _
SWP_NOACTIVATE Or _
SWP_NOZORDER Or _
SWP_NOOWNERZORDER)
End If
End If

MyBase.WndProc(m)
End Sub

Protected Overrides Sub OnDropDownClosed(ByVal e As System.EventArgs)
_hwndDropDown = 0
MyBase.OnDropDownClosed(e)
End Sub

关于.net - 无法设置 ComboBox 的 DropDownHeight,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1245530/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com