0

I have tried a lot of things.

Rectangle r = checkedListBox1.GetItemRectangle(0);
checkedListBox1.ClientSize = new Size(checkedListBox1.PreferredSize.Width, checkedListBox1.PreferredSize.Height);

Here I tried resizing the ClientSize to the PreferredSizes, this doesn't seem to always work. An odd note is that PreferredSize.Height is not always correct if I don't previously call GetItemRectangle().

I have tried capturing the maximum bounds on OnDrawItem with no luck because this only gives information about whats being painted.

I have tried iterating over each element using TextRenderer.MeasureText()

I have tried creating a fake graphics class along with graphics.MeasureString() to measure it in a simular fashion to which it was painted.

 foreach (string selection in this.Items)
{


    Image tmpImg = new Bitmap(1, 1);
    Graphics graphics = Graphics.FromImage(tmpImg);

    StringFormat format = new StringFormat(StringFormat.GenericTypographic);
    format.Trimming = StringTrimming.None;
    format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;

    SizeF size = graphics.MeasureString(selection, this.Font, 0, format);
    float selectionWidth  = size.Width + PaddingRecommendedByMSDN + CustomCheckBoxWidth;

    if (selectionWidth > maxWidth)
        maxWidth = (int)selectionWidth;


}
Rectangle r = this.GetItemRectangle(0);
this.ClientSize = new Size((int)maxWidth , this.PreferredSize.Height );

Although this last solution seems to be the most accurate. It still is slightly off on large strings.

Does anyone know where I can properly capture the maximum width of the item contents of a CheckedListBox? I'm just trying to make the width fill the CheckedListBox so there are no scrolls shown. PreferredSize.Height never seems to fail me, only the width.

clamchoda
  • 4,411
  • 2
  • 36
  • 74
  • CheckedListBox does not override GetPreferredSizeCore(). So you get the ListBox flavor of it. Which does nothing to include the space required for the checkbox. You'll have to hoof it yourself from the [drawing code](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/CheckedListBox.cs,14f67cb9fa3d0235), not fun. – Hans Passant Aug 02 '18 at 18:03
  • @HansPassant Ok thanks. I was playing with OnDrawItem but I got stuck because it does not fire for all Items, only the visible items. Do you have a suggestion on where to start in the drawing code? On a side note, you're my hero around here. Thank you for all your contributions. All my tricky questions always lead to your answers. – clamchoda Aug 02 '18 at 18:21
  • @HansPassant I was considering creating a custom CheckedListBox control which would just be a panel of CheckBoxes. The CheckBoxes would also be overriden and replace the painted string with an AutoSize label as well as setting the CheckBox minimum size, and click event. Is this approach overkill compared to extracting it from the drawing code in your experiences? – clamchoda Aug 02 '18 at 20:45

1 Answers1

0

Trying using TextRenderer.MeasureText instead:

Size size = TextRenderer.MeasureText(selection, this.Font);

TextRenderer uses GDI to render the text, whereas Graphics uses GDI+. The two use a slightly different method for laying out text so the sizes are different.

If the text will be displayed inside a Windows Forms control (in your case it will), it uses TextRenderer if UseCompatibleTextRendering is set to false (which is the default).

More generic information can be found here: TextRenderer.MeasureText and Graphics.MeasureString mismatch in size

Ctznkane525
  • 7,297
  • 3
  • 16
  • 40
  • I tried that one in my second attempt but it always returns shorter (incorrect) results than MeasureString when measuring a large string. Any thoughts? – clamchoda Aug 02 '18 at 18:11