Off the Ridge Code Newsletter

Search

All posts in "WPF"

WPF – Part: 2

Published December 4, 2013 in WPF - 0Comments

WPF overview tutorial Part: 2 – Part 1 is here.

Let’s take a look at WPF from 10,000 foot view:

Direct X – used to render the actual pixels onto the screen.

Composition Engine – (Media Integration Layer) – It’s a native component written in unmanaged code that resides in milcore.dll and is responsible for providing support 2D and 3D imaging. It interfaces directly with Direct X. It’s written in unmanaged code for a simple reason: Direct X uses COM Interfaces to communicate with the outside world and these calls do not come very cheap in the managed world of interop calls.

Presentation Core – exposes rendering services of the Composition Engine – essentially managed wrapper for the Composition Engine.

Presentation Framework – provides concepts such as: Control, Layout, command handling, data binding, etc.

XAML or Extensible application markup language.

I’ve said it again, and I’ll say it again: WPF doesn’t need XML and XML doesn’t need WPF. It’s simply a language for building .NET objects and XAML user interfaces are built as trees of objects.

Let’s take a look at a simple button:

[[code style="color: black; word-wrap: normal;"]]czo1NTk6XCIxOiAgJmx0O1BhZ2UgIDxiciAvPjI6ICAgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwe1smKiZdfTA2L3hhbWwvcHJlc2VudGF0aW9uXCIgIDxiciAvPjM6ICAgeG1sbnM6eD1cImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZntbJiomXX14LzIwMDYveGFtbFwiJmd0OyAgPGJyIC8+NDogICAmbHQ7R3JpZCBIb3Jpem9udGFsQWxpZ25tZW50PVwiQ2VudGVyXCIgVmVydGljYWxBe1smKiZdfWxpZ25tZW50PVwiQ2VudGVyXCImZ3Q7ICAgPGJyIC8+NTogICAgICZsdDtCdXR0b24geDpOYW1lPVwiWEFNTEJ1dHRvblRlc3RcIiAgIDxie1smKiZdfXIgLz42OiAgICAgICAgICAgICAgICAgICAgIEZvbnRGYW1pbHk9XCJWZXJhbmRhXCIgIDxiciAvPjc6ICAgICAgICAgICAgICAgICAgIHtbJiomXX0gIEZvbnRTaXplPVwiNDJcIiAgPGJyIC8+ODogICAgICAgICAgICAgICAgICAgICBGb3JlZ3JvdW5kPVwiRGFya1JlZFwiJmd0OyAgPGJyIHtbJiomXX0vPjk6ICAgICAgIF9TdWJtaXQhICA8YnIgLz4xMDogICAmbHQ7L0J1dHRvbiZndDsgICA8YnIgLz4xMTogICAmbHQ7L0dyaWQmZ3Q7e1smKiZdfSAgPGJyIC8+MTI6ICAmbHQ7L1BhZ2UmZ3Q7ICA8YnIgLz5cIjt7WyYqJl19[[/code]]
Note: On Line 4 HorizontalAlignment=”Center” VerticalAlignment=”Center” properties describe how a child elements should be position within its parent. i.e. this is what actually makes a button, otherwise it would fill out all available space.
Also, note that I have prefixed the ‘_Submit’ – this is how you define Mnemonic in WPF. (you need to hold an ALT key in order for it to show up)

XAML is a language for building .NET objects and here is how we would accomplish the same thing in C# using object initializer:

[[code style="color: black; word-wrap: normal;"]]czoyNDM6XCIgIHZhciB4bWxCdXR0b25UZXN0ID0gbmV3IEJ1dHRvbiAgPGJyIC8+ICAgICAgIHsgIDxiciAvPiAgICAgICAgIEZvbnR7WyYqJl19RmFtaWx5ID0gbmV3IEZvbnRGYW1pbHkoXCJWZXJhbmFkYVwiKSwgIDxiciAvPiAgICAgICAgIEZvbnRTaXplID0gNDIsICA8YnIgLz4ge1smKiZdfSAgICAgICAgRm9yZWdyb3VuZCA9IEJydXNoZXMuRGFya1JlZCwgIDxiciAvPiAgICAgICAgIENvbnRlbnQgPSBcIl9TdWJtaXRcIiAgPHtbJiomXX1iciAvPiAgICAgICB9OyAgPGJyIC8+XCI7e1smKiZdfQ==[[/code]]

There are two concepts how the input is handled in WPF, these are routed events and routed commands.
Events routing allows events to be handled by ancestor of the element who originated the event – there are two patterns for doing that:
1. Bubbling  (most common)
    The event propagates up the visual tree from the source element.

2. Tunneling
    These, as you may suspect, go the other way, down from the source element.

Events come in pairs: There’s usually a preview event that tunnels, followed by an event that bubbles – the reason being is so that the main element gets the first opportunity to respond or react to that event.

Controls 
WPF controls have no intrinsic look, they are ‘lookless’ – this is because templates can replace default look with your own design, unlike in WIN32 where we do have a default look.

Let’s take a look at how to define a template for a button, i.e. custom look, using property element syntax:

Line 2: The part before the dot is interpreted as the ‘class name’ and the part after the dot as the ‘property name’.
Line 3: TargetType=”Button” – defines what control is the template for.

[[code style="color: black; word-wrap: normal;"]]czoyNzA6XCIxOiAgJmx0O0J1dHRvbiBXaWR0aD1cIjY0XCIgSGVpZ2h0PVwiMzBcIiZndDsgIDxiciAvPjI6ICAgICAgICAmbHQ7QnV0dG9ue1smKiZdfS5UZW1wbGF0ZSZndDsgIDxiciAvPjM6ICAgICAgICAgICZsdDtDb250cm9sVGVtcGxhdGUgVGFyZ2V0VHlwZT1cIkJ1dHRvblwiJmd0O3tbJiomXX0gIDxiciAvPjQ6ICAgICAgICAgICZsdDsvQ29udHJvbFRlbXBsYXRlJmd0OyAgPGJyIC8+NTogICAgICAgICZsdDsvQnV0dG9uLlRle1smKiZdfW1wbGF0ZSZndDsgIDxiciAvPjY6ICAgICAgJmx0Oy9CdXR0b24mZ3Q7ICA8YnIgLz5cIjt7WyYqJl19[[/code]]
The code above represents the natural look for the button which essentially is ‘no look’.
Let’s fill in the appearance: (fully working XAML)
[[code style="color: black; word-wrap: normal;"]]czoxMzEzOlwiMTogICZsdDtXaW5kb3cgeDpDbGFzcz1cIldwZkFwcGxpY2F0aW9uMi5NYWluV2luZG93XCIgIDxiciAvPjI6ICAgICAgeHtbJiomXX1tbG5zPVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwvcHJlc2VudGF0aW9uXCIgIDxiciAvPjM6ICB7WyYqJl19ICAgIHhtbG5zOng9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFtbFwiICA8YnIgLz40OiAgICAgIFRpe1smKiZdfXRsZT1cIk1haW5XaW5kb3dcIiBIZWlnaHQ9XCIzNTBcIiBXaWR0aD1cIjUyNVwiJmd0OyAgPGJyIC8+NTogICAgJmx0O0dyaWQgSG9yaXpvbnR7WyYqJl19YWxBbGlnbm1lbnQ9XCJDZW50ZXJcIiBWZXJ0aWNhbEFsaWdubWVudD1cIkNlbnRlclwiJmd0OyAgPGJyIC8+NjogICAgICAmbHQ7QnV0dG97WyYqJl19biBXaWR0aD1cIjg1XCIgSGVpZ2h0PVwiNDVcIiBCYWNrZ3JvdW5kPVwiU3RlZWxCbHVlXCIgVmVydGljYWxBbGlnbm1lbnQ9XCJDZW50ZXJcIiBIe1smKiZdfW9yaXpvbnRhbEFsaWdubWVudD1cIkNlbnRlclwiJmd0OyAgPGJyIC8+NzogICAgICAgICZsdDtCdXR0b24uVGVtcGxhdGUmZ3Q7ICA8YntbJiomXX1yIC8+ODogICAgICAgICAgJmx0O0NvbnRyb2xUZW1wbGF0ZSBUYXJnZXRUeXBlPVwiQnV0dG9uXCImZ3Q7ICA8YnIgLz45OiAgICAgICB7WyYqJl19ICAgICAmbHQ7R3JpZCZndDsgIDxiciAvPjEwOiAgICAgICAgICAgICZsdDtSZWN0YW5nbGUgRmlsbD1cIntUZW1wbGF0ZUJpbmRpbmd7WyYqJl19IEJhY2tncm91bmR9XCIgUmFkaXVzWD1cIjhcIiBSYWRpdXNZPVwiOFwiJmd0OyZsdDsvUmVjdGFuZ2xlJmd0OyAgPGJyIC8+MTE6ICAgICAge1smKiZdfSAgICAgICAgJmx0O0NvbnRlbnRQcmVzZW50ZXIgUmVjb2duaXplc0FjY2Vzc0tleT1cIlRydWVcIiAgIDxiciAvPjEyOiAgICAgICAgIHtbJiomXX0gICAgICAgICAgICAgIENvbnRlbnQ9XCJ7VGVtcGxhdGVCaW5kaW5nIENvbnRlbnR9XCIgICA8YnIgLz4xMzogICAgICAgICAgICAgICB7WyYqJl19ICAgICAgICBWZXJ0aWNhbEFsaWdubWVudD1cIntUZW1wbGF0ZUJpbmRpbmcgVmVydGljYWxBbGlnbm1lbnR9XCIgICA8YnIgLz4xNDoge1smKiZdfSAgICAgICAgICAgICAgICAgICAgICBIb3Jpem9udGFsQWxpZ25tZW50PVwie1RlbXBsYXRlQmluZGluZyBIb3Jpem9udGFsQWxpZ25te1smKiZdfWVudH1cIiAvJmd0OyAgPGJyIC8+MTU6ICAgICAgICAgICAgJmx0Oy9HcmlkJmd0OyAgPGJyIC8+MTY6ICAgICAgICAgICZsdDsvQ29ue1smKiZdfXRyb2xUZW1wbGF0ZSZndDsgIDxiciAvPjE3OiAgICAgICAgJmx0Oy9CdXR0b24uVGVtcGxhdGUmZ3Q7ICA8YnIgLz4xODogICAgICB7WyYqJl19ICBfU3VibWl0ICA8YnIgLz4xOTogICAgICAmbHQ7L0J1dHRvbiZndDsgIDxiciAvPjIwOiAgICAmbHQ7L0dyaWQmZ3Q7ICA8YnIgL3tbJiomXX0+MjE6ICAmbHQ7L1dpbmRvdyZndDsgIDxiciAvPlwiO3tbJiomXX0=[[/code]]
Line: 10 “TemplateBinding Background” – allows us to bind the property ‘Background’ on line: 6 to the Content Presenter which essentially is a placeholder for any XAML content to be used during runtime.

The curly brackets tell XAML that we are using something called: the markup extension. (more about it in future posts). For now, let’s just say that markup extensions decide during runtime how the properties are set. What line 10 says is that we are creating an object of type: TemplateBinding and we are passing a string (yes, string) called ‘Background’ to a constructor.

Primitive elements:

The elements that define or rather have template are the controls in WPF, and as you may suspect not everything is a control in WPF. In other words you don’t have to worry as to how anything ever appears on your screen when programming in WPF. It’s only the elements that derive from the Control class, such as button that look for their appearance in template.
For example Rectangle, TextBlock and Image derive from the framework element – these are primitives and do not have a template of their own.

Layout primitives:

Grid Panel – flexible grid-based area with columns and rows.
Canvas Panel – fixed area to position elements by the use of coordinates.
Stack Panel – simple vertical or horizontal arrangement in a single line.
Dock Panel – allows to arrange child elements vertically or horizontally relative to each other; similar to windows forms docking.
Wrap Panel – allows to arrange child elements in a flow-like formatting.



WPF – Part: 1

Published October 26, 2013 in WPF - 0Comments

This is Part: 1 of the overview WPF Tutorial. 
I will tackle specific WPF concepts separately in future posts.

    WPF is a powerful framework for building windows applications, however there is a steep curve in learning. The whole WPF framework only makes sense when all the individual pieces of the framework fall in together. In other words, one must understand the entire WPF framework in order to understand any of it.

1. How Windows Forms differ from WPF?


    Windows forms are simply wrappers around USER 32 and GDI 32 APIs – which provide the traditional Windows look and feel and drawing support for rendering shapes, text, images, etc. respectively.

WPF doesn’t use GDI 32 rendering API at all, it’s part of .NET and a mixture of managed and unmanaged code and it’s only available from .NET – i.e. no public, unmanaged API calls allowed.


2. What’s in it for me?

    Today’s hardware and graphics cards in particular offer a lot of computing power, it’s not unheard of having gigabytes of memory purely on the graphics cards. If fact today’s graphics cards have more processing power than windows machines did 25 years ago, back when user.exe (16bit dll – and yes it had .exe extension) and later 32-bit backwards compatible USER 32 were designed. Also, remember that GDI and USER subsystems were introduced with Windows 1.0 in 1985. 
The USER 32 and GDI 32 subsystems weren’t designed for the new powerful graphics cards, so most of the power sits unused.

How do we take advantage of new graphics cards that offer 3D accelaration? 

One way is to write open GL or Direct X code, but that of course does not easily intergrate with user interface application, drop down boxes, data binding, etc. Using (or so I’ve heard) Direct X API to create windows business applications isn’t for the faint of heart. That’s where WPF comes in. WPF uses Direct X API,  so all WPF drawing is performed through Direct X, which allows it to take advantage of the latest in modern video cards.
   

    There’s also an issue with resolution, classic style of constructing user interfaces has issues on modern PCs because windows applications are bound by certain assumptions about screen resolution and that makes traditional applications unscalable. Windows applications render small on very high resolution monitors because they cram pixels more densely. 
WPF does not have this problem, because it uses system DPI setting and renders all elements on the screen by itself, so a button that’s 1 inch long on low resolution monitor will remain 1 inch long on a high resolution monitor. In other words, all elements on the screen are measured using device-independent units.

   Of course it is possible to write an application (without using WPF) that scales up or down itself and adapts to different screen resolutions (pixel size of the display), however most displays or monitors in the past had roughly the same pixel size, so of course nobody bothered to do that. Luckily for us WPF applications are DPI aware and hence scalable by default, nothing special needs to be done on your part. 

3. Let’s get our hands dirty and do some XAML WPF test (without actually writing any real code)

Note: It may surprise you but WPF doesn’t need XAML and XAML doesn’t need WPF.
Althought most of WPF is written using XAML.


Back in the day Microsoft used to bundle XamlPad with Visual Studio 2008, but it has been discontinued. You can still get it if you have MSDN Subscription but since not everyone reading this has one I found an alternative solution: Kaxaml.
It essentially lets you enter XAML and see what it will look like.

Enter the code below, if fact all you need to enter is the text in bold:

[[code style="color: black; word-wrap: normal;"]]czoyOTY6XCIgJmx0O1BhZ2UgIDxiciAvPiAgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFte1smKiZdfWwvcHJlc2VudGF0aW9uXCIgIDxiciAvPiAgeG1sbnM6eD1cImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YXtbJiomXX1tbFwiJmd0OyAgPGJyIC8+ICAmbHQ7R3JpZCZndDsgIDxiciAvPiAgPGI+ICZsdDtCdXR0b24gQ29udGVudD1cIk9LXCIgV2lkdGg9XCI4NXtbJiomXX1cIiBIZWlnaHQ9XCIyNVwiLyZndDsgPC9iPiA8YnIgLz4gICZsdDsvR3JpZCZndDsgIDxiciAvPiAmbHQ7L1BhZ2UmZ3Q7ICA8YnIgLz5cIntbJiomXX07e1smKiZdfQ==[[/code]]



Now, if you zoom in, you can see that the button does not get pixelated.



Composibility – it’s the power of WPF. We can compose all the different styles of content that WPF supports inside the button, so let’s take this basic button control and…

a. Add layout:


[[code style="color: black; word-wrap: normal;"]]czo4MTpcIiAmbHQ7UGFnZSB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhe1smKiZdfXRpb25cIiZuYnNwO1wiO3tbJiomXX0=[[/code]]
[[code style="color: black; word-wrap: normal;"]]czozNDE6XCIgICAgICAgeG1sbnM6eD1cImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sXCImZ3Q7ICAgPHtbJiomXX1iciAvPiAgJmx0O0dyaWQmZ3Q7ICA8YnIgLz4gICAgJmx0O0J1dHRvbiBXaWR0aD1cIjg1XCIgSGVpZ2h0PVwiMjVcIiAmZ3Q7ICAgIDxicntbJiomXX0gLz4gICAgIDxiPiAmbHQ7U3RhY2tQYW5lbCZndDsgICAgPGJyIC8+ICAgICAgICZsdDtUZXh0QmxvY2sgVGV4dD1cIk9LXCIvJmd0OyB7WyYqJl19ICAgPGJyIC8+ICAgICAgJmx0Oy9TdGFja1BhbmVsJmd0OyA8L2I+ICA8YnIgLz4gICAgJmx0Oy9CdXR0b24mZ3Q7ICAgPGJyIC8+IHtbJiomXX0gJmx0Oy9HcmlkJmd0OyAgPGJyIC8+ICZsdDsvUGFnZSZndDsgIDxiciAvPlwiO3tbJiomXX0=[[/code]]
WPF supports something called: a content model

Button in WPF lets you add only one child, just so it doesn’t have to be in charge of how all the other children are laid out, here I’ve used <StackPanel> so I can add more children later.

2. Format text:
[[code style="color: black; word-wrap: normal;"]]czo3NTpcIiAmbHQ7UGFnZSB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhe1smKiZdfXRpb25cIlwiO3tbJiomXX0=[[/code]]
[[code style="color: black; word-wrap: normal;"]]czo0Mzc6XCIgICAgICAgeG1sbnM6eD1cImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sXCImZ3Q7ICA8YntbJiomXX1yIC8+ICAmbHQ7R3JpZCZndDsgIDxiciAvPiAgICAmbHQ7QnV0dG9uIEhvcml6b250YWxBbGlnbm1lbnQ9XCJDZW50ZXJcIiBWZXJ0aWN7WyYqJl19YWxBbGlnbm1lbnQ9XCJDZW50ZXJcIiZndDsgICAgPGJyIC8+ICAgICAgJmx0O1N0YWNrUGFuZWwmZ3Q7ICAgPGJyIC8+ICAgICAgIDxie1smKiZdfT4mbHQ7VGV4dEJsb2NrIEZvbnRTaXplPVwiMzBcIiZndDsgV1BGICZsdDtJdGFsaWMmZ3Q7UnVsZXombHQ7L0l0YWxpYyZndDsgJmx0O3tbJiomXX0vVGV4dEJsb2NrJmd0OzwvYj4gICAgIDxiciAvPiAgICAgICZsdDsvU3RhY2tQYW5lbCZndDsgICAgIDxiciAvPiAgICAgJmx0Oy9Ce1smKiZdfXV0dG9uJmd0OyAgICA8YnIgLz4gICZsdDsvR3JpZCZndDsgIDxiciAvPiAmbHQ7L1BhZ2UmZ3Q7ICA8YnIgLz5cIjt7WyYqJl19[[/code]]

Notice that I’ve added HorizontalAlignment and VerticalAlignment so that the button will size itself according to the content.

3. and some graphics:

[[code style="color: black; word-wrap: normal;"]]czo2NjM6XCIgJmx0O1BhZ2UgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFtbC9wcmVzZW50e1smKiZdfWF0aW9uXCIgIDxiciAvPiAgICAgICB4bWxuczp4PVwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWxcIiZ7WyYqJl19Z3Q7ICA8YnIgLz4gICZsdDtHcmlkJmd0OyAgPGJyIC8+ICAgICZsdDtCdXR0b24gSG9yaXpvbnRhbEFsaWdubWVudD1cIkNlbnRlclwie1smKiZdfSBWZXJ0aWNhbEFsaWdubWVudD1cIkNlbnRlclwiJmd0OyAgIDxiciAvPiAgICAgJmx0O1N0YWNrUGFuZWwmZ3Q7ICAgICA8YnIgLz4gIHtbJiomXX0gICAgICZsdDtUZXh0QmxvY2sgRm9udFNpemU9XCIzMFwiJmd0OyBXUEYgJmx0O0l0YWxpYyZndDtSdWxleiZsdDsvSXRhbGljJmd0OyZ7WyYqJl19bHQ7L1RleHRCbG9jayZndDsgICAgPGJyIC8+ICAgICAgICA8Yj4mbHQ7RWxsaXBzZSBGaWxsPVwiUmVkXCIgV2lkdGg9XCIzMy4xNDNcIiB7WyYqJl19SGVpZ2h0PVwiMzMuMTQzXCIvJmd0OyAgIDxiciAvPiAgICAgICAgJmx0O0VsbGlwc2UgRmlsbD1cIkJsdWVcIiBXaWR0aD1cIjMzLjE0M1wiIHtbJiomXX1IZWlnaHQ9XCIzMy4xNDNcIi8mZ3Q7IDwvYj4gIDxiciAvPiAgICAgJmx0Oy9TdGFja1BhbmVsJmd0OyAgPGJyIC8+ICAgICZsdDsvQnV7WyYqJl19dHRvbiZndDsgICA8YnIgLz4gICZsdDsvR3JpZCZndDsgIDxiciAvPiAmbHQ7L1BhZ2UmZ3Q7ICA8YnIgLz5cIjt7WyYqJl19[[/code]]
Not very exciting graphics but the point to illustrate was composability of WPF.

As I’ve mentioned at the beginning, WPF does not necessarily need XAML, so how would
something like this?
<Button x:name=”submitButton” FontSize=”30″ FontFamily=”Arial’>_Submit</Button>

be written without XAML? Here’s how:

Button button = new Button();button.FontSize=30;button.FontFamily=new FontFamily(“Arial”);button.Content = “_Submit”;

That’s it for the first.