0

I am trying to make a control that can hold a variable amount of strings and adjust it's height dynamically by programmatically changing the height of this control.

So far I have tried the Checked Listbox and the ListView.

The listbox keeps showing a horizontal scrollbar, even though it has been set to false. The ListView looks more promising but it refuses to realign the items in the box:

public partial class Form1 : Form
{
    string[] content = 
        {
            "Lorem",
            "ipsum",
            "dolor",
            "sit",
            "amet",
            "consectetur",
            "adipiscing",
            "elit" ,
            "Integer" ,
            "commodo" ,
        };

    ListView listView1 = new ListView();

    public Form1()
    {
        InitializeComponent();

        listView1.Size = new System.Drawing.Size(300, 22);
        listView1.Font = new Font(FontFamily.GenericMonospace, 10);
        listView1.CheckBoxes = true;
        listView1.View = View.List;
        listView1.Scrollable = false;

        this.Controls.Add(listView1);

        groupBox1.Controls.Add(listView1);

        foreach (string str in content)
        {
            listView1.Items.Add(str.PadRight(12));
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        listView1.Height = 100;
    }
}

If I move the listView1.Height = 100; to the constructor of the class it will work so obviously that's where the problem lies. I can't seem to find what the root cause of this problem is though... Should I call some member function of the listbox to re-place it's items?

Update After fiddling some more it seems that the behavior can be reproduced also by adding items to the list using the designer, setting all the anchors, snap to the edges of the form and resizing the form at runtime. Then, again, the items will not realign. Still stuck on how to force to re-position the items in the listview though.

Nebula
  • 1,045
  • 2
  • 11
  • 24
  • Is the load event firing? If so did you try listView1.Refresh()? – Belmiris Aug 16 '12 at 13:56
  • @Belmiris Yeah, but the problem is not that the listview isn't resizing; it does that perfectly. The items in the listview stay as they were however: single row and outside the control. If you can find the time just copy paste the above code in an empty windows form project and you'll see what I mean. – Nebula Aug 16 '12 at 14:03
  • Not finding a solution - but using a different View setting (like SmallIcon) does not have this issue. Just don't set an ImageList. – John Arlen Aug 16 '12 at 20:10
  • I've been reading some more MSDN and indeed, there does not seem to be a solution for this. Writing my own placement routine won't work because one cannot alter Position in List mode. SmallIcon would have been an option where it not for the fact that there is a bug in SmallIcon which places the checkbox outside the control for the first column. I'm best off writing my own list. I'll post an answer if I have something to my satisfaction. Thanks! – Nebula Aug 20 '12 at 06:26

2 Answers2

1

Only now I realize What my answer is really doing. I basically reimplemented the Checkbox using an additional label for the text. Right...

Solution My solution ultimately boils down to a couple of checkboxes in a flowlayout panel.

Nebula
  • 1,045
  • 2
  • 11
  • 24
0

After some more investigation and the comments provided to me I dropped the idea of using standard controls. Here's why:

  • CheckedListBox: Has a bug where the scrollbar re-appears when the control's size is programatically changed.
  • ListView in List mode: Cannot re-align icons when past form's constructor.
  • ListView in SmallIcon mode: Has a bug that places the ceckbox outside the control for the first column.

So I decided to make my own control using these two sources:

I made myself a CheckedLabel:

Designer

#region Component Designer generated code

/// <summary>
/// Required method for Designer support - do not modify 
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
    this.cbCheckbox = new System.Windows.Forms.CheckBox();
    this.lblDisplay = new System.Windows.Forms.Label();
    this.SuspendLayout();
    // 
    // cbCheckbox
    // 
    this.cbCheckbox.AutoSize = true;
    this.cbCheckbox.Location = new System.Drawing.Point(3, 3);
    this.cbCheckbox.Name = "cbCheckbox";
    this.cbCheckbox.Size = new System.Drawing.Size(15, 14);
    this.cbCheckbox.TabIndex = 0;
    this.cbCheckbox.UseVisualStyleBackColor = true;
    this.cbCheckbox.CheckedChanged += new System.EventHandler(this.cbCheckbox_CheckedChanged);
    // 
    // lblDisplay
    // 
    this.lblDisplay.AutoSize = true;
    this.lblDisplay.Location = new System.Drawing.Point(24, 4);
    this.lblDisplay.Name = "lblDisplay";
    this.lblDisplay.Size = new System.Drawing.Size(35, 13);
    this.lblDisplay.TabIndex = 1;
    this.lblDisplay.Text = "label1";
    // 
    // CheckedLabel
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.AutoSize = true;
    this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
    this.Controls.Add(this.lblDisplay);
    this.Controls.Add(this.cbCheckbox);
    this.Name = "CheckedLabel";
    this.Size = new System.Drawing.Size(62, 20);
    this.ResumeLayout(false);
    this.PerformLayout();

}

#endregion

Implementation

[System.ComponentModel.DefaultEvent("CheckedChanged")]
public partial class CheckedLabel : UserControl
{
    public event EventHandler CheckedChanged;

    public CheckedLabel()
    {
        InitializeComponent();
    }

    public override string Text
    {
        get
        {
            return lblDisplay.Text;
        }

        set
        {
            lblDisplay.Text = value;
        }
    }


    private void cbCheckbox_CheckedChanged(object sender, EventArgs e)
    {
         // Pass the checkbox event as an ultra-shallow copy
        CheckBox b = new CheckBox();
        b.Checked = cbCheckbox.Checked;
        b.Text = lblDisplay.Text;

        CheckedChanged(b, e);
    }        
}

And add these controls to a FlowLayout panel. This setup actually allows me to grow and shrink the container as I see fit while automatically re-aligning the CheckedLabels to provde the best fit.

Community
  • 1
  • 1
Nebula
  • 1,045
  • 2
  • 11
  • 24