![]() |
Platforms, Frameworks & Libraries »
Windows Presentation Foundation »
XAML
Intermediate
WPF Windows: Code-based layout versus XAMLBy Dragos SbirleaDesigning your windows from code has suffered from the introduction of WPF and its XAML. Nevertheless it is possible not to use the descriptive language at all. Lets see how. |
C# 2.0, Windows, .NET 3.0, Visual Studio, WPF, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
With WPF, Microsoft introduced a new XML based descriptive language for use when designing interfaces called XAML. To help you use the new language, the company built in the VS forms designer support for XAML. Also, the Microsoft Expression Interactive Designer can be used to create such files.
But how about code-based layout? How did it change? Charles Petzold seems to think that it was left out from WPF layout improvements and designing code-only interfaces has now become harder than ever. Let's see if he is right.
Possible uses of this non-XAML approach in WPF are:
To understand the code, you should have a basic understanding of XAML and WPF layout using XAML. If you have experience dynamically creating .NET 2.0 forms using code, it's even better.
The code was written in VS 2005 with the June CTP of .NET 3.0 installed, it might not work with another CTP. It contains an example of code-only WPF window layout in a .NET 2.0 class library project, being used in a .NET 2.0 EXE application.
First of all, WPF made standard the resolution-independent way of designing Windows. In .NET 2.0 you had to manually position each control on the screen using co-ordinates and you could, with a certain amount of additional work, use resolution independent panels. In WPF, panels are the standard way of doing things so you should understand them well. A Form can hold only one child object, in its Content property. You could add a normal control there, but then you cannot add any other control on your form. That is why the Forms Content object should be a control Container, that is a control that can hold other controls. Containers designed and shipped in WPF for this purpose are: Canvas, Grid, StackPanel, and DockPanel. They provide different ways to arrange your controls on the form.
We will use a normal .NET 2.0 class project to create our WPF window in. Before we start, we should make sure we have all the prerequisites listed. Then, as we are not going to use a .NET 3.0 type of project, we must add references to the used assemblies. A reference is created by right-clicking on the References directory in your Solution Explorer. Then select Add Reference, then .NET. Add these DLLs: PresentationCore, PresentationFramework, and WindowsBase. They contain the objects we need from .NET 3.0. Now we can start coding in a new class file added to your project (Right click on your project in Solution Explorer, Add-> New->Class).
Window class. You want to add extra functionality to a blank WPF window. It is only natural to derive from it, like this:
public class StackPanelWindow:System.Windows.Window
StackPanel stack;
Button btn;
TextBox text;
Width and Height:
public StackPanelWindow()
{
this.Width = 300;
this.Height = 150;
Panel and set its Width and Height:
stack = new StackPanel();
stack.Width = this.Width;
stack.Height = this.Height;
Width, Height, other useful properties and events:
text = new TextBox();
text.Width = 100;
text.Height = 20;
text.Text = "some text";
stack.Children.Add(text);
Class.SetXXX(control_to_set,value);
CodeWindows.StackPanelWindow sw = new CodeWindows.StackPanelWindow();
sw.Visibility = System.Windows.Visibility.Visible;
The StackPanel allows you to add items to the Window just as you would add a plate on top of another plate, creating a stack of controls. Keep in mind that the last control added is the one you see at the bottom of the form, controls are added one under the other.
public class StackPanelWindow:System.Windows.Window
{
StackPanel stack;
Button btn;
TextBox text;
public StackPanelWindow()
{
this.Width = 300;
this.Height = 150;
//add the StackPanel
stack = new StackPanel();
stack.Width = this.Width;
stack.Height = this.Height;
this.Content = stack;
//add the text field
text = new TextBox();
text.Width = 100;
text.Height = 20;
text.Text = "some text";
stack.Children.Add(text);
//add the button
btn = new Button();
btn.IsEnabled = true;
btn.Width = 100;
btn.Height = 20;
btn.Content = "Say it!";
stack.Children.Add(btn);
}
We see that step 7 is missing; the controls are automatically positioned one under the previous one.
The DockPanel is a Panel in which each control is docked (that is, it sticks to a part of the Panel). The code is the same as the one with StackPanel but now we have to set the position of the controls manually by docking each one, like this:
DockPanel.SetDock(text, Dock.Top);
DockPanel.SetDock(btn, Dock.Bottom);
If we add a fifth control and so there is no side to dock it, it can be fitted in the center.
The Grid is like a table. It has rows and columns in which we can position controls. First we create the Grid structure - the rows and the columns:
//create two columns
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
//and two rows
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
Then to position each control in the Grid:
Grid.SetColumn(text, 0);
Grid.SetRow(text, 0);
The canvas was the standard .NET 2.0 way of doing things. It allows you to position each control on a canvas with precise co-ordinates, like this:
//inherit from the WPF Window object
public class CanvasWindow:System.Windows.Window
{
private Canvas canvas;
private TextBox text;
private Button btn;
public CanvasWindow()
{
//first, set the window properties
this.Width = 300;
this.Height = 150;
//add the canvas
canvas=new Canvas();
canvas.Width = this.Width;
canvas.Height = this.Height;
this.Content =canvas;
//add a text field
text = new TextBox();
text.Width = 100;
text.Height = 20;
text.Margin = new System.Windows.Thickness(10,10,10,10);
text.Text = "some text";
text.KeyDown += new System.Windows.Input.KeyEventHandler(text_KeyDown);
canvas.Children.Add(text);
//add a button
btn = new Button();
btn.IsEnabled = true;
btn.Width = 100;
btn.Height = 20;
btn.Content = "Say it!";
btn.Margin = new System.Windows.Thickness(110, 10, 10, 10);
btn.Click += new System.Windows.RoutedEventHandler(btn_Click);
canvas.Children.Add(btn);
}
The positioning was made by this line:
Control.Margin = new System.Windows.Thickness(10,10,10,10);
which is a general way to make sure your object is where it should be. If you want to use another approach, particular to the Canvas object, use:
Canvas.SetLeft( control_in_canvas , value );
and
Canvas.SetTop( control_in_canvas , value );
Note that layout created using the Canvas is not resolution-independent, as all the properties are in pixels. It is not recommended to use it if you do not need it.
For mode complex design, the panels should be used one in another. An example is: use a Stackpanel in a DockPanel to have several elements on the side of the DockPanel.
| You must Sign In to use this message board. | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 12 Aug 2006 Editor: Deeksha Shenoy |
Copyright 2006 by Dragos Sbirlea Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |