WPF FAQ - Layouts

Find answers for the most frequently asked questions
Expand All Collapse All

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

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

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

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

Share with

Couldn't find the FAQs you're looking for?

Please submit your question and answer.