无法设置ComboBox的DropDownHeight [英] Unable to set the DropDownHeight of ComboBox

查看:190
本文介绍了无法设置ComboBox的DropDownHeight的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不能让组合框设置适当,以显示所有项目的DropDownHeight。

I cannot get the DropDownHeight of the ComboBox set properly to display all the items.

我使用的是控制继承从ComboBox。我已重写以一列内创建多个列和文字环绕如果需要的的OnDrawItem和OnMeasureItem的方法。这一切工作正常。

I am using a control that inherits from the ComboBox. I have overridden the OnDrawItem and OnMeasureItem methods in order to create multiple columns and text-wrapping within a column if it is required. This all works fine.

当我尝试设置DropDownHeight出现问题。我设置DropDownHeight在任意大的值,比项目列表中选择一个好一点的要大。 ComboBox控件出现自动截断为DropDownHeight比列表中的所有显示项目的大小任意值。 (假设你的MaxDropDownItems属性设置不是项目,这是我做的要多。)一般情况下这种行为作品完美,如下图所示:

The problem occurs when I try to set the DropDownHeight. I set the DropDownHeight at an arbitrarily large value, a good bit larger than the list of items. The ComboBox control appears to automatically truncate any value for DropDownHeight that is larger than the size of all the displayed items in the list. (Assuming that you have the MaxDropDownItems property set higher than the number of items, which I do.) Normally this behavior works perfectly, as shown below:

没有,那不是我的在下拉框中的实际数据。

No, that's not my real data in the drop-down box.

当我在下拉需要为了显示完整的文字换行一个条目时,会出现问题。此项目显示正常,但却在组合框计算DropDownHeight,它忽略了一个事实,即项目的一个高一倍正常,所以你必须向下滚动一行去在下拉列表中的最后一项。

The problem occurs when I have an entry in the drop-down that needs to wrap in order to display the full text. This entry displays fine, but however the ComboBox is calculating the DropDownHeight, it ignores the fact that one of the entries is twice as tall as normal, so you have to scroll down one line to get to the last entry in the drop-down.

这是我用来确定一个项目需要的文本换行,并设置每个项目的高度code:

This is the code that I am using to determine if an item needs text wrapping and to set the height of each item:

 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控件知道,一个在列表中的项目(或以上)比正常高。

I cannot determine how to force the DropDownHeight property to be exactly the value that I want, or how to let the ComboBox control know that one (or more) of the items in the list are taller than normal.

我试图<打击>覆盖影着DropDownHeight属性,但是这似乎没有影响。

I've tried to Override Shadow the DropDownHeight property, but this seemed to have no impact.

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

推荐答案

我试图解决这一确切同样的问题我自己就在一瞬间是我迁移从VB6到VB.NET的应用程序。所有者绘制组合框控件我在VB6设置响应的组合控制WM_CTLCOLORLISTBOX消息,这让我们获得了HWND为组合的下拉列表中通过SetWindowPos API调用下拉的高度控制。下面$ C $下添加到我的类继承的组合框,似乎这样的伎俩,但仍需要检验。我不知道它是这样做无论是最优雅的方式。显然,你需要更改设置newHeight变线,但这应该给你的总体思路。

I'm trying to solve this exact same problem myself right at the moment for an application that I am migrating from VB6 to VB.NET. The owner-drawn combo control I have in VB6 sets the height of the drop-down through a SetWindowPos API call in response to the WM_CTLCOLORLISTBOX message on the combo control, which gives us access to the HWnd for the drop-down list of the combo control. The following code was added to my class that inherits from ComboBox and seems to do the trick, but still needs testing. I'm not sure it's the most elegant way of doing this either. Obviously you'll need to change the line that sets the newHeight variable, but this should give you the general idea.

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

这篇关于无法设置ComboBox的DropDownHeight的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆