Home General
Options

Can I get WrapPanel to use the full-width of the screen without hardcoding the children's width?

I have a custom control which uses the full width of the screen when dumped on its own, but I would like to be able to dump several side by side. I am using a WrapPanel to do this, but this shrinks my user control.

If I hard-code the width of the children, then the control is drawn correctly, but I would prefer to calculate the width as a percent of it's parent (i.e. 50% for two children, 33% for three etc).

Is this possible?

The following script demos the issue.

using LINQPad.Controls;

void Main()
{
    var section1 = new CheckBoxSet(new string[] { "CheckBox 1", "CheckBox 2", "CheckBox 3" });
    var section2 = new CheckBoxSet(new string[] { "CheckBox 4", "CheckBox 5", "CheckBox 6" });
    var section3 = new CheckBoxSet(new string[] { "CheckBox 7", "CheckBox 8" });

    var section4 = new CheckBoxSet(new string[] { "CheckBox 1", "CheckBox 2", "CheckBox 3" });
    var section5 = new CheckBoxSet(new string[] { "CheckBox 4", "CheckBox 5", "CheckBox 6" });
    var section6 = new CheckBoxSet(new string[] { "CheckBox 7", "CheckBox 8" });

    Console.WriteLine("Hard coding the width works.");   
    new FullWidthWrapPanel("20em", section1, section2, section3).Dump();
    Console.WriteLine("");

    Console.WriteLine("But attempting to avoid hard-coding does not.");
    new FullWidthWrapPanel(null, section4, section5, section6).Dump();

}

public class FullWidthWrapPanel : WrapPanel
{
    public FullWidthWrapPanel(string? width, params Control[] children) : base(children)
    {
        base.ChildVerticalAlign = "top";

        width = width ?? $"{100 / children.Length}%";

        Debug.WriteLine($"Setting width of children to {width}\r\n");

        foreach(var r in children)
            r.Styles["width"] = width ;
    }    
}

public class CheckBoxSet : Control
{
    public CheckBoxSet(string[] options )
    {
        var checkBoxes = new LINQPad.Controls.CheckBox[options.Length];

        for (int i = 0; i < options.Length; i++)
            checkBoxes[i] = new CheckBox(options[i], false);

        var fieldSet = new FieldSet("Set",   new LINQPad.Controls.StackPanel(false, checkBoxes)); 
        fieldSet.Styles["vertical-align"] = "top";

        VisualTree.Add(fieldSet);
    }   
}

Screenshot

Comments

  • After F12-ing on base.ChildVerticalAlign and seeing what it does, I was able to get this working using

    public class FullWidthWrapPanel : WrapPanel
    {
        public FullWidthWrapPanel(params Control[] children) : base(children)
        {
            base.Gap = "0.1%";
            base.ChildVerticalAlign = "top";
            base.CssChildRules[">div", "width"] = $"{Math.Round((100.0 / children.Length), 2) - 0.1}%";
        }
    }
    
Sign In or Register to comment.