C# 可变大小的所有者绘制组合框;列表大小不正确

C# 可变大小的所有者绘制组合框;列表大小不正确,c#,.net,winforms,combobox,C#,.net,Winforms,Combobox,我从ComboBox派生了一个类,使其成为所有者绘制的列表框(DrawMode.OwnerDrawVariable样式),并通过覆盖OnMeasureItem和OnDrawItem,向下拉列表中添加特殊项(例如分隔符),这些项的大小比控件中的正常项小/大 现在,我遇到的问题似乎无法有效解决,那就是下拉列表的大小:下拉列表时,列表末尾有一个难看的空白。我想我通过将ComboBox的DropDownHeight属性设置为所有项目高度的总和来解决这个问题,但这似乎并不总是有效。有时,在随机数目的物品上

我从ComboBox派生了一个类,使其成为所有者绘制的列表框(DrawMode.OwnerDrawVariable样式),并通过覆盖OnMeasureItem和OnDrawItem,向下拉列表中添加特殊项(例如分隔符),这些项的大小比控件中的正常项小/大

现在,我遇到的问题似乎无法有效解决,那就是下拉列表的大小:下拉列表时,列表末尾有一个难看的空白。我想我通过将ComboBox的DropDownHeight属性设置为所有项目高度的总和来解决这个问题,但这似乎并不总是有效。有时,在随机数目的物品上,厄运的空白区域会返回。这是一个不寻常的问题,但希望是一个常见且容易解决的问题


如何使组合框的下拉列表的大小精确到其内部项目所占的大小?

我猜您计算下拉列表高度的方式存在问题,我猜是这样的:

comboBox.DropDownHeight = N_of_items * item_height;
comboBox.DropDownHeight = N_of_items * item_height + SystemInformation.BorderSize.Height*2;
下拉列表的总高度还应包括其顶部和底部边框高度,因此,如果您要这样做:

comboBox.DropDownHeight = N_of_items * item_height;
comboBox.DropDownHeight = N_of_items * item_height + SystemInformation.BorderSize.Height*2;
它应该做到这一点,并显示没有白色区域的下拉列表


希望这有帮助,我在ComboBox.UpdateDropDownHeight()方法中看到了一个相当愚蠢的错误。当DropDownHeight属性与默认值匹配时,它将计算一个自定义高度,以使下拉列表与项目数相匹配。即使更改了DrawMode,它也会这样做,这显然是错误的

解决办法:

  int height = ...; // Your code here
  if (height == 106) ++height;
  comboBox1.DropDownHeight = height;

您将获得一个像素的间距,您应该能够在OnDrawItem()重载中隐藏它。

我花了很长时间来解决这个问题

将自定义项添加到组合框时,下拉高度设置不正确。为了保证每次都正确设置,您需要劫持Windows消息


展示了如何。只需跟踪组合框中所有项目(标准和自定义)的高度,然后设置下拉部分的总高度,如示例所示。

此错误扩展得更深一些。DropDownHeight的默认值基于组合框中项目的字体大小。不基于字体大小更改的单个项目高度更改将导致DropDownHeight属性出现问题。否,默认大小是硬编码为常量的,请查看参考源。它被命名为“DefaultDropDownHeight”。如果你的理论是正确的,你应该更频繁地看到这一点。特别是因为您实现了OnMeasureItem,所以项目高度将始终是非标准的。我不得不在这里猜测,你的问题没有暗示什么可能会触发缺口的出现。@nobugz:是的,你是对的。我打字比我想象的快。项目高度基于字体大小。在某些情况下,它是用来确定下拉高度的最大值的。很好地解决了这个问题。我想这个间隙并不是随机的,只有当高度等于106时,它才会重新出现,如你所示。谢谢哇,精神调试得1分。这需要很多人使用DrawMode.OwnerDrawVariable。希望他们能找到这个帖子。谢谢你让我们知道。