我正在创建一个可以绘制分隔符的自定义组合框。所以,我重写了OnDrawItem()和OnMeasureItem()方法
问题是OnMeasureItem()只在数据源更改时被调用一次。因此,如果我想稍后指定一个分隔项,我需要重新测量它的高度(因为带分隔符的项目应该更高),但似乎所有可能导致项目高度被重新测量的方法都是私有的,所以我不能称它们为。
我不知道上面写的内容是否容易理解,所以我会重复我需要的内容:
每当我指定应使用分隔符绘制项目时,我需要重新测量项目高度(必须调用OnMeasureItem())。
separatorableComboBox.DataSource = customers;
// and now I want the third customer in the list to be drawn with a separator,
// so it needs to be taller and therefore OnMeasureItem() should be called
separatorableComboBox.SpecifySeparatorItem(customers[2]);
UPD。伙计们,调用RefreshItems()有效,但速度非常慢(我的机器上大约20毫秒),有更快的方法吗?
UPD2。现在我正在使用SendMessage(...,CB_SETITEMHEIGHT,...);方法为serge_gubenko建议。但是我很好奇是否有一种快速的方法来完成.NET的任务(或更具体地说是ComboBox类本身)?
答案 0 :(得分:4)
您可以致电ComboBox.RefreshItems()
,以便在您的CustomCombo课程MeasureItem()
内提出SpecifySeparatorItem()
来电:
public void SpecifySeparatorItem(object arg)
{
//do some stuff
this.RefreshItems();
//do some more stuff
}
或者通过您可以在其他地方调用的公共方法公开ComboBox.RefreshItems()
public partial class CustomCombo : ComboBox
{
public CustomCombo ()
{
InitializeComponent();
}
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem(e);
}
public void RaiseOnMeasureItem()
{
this.RefreshItems();
}
}
答案 1 :(得分:3)
为了澄清,我假设您使用OwnerDrawVariable
样式用于组合框。如果我理解你的问题,有几种方法可以做你需要的:
RefreshItems
方法,该方法会为每个项目重新创建项目并触发onMeasureItem
事件。此方法受ComboBox
类保护,因此以下是如何使用反射执行此操作的示例: MethodInfo method = comboBox1.GetType().GetMethod(
"RefreshItems", BindingFlags.Instance | BindingFlags.NonPublic);
if (method != null) method.Invoke(comboBox1, null);
CB_SETITEMHEIGHT
消息发送给控件: public const int CB_SETITEMHEIGHT = 0x0153;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
...
// this will set height to 100 for the item with index 2
SendMessage(comboBox1.Handle, CB_SETITEMHEIGHT, 2, 100);
希望这有帮助,尊重