Another important part of any WPF application is to define the Layout of the screen.
WPF introduces a number of Panels each are derived from abstract class Panel. You can also Derive Panel to define your custom Panel if you wish. We will look into how you can define your own CustomPanel later. Now lets discuss about all the basic Panels supported by WPF.
PANEL
Panel is the abstract class from which each and every panel is derived from. So each layout element that we will talk about is derived from the Panel class and has few properties which I should discuss before talking about Concrete objects.
1. Z-Index : It determines the index of the UIElement which overlapped with another element. ZIndex is an Attached property which determines the index in
layered elements. One with higher Zindex will show above the other.
2. InternalChildren : This is the basic UIElementCollection element which is exposed using Children property. When defining your custom Panel you can
use it to get the elements.
3. Background : This is also present for any panel element, which specifies the Background Color for the Panel.
Custom Panel
To create a custom Panel yourself, you need to override two methods:
MeasureOverride : This method is called whenever an element is added on the Panel. It takes the availableSize as input and returns the DesiredSize for the element passed. You need to calculate the Size so that it could be placed accordingly in desired size.
ArrangeOverride : This method is called to determine the arrangement of the Element. It will be called once for the whole panel, when Layout is created and the final desired size for the panel is returned from it. It will again be called when Layout is Updated.
You can try the MSDN Sample for more details of creating Custom Panel :
http://go.microsoft.com/fwlink/?LinkID=159979
GRID
Grid is the most basic layout panel which forms a graph in the whole frame. Grid forms a Table which you can address using Row and Column. You can specify the RowDefination and ColumnDefination for Rows and columns of the Grid. You can specify the height of a Row and Width of a Column easily using RowDefinations and ColumnDefinations.
Sizing of Rows and Columns :
As I already said, Height and Width of each Cell in a Grid can be specified using RowDefinations and ColumnDefinations, the sizing can be specified in more than one
way. The Sizing can be :
=> Auto : This is the default Sizing which is determined by the element you place within the Control.
=> * (Star) : When you use star it means the measurement will be done using ratio. 2* means double of 1*. So if you want to make two columns in 2:1 ratio you mention the width as 2* and 1*.
=> Absolute : You can also specify the absolute value of the height and width.
Means if you specify 100 as height it will take it accordingly.
From my own experience, it is better practice to use MinHeight and MaxWidth instead of Width and Height when you want your layout to be strict and doesnt depend on the child elements.
In the sample application, I have created a Grid with 3X3 matrix. You can use TextBoxes specified on the top to position the Box in Row and Columns Dynamically.
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Background="BurlyWood" x:Name="brdElement">
<TextBlock x:Name="tbElement" Text="Row 0, Column 0"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
This will place the Border in 0,0 column of the 3X3 Table.
STACKPANEL
The very next control that I must start with is a StackPanel. StackPanel is a container where all the child elements are placed in stacks, that means one after another, so that no one overlaps on one another.
Stackpanel places controls based on PositiveInfinity, which means the size that it can take in positive direction. The main property of StackPanel is its Orientation. There are two Orientation supported.
Vertical : This is the default orientation for StackPanel where the child items are places vertically one after another from top to bottom.
Horizontal : Here the items are placed from left to Right one after another.
<StackPanel x:Name="spMain" Orientation="Horizontal">
<Border Background="Brown" Padding="50"></Border>
<Border Background="Green" Padding="50" />
</StackPanel>
WRAPPANEL:
WrapPanel is almost similar to StackPanel, but it produces a newLine when it reaches the edge of the panel. Thus WrapPanel has additional flexibility to wrap elements when space matters. Another difference is, WrapPanel always determines the size based on the size of the content rather than PositiveInfinity as of StackPanel.
So if you resized the window, the content will be automatically wrapped to the new line. WrapPanel also exposes Orientation Property as StackPanel.
<WrapPanel x:Name="wpMain" Grid.Row="1">
<Border Background="Brown" Padding="30"/>
<Border Background="Green" Padding="30" />
<Border Background="Brown" Padding="30" />
<Border Background="Green" Padding="30" />
</WrapPanel>
DOCKPANEL
DockPanel is the most widely used control to determine the layout of an application. It uses DockPanel.Dock attached property to determine the position of the element. The Dock element when Top or Bottom, will make the element appear Top or Bottom of each other, and when its Left and right it is left and right of each other.
In case of DockPanel, if the height and width of the element placed within it is not specified, it takes the size of the area it is provided with.
<DockPanel>
<Border Background="Aqua" DockPanel.Dock="Top">
<TextBlock Text="Dock:Top" />
</Border>
<Border Background="Red" DockPanel.Dock="Bottom">
<TextBlock Text="Dock:Bottom" />
</Border>
<Border Background="Orange" DockPanel.Dock="Left">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Left" />
</Border>
<Border Background="Blue" DockPanel.Dock="Left">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Left" />
</Border>
<Border Background="Aqua" DockPanel.Dock="Bottom">
<TextBlock Text="Dock:Top" />
</Border>
<Border Background="Aquamarine" DockPanel.Dock="Top">
<TextBlock Text="Dock:Top" />
</Border>
<Border Background="BurlyWood" DockPanel.Dock="Right">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Right" />
</Border>
<Border Background="Coral" DockPanel.Dock="Right">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Right" />
</Border>
<Border Background="Cornsilk" >
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Remaining Fill" />
</Border>
</DockPanel>
So, you can see you need to explicitly mention Dock property of each individual element to make it appear accordingly. The sequence of declaration is also play a vital role in case of DockPanels. If you mention two elements in a row with DockPanel.Dock=Top, that means the two individual elements will appear as Vertically Oriented StackPanel.
A property called LastChildFill makes the remaining space to be filled with undocked element. You can see in the figure the last element is filled with the entire space left. You can make it false if you dont need it.
If you want to do this with code, you need to use DockPanel.SetDock.
VirtualizingStackPanel:
WPF introduces a special type of panel which Virtualize its content when the content is bound to Data elements. The word virtualize means the content will only be produced when the element is visible to the screen. Thus the performance will be improved a lot.
<ListBox x:Name="lstElements" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ItemsSource="{Binding}"/>
Now from code if you write :
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<int> obs = new ObservableCollection<int>();
Random rnd = new Random(1000);
for (int i = 0; i < 100000; i++)
obs.Add(rnd.Next());
this.lstElements.DataContext = obs;
}
This will produce 100000 elements to be added over the ListBox. If you use VirtualizingStackPanel.IsVirtualizing=True, the content will appear instantly, as it doesnt require to produce all the ListBoxItem elements from the first time. The application will hang if you make IsVirtualizing=false as creating 100000 ListboxItem elements takes a lot of time.
VirtualizationMode can be of two types:
Standard: It means the Item will be created when the ScrollViewer is scrolled.
Recycling : It means the item will be replaced with Data when ScrollViewer is scrolled.
CANVAS
Canvas is a special Layout panel which position elements with absolute position means using x and y co-ordinates. When used within a Canvas, elements are not restricted to anything. It can be overlapped when the position intersects with other controls. Each element is drawn based on the sequence of its declaration. You can easily use Panel.ZIndex to make this declaration unspecific.
Canvas doesn't employ any restriction to its elements. So the width and height of individual elements is very necessary to be specified. You can use Canvas.Left, Canvas.Right, Canvas.Top and Canvas.Bottom to specify the co-ordinates. The only thing you need to remember, that Canvas.Left and Canvas.Right is same, but it determines the start point of co-ordinate system from the extreme left or extreme right.
<Canvas>
<Border Canvas.Top="20" Canvas.Left="25" Background="Bisque" Width="30"
Height="25" />
<Border Canvas.Top="20" Canvas.Right="25" Background="Green" Width="30"
Height="25" />
<Border Canvas.Bottom="20" Canvas.Right="25" Background="Black"
Width="30" Height="25" />
<Border Canvas.Bottom="20" Canvas.Left="25" Background="IndianRed"
Width="30" Height="25" />
<Ellipse Fill="DarkGray" Canvas.Left="100" Canvas.Top="130" Width="100"
Height="80"></Ellipse>
<Ellipse Fill="DarkCyan" Canvas.Left="100" Canvas.Top="80" Width="100"
Height="80"></Ellipse>
<Ellipse Fill="DarkSalmon" Canvas.Left="140" Canvas.Top="100"
Width="100" Height="80" />
</Canvas>
Here you can see the Border elements even though placed in the same are, the Canvas properties changes the Co-ordinate system and thus places on the four sides of the window.
The ellipses are Overlapped between one another in the same sequence as it is specified.
UNIFORMGRID
UniformGrid is a special control which adjusts its elements uniformly. If you want your Rows and Columns to be uniform in your grid, you can use UniformGrid instead of Normal Grid declaration.
In case of UniformGrid, the child elements will always be of same size.
<UniformGrid Columns="2" Rows="3">
<Border Background="Red" />
<Border Background="Green" />
<Border Background="Blue" />
<Border Background="Yellow" />
<Border Background="DarkGoldenrod" />
<Border Background="DarkKhaki" />
</UniformGrid>
So its 3X2 Grid and all elements are placed according to the sequence it is specified.
ScrollViewer
It is often happens that the elements goes outside of the Display area. In that case, ScrollViewer places an Automatic Scrollbars which can be used to view the area outside the bounds. ScrollViewer encapsulates the ScrollBars within it and displays it whenever it is required. As the ScrollViewer implements IScrollInfo is the main scrolling area inside the scrollviewer. ScrollViewer also responds to mouse and keyboard commands.
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is enabled when it is necessary. Resize the window, making it larger and smaller.</TextBlock>
<Rectangle Fill="Honeydew" Width="500"
Height="500"></Rectangle>
</StackPanel>
</ScrollViewer>
The CanContentScroll property of a ScrollViewer determines whether the elements would be scrollable or not. HorizontallScrollBarVisibility and ticalScrollBarVisibility makes the scrollbar appear accordingly. The default behaviour is Auto which means the scrollbar will appear only when it is required.
GroupBox
GroupBox allows to group content with a custom header in it. This is same as GroupBox we know in windows. The Header property takes the text element which is placed as header of the GroupBox. As GroupBox is a ContentControl, it can have only a single element in the body. So you need to use Panels to add children within it.
<GroupBox Header="This goes to Header" Margin="50">
<StackPanel>
<Button Content="First Element"/>
<Button Content="Second Element" />
</StackPanel>
</GroupBox>
Expander
Expander is same as groupbox but has extra facility to expand content. It is also derived form HeaderedContentControl and thus has one single content within it. The IsExpanded property determines if the panel is expanded or not.
ExpandDirection is used to make the content expanded behaviour. It has four Directions, Down, Up, Right and Left. You can use them to change the Expanded direction of the content.
<Expander Header="This goes to Header" Margin="50" IsExpanded="True"
ExpandDirection="Down">
<StackPanel>
<Button Content="First Element"/>
<Button Content="Second Element" />
</StackPanel>
</Expander>
ViewBox
ViewBox is a special WPF control which stretch or scale the contents of the elements.
This comes very handy to allow anchoring of the elements, as in case of ViewBox the controls will never change its position, rather the whole content will be stretched or shrinked.
The Stretch property of ViewBox can have four properties:
1. Fill : Fills the content and also makes the Aspect Ratio intact.
2. None: Stretch behaviour will not be set.
3. UniformToFill: Fills the element uniformly, and changes the Aspect Ratio.
4. Uniform : Uniformly enlarges the content.
The stretchDirection can be specified as Both, DownOnly and UpOnly.
<Viewbox Stretch="None" StretchDirection="Both" >
<Grid>
<TextBox Text="This is a content" FontWeight="Bold" FontSize="30"/>
</Grid>
</Viewbox>
Popup
Popup is a special control that is used to create floating window over the actual window. Popup is a control that is rendered always on Top of the window. Popup is used to display quick elements whenever it is needed without altering the whole window.
A Popup control can be positioned using properties called PlacementTarget, PlacementRectangle, Placement, HorizontalOffset, VerticalOffset etc. A popup is a window outside the bounds of the existing WPF window, and thus it can be moved outside the whole content area of the XAML. WPF popup control supports few animation likeFade, Scroll, Slide etc which you can apply to it using PopupAnimation property. A WPF Popup supports transparency when AllowsTransparency is set to
true.
<ToggleButton IsChecked="{Binding ElementName=pup, Path=IsOpen}"
Content="Open Popup" Margin="100" />
<Popup Placement="Bottom" AllowsTransparency="True"
PopupAnimation="Fade" x:Name="pup" VerticalOffset="-100">
<StackPanel>
<TextBlock Name="McTextBlock" Background="Black"
Foreground="White" >
This is popup text
</TextBlock>
<Button Content="This is button on a Pupup" />
</StackPanel>
</Popup>
Here the Popup will be displayed when the ToggleButton is clicked as IsChecked is bound to IsOpen of Popup. When IsOpen is true, the popup will be displayed.
InkCanvas
Another most powerful control which is introduced with WPF is InkCanvas. This control allows you to draw over the Canvas and ultimately get the image bytes saved. It is very powerful as you can easily get the strokes drawn over the canvas as Objects.
Just place an InkCanvas on the WPF Window and you will find that you can draw over the screen. The EditingMode gives you few editing mode for the InkCanvas. We will discuss with this control later in another article.
<StackPanel>
<InkCanvas Height="200" x:Name="icBox">
</InkCanvas>
<RadioButton GroupName="mode" Checked="Pen_Checked" Content="Pen"/>
<RadioButton GroupName="mode" Checked="Erase_Checked"
Content="Eraser By Point" />
<RadioButton GroupName="mode" Checked="EraseByStroke_Checked"
Content="Eraser By Stroke" />
</StackPanel>
WPF introduces a number of Panels each are derived from abstract class Panel. You can also Derive Panel to define your custom Panel if you wish. We will look into how you can define your own CustomPanel later. Now lets discuss about all the basic Panels supported by WPF.
PANEL
Panel is the abstract class from which each and every panel is derived from. So each layout element that we will talk about is derived from the Panel class and has few properties which I should discuss before talking about Concrete objects.
1. Z-Index : It determines the index of the UIElement which overlapped with another element. ZIndex is an Attached property which determines the index in
layered elements. One with higher Zindex will show above the other.
2. InternalChildren : This is the basic UIElementCollection element which is exposed using Children property. When defining your custom Panel you can
use it to get the elements.
3. Background : This is also present for any panel element, which specifies the Background Color for the Panel.
Custom Panel
To create a custom Panel yourself, you need to override two methods:
MeasureOverride : This method is called whenever an element is added on the Panel. It takes the availableSize as input and returns the DesiredSize for the element passed. You need to calculate the Size so that it could be placed accordingly in desired size.
ArrangeOverride : This method is called to determine the arrangement of the Element. It will be called once for the whole panel, when Layout is created and the final desired size for the panel is returned from it. It will again be called when Layout is Updated.
You can try the MSDN Sample for more details of creating Custom Panel :
http://go.microsoft.com/fwlink/?LinkID=159979
GRID
Grid is the most basic layout panel which forms a graph in the whole frame. Grid forms a Table which you can address using Row and Column. You can specify the RowDefination and ColumnDefination for Rows and columns of the Grid. You can specify the height of a Row and Width of a Column easily using RowDefinations and ColumnDefinations.
Sizing of Rows and Columns :
As I already said, Height and Width of each Cell in a Grid can be specified using RowDefinations and ColumnDefinations, the sizing can be specified in more than one
way. The Sizing can be :
=> Auto : This is the default Sizing which is determined by the element you place within the Control.
=> * (Star) : When you use star it means the measurement will be done using ratio. 2* means double of 1*. So if you want to make two columns in 2:1 ratio you mention the width as 2* and 1*.
=> Absolute : You can also specify the absolute value of the height and width.
Means if you specify 100 as height it will take it accordingly.
From my own experience, it is better practice to use MinHeight and MaxWidth instead of Width and Height when you want your layout to be strict and doesnt depend on the child elements.
In the sample application, I have created a Grid with 3X3 matrix. You can use TextBoxes specified on the top to position the Box in Row and Columns Dynamically.
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border Background="BurlyWood" x:Name="brdElement">
<TextBlock x:Name="tbElement" Text="Row 0, Column 0"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
This will place the Border in 0,0 column of the 3X3 Table.
STACKPANEL
The very next control that I must start with is a StackPanel. StackPanel is a container where all the child elements are placed in stacks, that means one after another, so that no one overlaps on one another.
Stackpanel places controls based on PositiveInfinity, which means the size that it can take in positive direction. The main property of StackPanel is its Orientation. There are two Orientation supported.
Vertical : This is the default orientation for StackPanel where the child items are places vertically one after another from top to bottom.
Horizontal : Here the items are placed from left to Right one after another.
<StackPanel x:Name="spMain" Orientation="Horizontal">
<Border Background="Brown" Padding="50"></Border>
<Border Background="Green" Padding="50" />
</StackPanel>
WRAPPANEL:
WrapPanel is almost similar to StackPanel, but it produces a newLine when it reaches the edge of the panel. Thus WrapPanel has additional flexibility to wrap elements when space matters. Another difference is, WrapPanel always determines the size based on the size of the content rather than PositiveInfinity as of StackPanel.
So if you resized the window, the content will be automatically wrapped to the new line. WrapPanel also exposes Orientation Property as StackPanel.
<WrapPanel x:Name="wpMain" Grid.Row="1">
<Border Background="Brown" Padding="30"/>
<Border Background="Green" Padding="30" />
<Border Background="Brown" Padding="30" />
<Border Background="Green" Padding="30" />
</WrapPanel>
DOCKPANEL
DockPanel is the most widely used control to determine the layout of an application. It uses DockPanel.Dock attached property to determine the position of the element. The Dock element when Top or Bottom, will make the element appear Top or Bottom of each other, and when its Left and right it is left and right of each other.
In case of DockPanel, if the height and width of the element placed within it is not specified, it takes the size of the area it is provided with.
<DockPanel>
<Border Background="Aqua" DockPanel.Dock="Top">
<TextBlock Text="Dock:Top" />
</Border>
<Border Background="Red" DockPanel.Dock="Bottom">
<TextBlock Text="Dock:Bottom" />
</Border>
<Border Background="Orange" DockPanel.Dock="Left">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Left" />
</Border>
<Border Background="Blue" DockPanel.Dock="Left">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Left" />
</Border>
<Border Background="Aqua" DockPanel.Dock="Bottom">
<TextBlock Text="Dock:Top" />
</Border>
<Border Background="Aquamarine" DockPanel.Dock="Top">
<TextBlock Text="Dock:Top" />
</Border>
<Border Background="BurlyWood" DockPanel.Dock="Right">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Right" />
</Border>
<Border Background="Coral" DockPanel.Dock="Right">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Dock:Right" />
</Border>
<Border Background="Cornsilk" >
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center" Text="Remaining Fill" />
</Border>
</DockPanel>
So, you can see you need to explicitly mention Dock property of each individual element to make it appear accordingly. The sequence of declaration is also play a vital role in case of DockPanels. If you mention two elements in a row with DockPanel.Dock=Top, that means the two individual elements will appear as Vertically Oriented StackPanel.
A property called LastChildFill makes the remaining space to be filled with undocked element. You can see in the figure the last element is filled with the entire space left. You can make it false if you dont need it.
If you want to do this with code, you need to use DockPanel.SetDock.
VirtualizingStackPanel:
WPF introduces a special type of panel which Virtualize its content when the content is bound to Data elements. The word virtualize means the content will only be produced when the element is visible to the screen. Thus the performance will be improved a lot.
<ListBox x:Name="lstElements" VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ItemsSource="{Binding}"/>
Now from code if you write :
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ObservableCollection<int> obs = new ObservableCollection<int>();
Random rnd = new Random(1000);
for (int i = 0; i < 100000; i++)
obs.Add(rnd.Next());
this.lstElements.DataContext = obs;
}
This will produce 100000 elements to be added over the ListBox. If you use VirtualizingStackPanel.IsVirtualizing=True, the content will appear instantly, as it doesnt require to produce all the ListBoxItem elements from the first time. The application will hang if you make IsVirtualizing=false as creating 100000 ListboxItem elements takes a lot of time.
VirtualizationMode can be of two types:
Standard: It means the Item will be created when the ScrollViewer is scrolled.
Recycling : It means the item will be replaced with Data when ScrollViewer is scrolled.
CANVAS
Canvas is a special Layout panel which position elements with absolute position means using x and y co-ordinates. When used within a Canvas, elements are not restricted to anything. It can be overlapped when the position intersects with other controls. Each element is drawn based on the sequence of its declaration. You can easily use Panel.ZIndex to make this declaration unspecific.
Canvas doesn't employ any restriction to its elements. So the width and height of individual elements is very necessary to be specified. You can use Canvas.Left, Canvas.Right, Canvas.Top and Canvas.Bottom to specify the co-ordinates. The only thing you need to remember, that Canvas.Left and Canvas.Right is same, but it determines the start point of co-ordinate system from the extreme left or extreme right.
<Canvas>
<Border Canvas.Top="20" Canvas.Left="25" Background="Bisque" Width="30"
Height="25" />
<Border Canvas.Top="20" Canvas.Right="25" Background="Green" Width="30"
Height="25" />
<Border Canvas.Bottom="20" Canvas.Right="25" Background="Black"
Width="30" Height="25" />
<Border Canvas.Bottom="20" Canvas.Left="25" Background="IndianRed"
Width="30" Height="25" />
<Ellipse Fill="DarkGray" Canvas.Left="100" Canvas.Top="130" Width="100"
Height="80"></Ellipse>
<Ellipse Fill="DarkCyan" Canvas.Left="100" Canvas.Top="80" Width="100"
Height="80"></Ellipse>
<Ellipse Fill="DarkSalmon" Canvas.Left="140" Canvas.Top="100"
Width="100" Height="80" />
</Canvas>
Here you can see the Border elements even though placed in the same are, the Canvas properties changes the Co-ordinate system and thus places on the four sides of the window.
The ellipses are Overlapped between one another in the same sequence as it is specified.
UNIFORMGRID
UniformGrid is a special control which adjusts its elements uniformly. If you want your Rows and Columns to be uniform in your grid, you can use UniformGrid instead of Normal Grid declaration.
In case of UniformGrid, the child elements will always be of same size.
<UniformGrid Columns="2" Rows="3">
<Border Background="Red" />
<Border Background="Green" />
<Border Background="Blue" />
<Border Background="Yellow" />
<Border Background="DarkGoldenrod" />
<Border Background="DarkKhaki" />
</UniformGrid>
So its 3X2 Grid and all elements are placed according to the sequence it is specified.
ScrollViewer
It is often happens that the elements goes outside of the Display area. In that case, ScrollViewer places an Automatic Scrollbars which can be used to view the area outside the bounds. ScrollViewer encapsulates the ScrollBars within it and displays it whenever it is required. As the ScrollViewer implements IScrollInfo is the main scrolling area inside the scrollviewer. ScrollViewer also responds to mouse and keyboard commands.
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock TextWrapping="Wrap" Margin="0,0,0,20">Scrolling is enabled when it is necessary. Resize the window, making it larger and smaller.</TextBlock>
<Rectangle Fill="Honeydew" Width="500"
Height="500"></Rectangle>
</StackPanel>
</ScrollViewer>
The CanContentScroll property of a ScrollViewer determines whether the elements would be scrollable or not. HorizontallScrollBarVisibility and ticalScrollBarVisibility makes the scrollbar appear accordingly. The default behaviour is Auto which means the scrollbar will appear only when it is required.
GroupBox
GroupBox allows to group content with a custom header in it. This is same as GroupBox we know in windows. The Header property takes the text element which is placed as header of the GroupBox. As GroupBox is a ContentControl, it can have only a single element in the body. So you need to use Panels to add children within it.
<GroupBox Header="This goes to Header" Margin="50">
<StackPanel>
<Button Content="First Element"/>
<Button Content="Second Element" />
</StackPanel>
</GroupBox>
Expander
Expander is same as groupbox but has extra facility to expand content. It is also derived form HeaderedContentControl and thus has one single content within it. The IsExpanded property determines if the panel is expanded or not.
ExpandDirection is used to make the content expanded behaviour. It has four Directions, Down, Up, Right and Left. You can use them to change the Expanded direction of the content.
<Expander Header="This goes to Header" Margin="50" IsExpanded="True"
ExpandDirection="Down">
<StackPanel>
<Button Content="First Element"/>
<Button Content="Second Element" />
</StackPanel>
</Expander>
ViewBox
ViewBox is a special WPF control which stretch or scale the contents of the elements.
This comes very handy to allow anchoring of the elements, as in case of ViewBox the controls will never change its position, rather the whole content will be stretched or shrinked.
The Stretch property of ViewBox can have four properties:
1. Fill : Fills the content and also makes the Aspect Ratio intact.
2. None: Stretch behaviour will not be set.
3. UniformToFill: Fills the element uniformly, and changes the Aspect Ratio.
4. Uniform : Uniformly enlarges the content.
The stretchDirection can be specified as Both, DownOnly and UpOnly.
<Viewbox Stretch="None" StretchDirection="Both" >
<Grid>
<TextBox Text="This is a content" FontWeight="Bold" FontSize="30"/>
</Grid>
</Viewbox>
Popup
Popup is a special control that is used to create floating window over the actual window. Popup is a control that is rendered always on Top of the window. Popup is used to display quick elements whenever it is needed without altering the whole window.
A Popup control can be positioned using properties called PlacementTarget, PlacementRectangle, Placement, HorizontalOffset, VerticalOffset etc. A popup is a window outside the bounds of the existing WPF window, and thus it can be moved outside the whole content area of the XAML. WPF popup control supports few animation likeFade, Scroll, Slide etc which you can apply to it using PopupAnimation property. A WPF Popup supports transparency when AllowsTransparency is set to
true.
<ToggleButton IsChecked="{Binding ElementName=pup, Path=IsOpen}"
Content="Open Popup" Margin="100" />
<Popup Placement="Bottom" AllowsTransparency="True"
PopupAnimation="Fade" x:Name="pup" VerticalOffset="-100">
<StackPanel>
<TextBlock Name="McTextBlock" Background="Black"
Foreground="White" >
This is popup text
</TextBlock>
<Button Content="This is button on a Pupup" />
</StackPanel>
</Popup>
Here the Popup will be displayed when the ToggleButton is clicked as IsChecked is bound to IsOpen of Popup. When IsOpen is true, the popup will be displayed.
InkCanvas
Another most powerful control which is introduced with WPF is InkCanvas. This control allows you to draw over the Canvas and ultimately get the image bytes saved. It is very powerful as you can easily get the strokes drawn over the canvas as Objects.
Just place an InkCanvas on the WPF Window and you will find that you can draw over the screen. The EditingMode gives you few editing mode for the InkCanvas. We will discuss with this control later in another article.
<StackPanel>
<InkCanvas Height="200" x:Name="icBox">
</InkCanvas>
<RadioButton GroupName="mode" Checked="Pen_Checked" Content="Pen"/>
<RadioButton GroupName="mode" Checked="Erase_Checked"
Content="Eraser By Point" />
<RadioButton GroupName="mode" Checked="EraseByStroke_Checked"
Content="Eraser By Stroke" />
</StackPanel>












No comments:
Post a Comment