Lesson 3 - Positioning in C# .NET WPF

C# .NET WPF Positioning in C# .NET WPF

In the previous lesson, The XAML language in C# .NET WPF, we went over the basics of XAML syntax in C# .NET WPF. In today's tutorial, we're going to learn all about positioning elements. This will be the last thing we go over before we start making more interesting applications.

Absolute and relative positions

In our hello-world app, our TextBlock had an absolute position. However, we also mentioned that WPF uses relative positions form elements, which we will be putting into use in this lesson. Let's take a look at the XAML code that was generated by the graphic designer when we added a TextBlock to the form.

<TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="91,42,0,0" Text="Hello world from forms!"/>

Absolute position

In WPF, we cannot place elements in an absolute position on the Grid directly, but we can do it using margins. In the example above, the graphic designer tracked our cursor while we dropped the TextBlock in the form and added the coordinates [91; 42] to a margin. In order to display it there, it had to place it in the top left of the layout. That's why the HorizontalAlig­nment="Left" and VerticalAlignmen­t="Top" attributes are set. Once it did that, it set the outer margins to 91 on the left and to 42 on the top via the Margin attribute. This way, it seems like the control is at [91; 42] when in fact the only reason it is at that spot is because there is a margin around it.

Perhaps the biggest drawback of using absolute positions is that the form will not respond to resizing or aspect ratio changes. This often happens nowadays because each device has a different screen size (cellphones, tablets, PCs). The another disadvantage is that if any control increases its size, we would have to move the other ones manually to make the form function properly. This may get very complicated in larger, more complex applications.

Although we have set the TextBlock in the middle of the form, when we resize the form, the application will end up looking like this:

Absolute position in WPF in C# .NET

Adding elements at fixed positions by clicking is a very simple and fast way to get things done, but it is also the fastest way to break our forms. Because of this, no one makes forms using fixed positions.

Relative position

Relative positions, unlike absolute positions, respect its surrounding controls in both the form and in the window. Now, let's edit the TextBlock XAML code so that it is centered in its parent element (the element we have nested it in). In our case, it will be in the middle of the Grid:

<TextBlock x:Name="textBlock" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" Text="Hello world from forms!"/>

Now, when we run the application and narrow the form vertically or expand it horizontally, the TextBlock remains centered. Needless to say that HorizontalAlignment sets the horizontal alignment and VerticalAlignment sets the vertical alignment of an element.

Relative position in WPF in C# .NET

Margin and Padding

Every element has a margin (the outer spacing beyond its border) and padding (the inner spacing before its border). Those of you familiar with HTML will feel at home here in the following section.

Margin a Padding in WPF in C# .NET

We can set different values for the margin and padding for each individual side of an element or set them all the same if we want to.

Now, let's delete the TextBlock from the form and insert a button using the following XAML code:

<Button Content="My button" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Margin="100,0,0,0" Padding="0,50,0,0"/>

Your form should now look like this:

Margin and padding of a button in an WPF application in C# .NET

We can see that even though the button is centered, its left margin is 100. As for the padding, the top is set to 50, which is significantly larger than the other ones.

We set margin and padding values in the following order: left, top, right, bottom (separated by commas). We are also able to specify a single value, which would set every side of the margin/padding to this value. Likewise, you could also specify two values, for horizontal and vertical spacing respectively.

Note that we have specified the width of the button in the example above using the Width attribute. Doing so is a common practice with buttons. If we didn't, the button wouldn't vary in width when the text length changed.

Device Independent Pixels

We specify sizes in DIP units. DIP stands for Device Independent Pixels. At 96 DPI, which is usually the default value when you install Windows, 1 DIP has a size of 1 physical pixel on the display. Users with large monitors, like me, usually have a higher DPI, Dots Per Inch, which changes the DIP to something like 1.25 of a physical display pixel. DPI is becoming more and more important because displays vary exponentially in size. There are 2k and 4k displays on the market, which have 4 times the resolution than those that are now considered standard. If we used ordinary pixels, our applications would be hard to see on such displays. With DIPs, it would look exactly the same because WPF would scale it automatically for us.

To set the DPI in Windows, you have to right-click on the desktop and select Personalize. Then select Display in the bottom left. There, you'll be able to change the overall size of fonts and items.

Changing DPI in Windows

You could set a higher DPI if you want and run your WPF application which will adapt to the newly set DPI (doing so will require you to log out and back in). A Windows Forms application would break or blur after such a change. GO ahead and try running some other applications, most of them won't work properly because they're still using old technology.

Positioning

Now, let's talk a little bit more about positioning controls. Edit the XAML code of the button to make it look like this:

<Button Content="My button" />

The button will stretch all over the Grid:

Button in the WPF application in C# .NET

This is the default behavior of controls. If an alignment is not specified, the Stretch value is assumed:

<Button Content="My button" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

We can set the following values to the HorizontalAlignment attribute:

  • Center - Aligns to center
  • Left - Aligns to left
  • Right - Aligns to right
  • Stretch - Stretches to fill the full width

As for VerticalAlignment, the values are similar, but instead of Left and Right, we set Top or Bottom values.

Try them all out so you can get a good feel of what relative positioning looks like. Once again, all controls are aligned to the element in which they're nested, wich is referred to as the parent element.

The height and width of elements

To set the width and height, we simply use the width and height attributes of an element. The value will be in DIP, and can also be set to the Auto value (which is default). The size is then determined based on the element contents, e.g. based off of the length of the text of the button title. You can also set a minimum or maximum size using the MinWidth, MinHeight, MaxWidth and MaxHeight attributes.

In the next lesson, Designing a calculator form in C# .NET WPF, we'll design a simple calculator form. You can download today's source code below as always.


 

Download

Downloaded 10x (55.53 kB)
Application includes source codes in language C#

 

 

Article has been written for you by David Capka
Avatar
Do you like this article?
3 votes
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn College The author learned IT at the Unicorn College - a prestigious college providing education on IT and economics.
Activities (8)

 

 

Comments

To maintain the quality of discussion, we only allow registered members to comment. Sign in. If you're new, Sign up, it's free.

No one has commented yet - be the first!