1

我编写了一些代码来使用 mListBox.ItemHeight 和 mListBox.CreateGraphics().MeasureString(...) 自动将 CheckedListBox 缩放到其内容。字符串测量的输出有点可疑,但真正让我困惑的是要为边框等添加多少。

我尝试了 SystemInformation.Border3DSize (= 2) 以及 ClientSize 和 Size (= 4) 之间的差异。但是将 mListBox.ItemHeight * mListBox.Items.Count + 4 作为高度会使其太小一个像素并出现滚动条。

对于宽度,它根本不起作用,因为它没有考虑我似乎无法找到来源的复选框的大小。

我应该如何确定控件的大小?

4

1 回答 1

1

在这种情况下,通常更容易设置 ClientSize 而不是整个 Size。关于 ItemHeight 需要注意的一件事是它不包括项目的边距。使用默认设置的 CheckedListBox,我的 ItemHeight 为 13。但 ItemRectangle 属性的高度为 15。

所以这就是我所做的。我在 CheckedListBox 中添加了 9 个项目(第一个项目比其他项目长),保持设计者设置的控件的默认大小。然后在表单的构造函数中,我将 ClientSize 设置为:

this.checkedListBox1.ClientSize = new Size(TextRenderer.MeasureText(checkedListBox1.Items[0].ToString(), checkedListBox1.Font).Width + 20, checkedListBox1.GetItemRectangle(0).Height * checkedListBox1.Items.Count);

请注意,我使用 TextRenderer.MeasureText 来测量文本。它通常会为您提供比 Graphics.MeasureString 更好的值。默认情况下,TextRenderer 在其测量中包含一些填充。我还包括一个 20 像素的填充来说明复选框。无论如何,使用 TextRenderer.MeasureText,宽度为 20 像素的填充,高度为 ItemRectangle * Items.Count,这给了我一个 CheckedListBox,它的大小与其内容一样,没有 ScrollBars。

编辑:如果项目宽度不同,设置宽度可能会变得复杂,因为您需要根据最长的项目设置宽度。在这种情况下,您需要测量每个项目并跟踪哪个项目最长。

编辑 2:好的,所以我在 CheckedListBox 源代码中进行了挖掘。他们使用默认大小 13 加上 3 像素填充作为复选框的宽度和高度。但是,如果启用了 VisualStyles,它们会调用CheckBoxRenderer.GetGlyphSize以获取要使用的尺寸,因为它考虑了 DPI 设置。大多数机器设置为 96 DPI,因此该方法仍将返回 (13,13) 的大小。因此,当您测量项目的文本时,您还可以将 Graphics 对象和 CheckBoxState 枚举传递给CheckBoxRenderer.GetGlyphSize以获取大小。我用于System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal状态,但我不确定状态是否重要。我也试过CheckBoxState.MixedDisabled了,它返回了相同的大小,(13,13)。

总而言之,您可以使用CheckBoxRenderer来获取复选框的大小,但您可能仍需要使用一些填充。这减少了硬编码幻数以说明复选框的需要。由于复选框已绘制并且不是实际控件,因此无法像控件大小一样确定其大小。

这是 CheckedListBox 源的链接。看着它不会有什么坏处。具体看protected override void OnDrawItem方法。

CheckedListBox 源

于 2013-02-11T00:36:59.163 回答