1
2
Layout is a concept in WPF that describes the process of arranging and positioning elements onscreen. The WPF layout system controls three different properties in regards to the positioning of a control’s child elements. Each layout panel controls alignment, margins, and padding. These properties are manipulated to produce the desired look and feel of an application or one of its components. Alignment— This describes a child element’s position in relation to its parent element. For example, a button can be aligned to the right, center, or left of a container. Margin— This describes the amount of space around the perimeter of a control. Margin can be thought of as padding around the outside of a control. Padding— This describes the amount of space between the parent element’s bounding border and each child element. WPF provides a set of layout containers for use in WPF applications. These containers determine the position, size, and arrangement of the elements they hold. Layout panels automatically manage the position and placement of the child elements they contain relative to their position in the panel. Layout panels can be implemented implicitly or explicitly. Implicit means that a layout panel will resize automatically in relation to its parent container. This is useful when the UI layout must accommodate varying resolutions and screen sizes. “Explicitly” means that a layout panel’s width and height are fixed to set values so that they maintain their size and appearance when a window is resized. Layout panels should be used judiciously and the selection of a panel should be appropriate for the UI functionality required. At runtime, the position of each child control within a layout panel is calculated as each panel is resized. The complexity of the calculation increases in relation to the quantity of child objects onscreen. As such, if a UI element can be positioned correctly using a simple canvas panel, you will find that it yields better runtime performance than a complex grid panel.
3
Panel : Panel elements are components that control the rendering of elements—their size and dimensions, their position, and the arrangement of their child content. A Panel contains a collection of UIElement objects. Adding a UIElement child to a Panel implicitly adds it to the UIElementCollection for the Panel element. WPF provides a wide variety of derived Panel layouts, providing many complex layouts. WPF layouts are extensible as it allows to a create custom layout elements that are derived from Panel. To implement custom Panel behaviors, use the MeasureOverride and ArrangeOverride methods. Each method returns the Size data that is necessary to position and render child elements. Panel elements do not receive mouse or stylus events if a Background is not defined. Panel elements do not receive focus by default. To compel a panel element to receive focus, set the Focusable property to true. The standard layouts in WPF are derivative of Panel class as listed below: •Canvas, StackPanel ,WrapPanel , DockPanel and Grid. In next slide we will learn about the standard layouts in WPF.
A layout in WPF is the bounding box that surrounds all elements. All the layouts in WPF are derived from base class Panel. More specifically, layout describes the process of measuring and arranging the members of a Panel element's Children collection. The WPF includes a comprehensive suite of derived panel implementations that enable many complex layouts. These derived classes expose properties and methods that enable most standard user interface (UI) scenarios. Panel is the base class for all elements that provide layout support in Windows Presentation Foundation (WPF). Derived Panel elements are used to position and arrange elements in Extensible Application Markup Language (XAML) and code. StackPanel : It places elements in a horizontal or vertical stack. This layout container is typically used for small sections of a larger, more complex window. A StackPanel enables you to "stack" elements in an assigned direction. The default stack direction is vertical. The Orientation property can be used to control content flow. DockPanel : DockPanel enables easy docking of elements to an entire side of the panel, stretching it to fill the entire width or height. It also enables a single element to fill all the remaining space unused by the docked elements. WrapPanel : WrapPanel is similar to StackPanel. But in addition to stacking its child elements, it wraps them to additional rows or columns when there’s not enough space for a single stack. This is useful for displaying an indeterminate number of items with a more interesting layout than a simple list, much like Windows Explorer does. Canvas: Canvas is the most basic panel. Canvas only supports the “classic” notion of positioning elements with explicit coordinates, although at least those coordinates are device-independent pixels, unlike older UI systems. Canvas also enables you to specify coordinates relative to any corner of it; not just the top-left corner. You can position elements in a Canvas using its attached properties: Left, Top, Right, and Bottom. By setting a value for Left or Right, you’re stating that the closest edge of the element should remain a fixed distance from the left or right edge of the Canvas. And the same goes for setting a value for Top or Bottom. In essence, you choose the corner in which to “dock” each element, and the attached property values serve as margins (to which the element’s own Margin values are added). If an element doesn’t use any of these attached properties (leaving them with their default value of Double.NaN), it is placed in the top-left corner of the Canvas (the equivalent of setting Left and Top to 0). Example <Canvas> <Button Background=”Red”>Left=0, Top=0</Button> <Button Canvas.Left=”18” Canvas.Top=”18” Background=”Orange”>Left=18, Top=18</Button> <Button Canvas.Right=”18” Canvas.Bottom=”18” Background=”Yellow”>Right=18, Bottom=18</Button> <Button Canvas.Right=”0” Canvas.Bottom=”0” Background=”Lime”>Right=0, Bottom=0</Button> <Button Canvas.Right=”0” Canvas.Top=”0” Background=”Aqua”>Right=0, Top=0</Button> <Button Canvas.Left=”0” Canvas.Bottom=”0” Background=”Magenta”>Left=0, Bottom=0</Button> </Canvas>
5
Grid : Grid is the most versatile panel. It enables you to arrange its children in a multi row and multicolumn fashion. Thus the Grid layout arranges the elements in tabular form.
Grid layout consists of two distinct phases: (1) defining the rows and columns, and (2) assigning the children to slots. The columns in a Grid are defined using the ColumnDefinition element. To define rows RowDefinition element is used.
6
StackPanel StackPanel stacks the elements either horizontally or vertically . StackPanel class belongs to the namespace System.Windows.Controls. StackPanel content can flow both vertically, which is the default setting, or horizontally. Though vertical orientation is the default, this can be changed using the Orientation property. Content is automatically stretched based on the orientation and this can be controlled by changing the HorizontalAlignment or VerticalAlignment properties. A StackPanel allows you to stack elements in a specified direction. By using properties that are defined on The slot for each child in StackPanel is given the entire width or height of the control (depending on its orientation), and StackPanel determines its preferred size according to the maximum size of its children. StackPanel attributes Orientation In horizontal orientation the Elements are stacked left to right, then wrap top to bottom. Vertical Orientation is like Windows Explorer’s List view: Elements are stacked top to bottom, then wrap left to right. Alignment A StackPanel with vertical orientation—the VerticalAlignment property has no effect because each element is given as much height as it needs and no more. However, the HorizontalAlignment is important. It determines where each element is placed in its row. The StackPanel also has its own HorizontalAlignment and VerticalAlignment properties. By default, both of these are set to Stretch, and so the StackPanel fills its container completely. Ordinarily, the default HorizontalAlignment is Left for a label and Stretch for a Button. That’s why every button takes the full column width. However, these details can be changed as shown in the example below: <StackPanel> <Label HorizontalAlignment="Center">A Button Stack</Label> <Button HorizontalAlignment="Left">Button 1</Button> <Button HorizontalAlignment="Right">Button 2</Button> <Button>Button 3</Button> <Button>Button 4</Button> </StackPanel> Margin The margin is the space between this element and other elements that will be adjacent when layout creates the user interface (UI). Setting Margins : When setting margins, set a single width for all sides, as obvious in the example below: <StackPanel Margin="3"> <Label Margin="3" HorizontalAlignment="Center"> A Button Stack</Label> <Button Margin=“5" HorizontalAlignment="Left">Left Button </Button> <Button Margin=“5" HorizontalAlignment="Right">Right Button </Button> <Button Margin=“5">Button 3</Button> <Button Margin=“5">Button 4</Button> </StackPanel> Or For setting margins, set a single width for all sides, as shown in the example below: <Button Margin=“3">Click Mw..!</Button> Alternatively, you can set different margins using top, left, bottom and right values as obvious in the example below <Button Margin="5,10,5,10">Calculate</Button> How does a StackPanel controls the size of the buttons placed on it ? • The minimum size - Each button will always be at least as large as the minimum size. • The maximum size -Each button will always be smaller than the maximum size ,unless the maximum size is incorrectly set to be smaller than the minimum size. • The content - If the content inside the button requires a larger than its width, the StackPanel will attempt to enlarge the button. • The size of the container - If the minimum width is larger than the width of the StackPanel, a portion of the button will be cut off. Otherwise, the button will not be allowed to grow wider than the StackPanel, even if it can’t fit all its text on the button surface. •The horizontal alignment - Because the button uses a HorizontalAlignment of Stretch (the default), the StackPanel will attempt to enlarge the button to fill the entire area of the StackPanel. The XAML markup on the presentation is as below: <StackPanel Orientation="Vertical"> <Label Margin="5" Background="Pink">Pink 1</Label> <StackPanel Orientation="Vertical"> <Label HorizontalAlignment="Center" Background="Pink">(Center)Pink 2</Label> <Label HorizontalAlignment="Right" Background="LightBlue">((Right)Blue 2</Label> <Label HorizontalAlignment="Left" Background="Yellow">(Left) Yellow 2</Label> <Label Background="Orange">(No Margin)Orange 2</Label> </StackPanel> <Label Margin="7" Background="LightBlue">(with Margin="7") Blue 1</Label> <Label Margin="7" Background="Yellow">(with Margin="7") Yellow 1</Label> <Label Margin="7" Background="Orange">(with Margin="7") Orange 1</Label> </StackPanel>
7
Example <StackPanel Orientation="Vertical"> <!-- Vertical is the default --> <Label Background="Pink">Pink 1</Label> <StackPanel Orientation="Vertical"> <Label Background="Pink">Pink 2</Label> <Label Background="LightBlue">Blue 2</Label> <Label Background="Yellow">Yellow 2</Label> <Label Background="Orange">Orange 2</Label> </StackPanel> <Label Background="LightBlue">Blue 1</Label> <Label Background="Yellow">Yellow 1</Label> <Label Background="Orange">Orange 1</Label> </StackPanel> In the first example above a nested StackPanel is created. The orientation property for both the StackPanel is set to Vertical. In the second example, the HorizontalAlignment is set for the inner nested panel buttons to centre and the Margin for the outer StackPanel buttons is set to 7. <StackPanel Orientation="Vertical"> <Label Margin="5" Background="Pink">Pink 1</Label> <StackPanel Orientation="Vertical"> <Label HorizontalAlignment="Center" Background="Pink">(Center)Pink 2</Label> <Label HorizontalAlignment="Right" Background="LightBlue">((Right)Blue 2</Label> <Label HorizontalAlignment="Left" Background="Yellow">(Left) Yellow 2</Label> <Label Background="Orange">(No Margin)Orange 2</Label> </StackPanel> <Label Margin="7" Background="LightBlue">(with Margin="7") Blue 1</Label> <Label Margin="7" Background="Yellow">(with Margin="7") Yellow 1</Label> <Label Margin="7" Background="Orange">(with Margin="7") Orange 1</Label> </StackPanel>
8
WrapPanel It arranges items in a line from left to right, until the border is hit, then wraps to the next line. The WrapPanel lays out controls in the available space, one line or column at a time. In WrapPanel items are stretched to fit their contents (text). If an item cannot fit entirely in the allotted space, the entire control is moved to the next line. Uses the available space and fits elements to it; and when it runs out of room, it wraps to the next line. his is useful for displaying an indeterminate number of items with a more interesting layout than a simple list, much like Windows Explorer does. Like StackPanel, WrapPanel has no attached properties for controlling element positions. It defines three properties for controlling its behavior: a) Orientation— This is just like StackPanel’s property, except Horizontal is the default. Horizontal Orientation is like Windows Explorer’s Thumbnails view: Elements are stacked left to right, then wrap top to bottom. Vertical Orientation is like Windows Explorer’s List view: Elements are stacked top to bottom, then wrap left to right. b) ItemHeight— A uniform height for all child elements. The way each child fills that height depends on its own VerticalAlignment, Height, and so forth. Any elements taller than ItemHeight get clipped. c) ItemWidth— A uniform width for all child elements. The way each child fills that width depends on its own HorizontalAlignment, Width, and so forth. Any elements wider than ItemWidth get clipped. By default, ItemHeight and ItemWidth are not set. In this case, a WrapPanel with Vertical Orientation gives each column the width of its widest element, whereas a WrapPanel with Horizontal Orientation gives each row the height of its tallest element. By default, WrapPanel simply sizes all the children to fit their content ,although the width and height of the children can be fixed by using the ItemWidth and ItemHeight properties. WrapPanel is most commonly used as an items panel for an items control. For example, to support user selection of wrapping items (as in Windows Explorer), it makes sense to use a ListBox but replace its default panel with a WrapPanel as follows: <ListBox> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel/> </ItemsPanelTemplate> </ListBox.ItemsPanel> … </ListBox>
9
WrapPanel: A layout that arranges items in a line until the border is hit, then wraps to the next line. Example The first example creates a WrapPanel with vertical orientation while the second example show a WrapPanel with horizontal orientation . <Window x:Class="LayoutDemos.WrapPanelDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WrapPanelDemo" Height="310" Width="387"> <Border HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="2"> <WrapPanel Orientation=â&#x20AC;&#x153;Vertical" Height="240" Width="324"> <Label Height="125" Background="Pink" >Pink 1</Label> <Label Height="100" Background="LightGreen">Green 1</Label> <Label Height="125" Background="LightBlue">Blue 1</Label> <Label Height="50" Background="Yellow">Yellow 1</Label> <Label Height="150" Background="BurlyWood">BurlyWood 1</Label> <Label Height="100" Background="Pink">Pink 2</Label> <Label Height="150" Background="LightGreen">Green 2</Label> <Label Height="75" Background="LightBlue">Blue 2</Label> <Label Height="50" Background="Yellow">Yellow 2</Label> <Label Height="175" Background="BurlyWood" Width="56.39">BurlyWood 2</Label> </WrapPanel> </Border> </Window>
10
DockPanel The DockPanel is used to anchor elements to the edges of the container, and is a good choice to set up the overall structure of the application UI. Elements are docked using the DockPanel.Dock attached property. The order that elements are docked determines the layout. Here is an example that sets up a typical navigation system: a top menu, a bottom status bar, left and right navigational or informational panes, and a center area that fills the remaining space. How DockPanel organizes control on it? DockPanel enables easy docking of elements to an entire side of the panel, stretching it to fill the entire width or height. (This is unlike Canvas, which enables you to dock elements to a corner only.) It also enables a single element to fill all the remaining space unused by the docked elements. DockPanel has a Dock attached property (of type System.Windows.Controls.Dock), so children can control their docking with one of four possible values: Left (the default when Dock isn’t applied), Top, Right, and Bottom. Note that there is no Fill value for Dock. Instead, the last child added to a DockPanel fills the remaining space unless DockPanel’s LastChildFill property is set to false. With LastChildFill set to true (the default), the last child’s Dock setting is ignored. With it set to false, it can be docked in any direction (Left by default). DockPanel’s functionality is actually a superset of StackPanel’s functionality. With LastChildFill set to false, DockPanel behaves like a horizontal StackPanel when all children are docked to the left, and it behaves like a vertical StackPanel when all children are docked to the top. Example <DockPanel LastChildFill="True"> <Button DockPanel.Dock="Top">Button Anchored Top Region </Button> <Button DockPanel.Dock="Bottom">Button Anchored Bottom Region </Button> <Button DockPanel.Dock="Left">Button Anchored Left Region </Button> <Button DockPanel.Dock="Right">Button Anchored Right Region </Button> <Button>Central Remaining Space</Button> </DockPanel> This example anchors a Button at the Top, Botton, Left , Right and also sets the LastChildFill to true, which informs the DockPanel to give the remaining space to the last element DockPanel is useful for arranging the top-level UI in a Window or Page, where most docked elements are actually other panels containing the other UIElement. For example, applications typically dock a Menu on top/ Toolbar , perhaps a panel on the side, a StatusBar on the bottom, and then fill the remaining space with the main content. The order children are added to DockPanel matters because each child is given all the space remaining on the docking edge.
11
The example uses a DockPanel layout with the single button anchored at the top, left and right except the bottom and central region, that contain 2 buttons. <Window x:Class="LayoutDemos.DPDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="DPDemo" Height="300" Width="300â&#x20AC;&#x153;> <DockPanel> <Label DockPanel.Dock="Top" Height="100" Background="Beige">(At Top)</Label> <Label DockPanel.Dock="Left" Background="LightGreen">(At Left)</Label> <Label DockPanel.Dock="Right" Background="LightBlue">(At Right)</Label> <Label DockPanel.Dock="Bottom" Background="LightBlue">(LightBlue -At bottom)</Label> <Label DockPanel.Dock="Bottom" Height="50" Background="Yellow">(Yellow -At bottom)</Label> <Label Width="100" Background="Orange"> Orange 1</Label> <!-- default is to fill --> <Label Background="Bisque">Bisque</Label> </DockPanel> </Window>
12
Grid : A Grid is a layout arranges the elements in tabular form. That is in rows and columns like a table. Grid layout consists of two distinct phases: (1) defining the rows and columns, and (2) assigning the children to slots. The columns in a Grid are defined using the ColumnDefinition element. To define rows RowDefinition element is used. Example: <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Button Grid.Row='0' Grid.Column='0' >One</Button> <Button Grid.Row='0' Grid.Column='1' >Two</Button> <Button Grid.Row='1' Grid.Column='0' >Three</Button> <Button Grid.Row='1' Grid.Column='1' >Four</Button> </Grid> Important properties of Grid Column :A read-write value that indicates which column child content within a Grid should appear in. ColumnSpan :A read-write value that indicates the total number of columns that child content spans within a Grid. Row : A read-write value that indicates which row child content within a Grid should appear in. RowSpan :A read-write value that indicates the total number of rows that child content spans within a Grid. (Refer to next slide) ShowGridLines : A read-write value that indicates whether grid lines are visible within this Grid. (Refer to next slide). Sizing the Rows and Columns Unlike FrameworkElement’s Height and Width properties, RowDefinition’s and ColumnDefinition’s corresponding properties do not default to Auto (or Double.NaN). And unlike almost all other Height and Width properties in WPF, they are of type System.Windows.GridLength rather than double. This way, Grid can uniquely support three different types of RowDefinition and ColumnDefinition sizing: Absolute sizing— Setting Height or Width to a numeric value representing device independent pixels (like all other Heights and Widths in WPF). Unlike the other types of sizing, an absolute-sized row or column does not grow or shrink as the size of the Grid or size of the elements changes. Autosizing— Setting Height or Width to Auto, which gives child elements the space that they need and no more (like the default setting for other Heights and Widths in WPF). For a row, this is the height of the tallest element, and for a column, this is the width of the widest element. This is a better choice than absolute sizing whenever text is involved to be sure it doesn’t get cut off because of different font settings or localization. Proportional sizing (sometimes called star sizing)— Setting Height or Width to special syntax to divide available space into equal-sized regions or regions based on fixed ratios. A proportional-sized row or column grows and shrinks as the Grid is resized. Absolute and auto sizing are straightforward, but proportional sizing needs more explanation. It is done with star syntax, and works as follows: This value is expressed as * or 2* when you use Extensible Application Markup Language (XAML). In the first case, the row or column would receive one times the available space, while in the second case, the row or column would receive two times the available space, and so on. . When a row’s height or column’s width is set to *, it occupies all the remaining space. . When multiple rows or columns use *, the remaining space is divided equally between them. . Rows and columns can place a coefficient in front of the asterisk (like 2* or 5.5*) to take proportionately more space than other columns using the asterisk notation. A column with width 2* is always twice the width of a column with width * (which is shorthand for 1*) in the same Grid. A column with width 5.5* is always twice the width of a column with width 2.75* in the same Grid. The “remaining space” is the height or width of the Grid minus any rows or columns that use absolute or auto sizing. The default height and width for Grid rows and columns is *. That’s why the rows and columns are evenly distributed. Examples: For example, here’s how you set an absolute width of 80 device-independent units: <ColumnDefinition Width=“80"></ColumnDefinition> To use automatic sizing, use a value of Auto: <ColumnDefinition Width="Auto"></ColumnDefinition> Finally, to use proportional sizing, you use an asterisk (*): <ColumnDefinition Width="*"></ColumnDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="2*"></RowDefinition> Spanning Rows and Columns: For example, this button will take all the space that’s available in the first and second cell of the first row: <Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">Span Button</Button> And this button will stretch over four cells in total by spanning two columns and two rows: <Button Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2“>Span Button</Button> Example <Grid ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <TextBox Margin="10" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"> This is a test.</TextBox> <Button Margin="10,10,2,10" Padding="3" Grid.Row="1" Grid.Column="1">OK</Button> <Button Margin="2,10,10,10" Padding="3" Grid.Row="1" Grid.Column="2">Cancel</Button> </Grid>
13
For details on the above listed properties, please refer to the section - Important properties of Grid on the previous slide notes. Uniform Grid A Uniform grid maintains a series of grid cells of equal size. It is an interesting primitive panel (although its usefulness is questionable). It’s a simplified form of Grid, where all rows and columns are of size * and can’t be changed. Because of this, UniformGrid has two simple double properties to set the number of rows and columns rather than the more verbose RowDefinitions and ColumnDefinitions collections. It also has no attached properties; children are added in row-major order, and there can only be one child per cell. Furthermore, if you don’t explicitly set the number of rows and columns, UniformGrid automatically chooses suitable values. For example, it automatically places 2–4 elements in a 2x2 arrangement, 5–9 elements in a 3x3 arrangement, 10–16 elements in a 4x4 arrangement, and so on. The XAML markup on the presentation is as below: <UniformGrid> <Label Background="pink">Pink </Label> <Label Background="LightGreen">Green </Label> <Label Background="LightBlue">Blue </Label> <Label Background="Yellow">Yellow </Label> <Label Background="Orange">Orange </Label> <Label Background="BlanchedAlmond">BlanchedAlmond 2</Label> <Label Background="Azure">Azure</Label> <Label Background="Coral">Coral</Label> <Label Background="Crimson">Crimson</Label> </UniformGrid>
14
The code on the presentation defines a Grid with 2 columns and 4 rows. The text block in grid row 0 – and column 0 spans across 4 columns. The textbox place in column 1 and row 2 spans across 3 columns. The control are placed in the Grid cells using the Dependency property Grid.Row and Grid.Column. The XAML markup on the presentation is as below: <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Label Grid.Column="0" Grid.Row="0" Background="DarkSalmon" Grid.ColumnSpan="2">(Spanned across 2 columns)Red 1(0,0)</Label> <Label Grid.Column="0" Grid.Row="1" Background="LightBlue">LightBlue1 (0,1)</Label> <Label Grid.Column="1" Grid.Row="1" Background="BlanchedAlmond">BlanchedAlmond(1,1)</Label> <Label Grid.Column="0" Grid.Row="2" Grid.RowSpan="2" Background="LavenderBlush">(Spanned across 2 rows)Orange 1(0,2)</Label> <Label Grid.Column="1" Grid.Row="2" Background="HotPink">HotPink(1,2)</Label> <Label Grid.Column="1" Grid.Row="3" Background="Gold">Gold 1(1,3)</Label> </Grid> Summary: To organize controls on the WPF form, WPF ships with the following layout panels: •Canvas - for specific (X,Y) positioning •StackPanel - for stacking elements horizontally or vertically •WrapPanel - automatically handles wrapping elements to a new row as needed •DockPanel - for familiar docking functionality •Grid - for a row and column based layout •UniformGrid - a specialized form of Grid where all cells are the same size . Note :-In a situation where the standard layouts, do not suffice layout requirement, WPF allows customizing them.
15
16
17
18
19
20