我编写了一些代码,使用mListBox.ItemHeight和mListBox.CreateGraphics()。MeasureString(...)自动将CheckedListBox缩放到其内容。 字符串测量的输出有点可疑但真正让我感到困惑的是为边界添加了多少等等。
我尝试了SystemInformation.Border3DSize(= 2)以及ClientSize和Size(= 4)之间的差异。 但是将mListBox.ItemHeight * mListBox.Items.Count + 4作为高度会使它的像素太小而出现滚动条。
对于宽度,它根本不起作用,因为它没有考虑复选框的大小,我似乎无法找到它。
我应该如何确定控件的大小?
答案 0 :(得分: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
方法。