WPF FAQ - Layouts

When I try to add multiple controls to a button it shows an error, how do I add multiple controls to a button?

Most of UI Elements in WPF can contain only a single child element, therefore, when you add a control to a button, an error stating that the control has a child and only one child can be added to the control is generated. To overcome this error add layouts like StackPanel inside the control and add multiple controls inside that StackPanel.

The following code snippet will cause the error mentioned above.

[XAML]

<Button Height='100'>
            <RadioButton Content='Button1' />
            <RadioButton>Button 2</RadioButton>>
</Button>

A StackPanel can be used inside the button to have multiple controls inside the button.

The following lines of code can be used to overcome the error.

 [XAML]
<Button Height='100'>
	<StackPanel Orientation='Horizontal'>
        <RadioButton Content='Button1'/>
		<RadioButton>Button 2</RadioButton>
    </StackPanel>
</Button>
Permalink
How placing controls in a WrapPanel differs from a Grid?

Placing controls inside a WrapPanel will shrink the control to it’s minimum width or it will wrap the controls to the next line when the form’s size is reduced. But when the form’s size is increased it will not resize the control accordingly, instead, it will place the controls next to each other. On the other hand, if the controls are placed inside a Grid, it will resize the controls when the form is resized.

Permalink
How do I prevent a control from being resized manually by the user or through docking or anchoring?

The best way to ensure a particular height or width for a control is to override the control’s SetBoundsCore method.

This sample shows a Button which has a fixed height and width. The same technique can be used to set the upper and lower bounds on sizes.

[C#]

using System.Windows.Forms;

public class ButtonWithConstrainedSize : Button
{
  private static int fixedHeight = 50;
  private static int fixedWidth = 50;

  protected override void SetBoundsCore( int x, int y, int width, int height,
      BoundsSpecified specified )
  {
    base.SetBoundsCore( x, y, fixedWidth, fixedHeight, specified );
  }
}
Permalink
How do SuspendLayout and ResumeLayout work ?

SuspendLayout and ResumeLayout only prevent ’OnLayout’ from being called. Additionally they only prevent OnLayout from being called for that particular control. So if you have a Form with a Panel in it and call SuspendLayout on the Form, the Panel’s layout will not be suspended.

[C#]

   private void button1_Click(object sender, EventArgs e) 
{
   this.Layout += new LayoutEventHandler(Form1_Layout);
   panel1.Layout += new LayoutEventHandler(Panel1_Layout);

   // Test one - calling PerformLayout here does not call Form1_Layout.
   this.SuspendLayout();
   this.PerformLayout();
   this.ResumeLayout(false);

   // Test two - calling PerformLayout here calls Panel1_Layout.
   // Child controls are not suspended when the parent is suspended.
   this.SuspendLayout();
   panel1.PerformLayout();
   this.ResumeLayout(false);

   // Test three, properly suspending layout.
   this.SuspendLayout();
   panel1.SuspendLayout();
   panel1.PerformLayout();   // <--- Layout event on Panel NOT called
   panel1.ResumeLayout(false); 
   this.ResumeLayout(false);

   panel1.Layout -= new LayoutEventHandler(Panel1_Layout);
   this.Layout -= new LayoutEventHandler(Form1_Layout);
 }
Permalink