Introduction

Whenever a new technology comes along, I personally find that the best way to get to grips with its functionality is to try and create something you have done in another language. To this end, this article will describe how to create a custom control in WPF which will raise custom events. The custom control will then be placed with a standard XAML window and the custom control's events shall be subscribed to. That's it in a nutshell. But along the way there are several things that I would like to point out to you.

The proposed structure will be as follows:

A word on XAML / WPF

The custom Control Itself

A word on events in .NET 3.0

Referencing an external custom control in an XAML window

Where is the InitializeComponent() method anyway

A screen shot of the demo app

A Word On XAML / WPF

WPF applications are quite similar is one sense to ASP.NET applications; there may (or may not) be an XAML file, and also a code behind file where the XAML file contains the windows / control rendering, and the code behind does all the procedural code. This is one development model. But there is another way. Anything that can be done in XAML can also be done entirely in code behind (C#/ VB). To this end the custom control that I've created is entirely code created. As for this example it just seemed to make more sense.

The Custom Control Itself

As color pickers seem to be almost universally popular at codeproject, I thought let's do one of them. This is a single control that has been created in a separate Visual Studio 2005 project, and is part of the whole solution. I have done this as it is the most common way that we all use third party controls. We get a DLL and make a reference to it. In fact I have chosen this path, as the XAML directives to reference a control do vary slightly depending on whether it is an internal class, or an external DLL. Most commonly I thought it would be a third party external DLL that was being referenced. If you don't get this, don't worry. There will be more on it later.

It can be seen that this is all fairly normal C# .NET 3.0 code (that is if you are OK with .NET 3.0 stuff, I am just learning). I want to pay some special attention to the constructor. Let's have a look at that part by part.

// Define a template for the Items, use the lazy FrameworkElementFactory
// method
FrameworkElementFactory fGrid = new FrameworkElementFactory
(typeof(System.Windows.Controls.Primitives.UniformGrid));
fGrid.SetValue
(System.Windows.Controls.Primitives.UniformGrid.ColumnsProperty, 10);
//update the ListBox ItemsPanel with the new ItemsPanelTemplate just created
ItemsPanel = new ItemsPanelTemplate(fGrid);

The FrameworkElementFactory class is a way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate. This is equivalent to creating a <ControlTemplate> tag in XAML markup. So what we are really doing here is saying that the internal inherited Listbox.ItemsPanel will have a template applied to it that will be a uniform grid layout with 10 columns.

This section of the code is responsible for creating the individual ListItem contents. So what is going on? Well, the items are being created as Rectangle objects (yep that's right, Rectangles). Then the Rectangles are being filled with a Brush color, and then the Rectangle has a ToolTip applied.

//Indicate that SelectedValue is Fill property of Rectangle item.
//Kind of like an XPath query, this is the string name of the property
//to use as the selected item value from the actual item data. The item
//data being a Rectangle in this case
SelectedValuePath = "Fill";

Finally the SelectedValuePath is told that the property that should be mapped to the SelectedValue is "Fill". So this means that whenever we get the SelectedValue the object it will be is a Brush as default, as "Fill" is a Brush Type, unless it is cast to another object Type. Isn't that mental. WPF is mind blowing, it really is.

The more eagle eyed amongst you will notice that the code for the control contains 2 events one of which is commented out. More on this later.

A word on events in .NET 3.0

Microsoft being Microsoft didn't want us to get too comfortable with things, so they have overhauled everything it would appear. Even something as small as events, is no longer the same as it was in .NET 2.0.

The code snippets below represent the new .NET 3.0 way of creating events.

I have created a custom event called NewColorEvent so let's have a look at how to define an event:

And that's all there is to creating a custom event in a custom control. We just need to place the control somewhere now and subscribe to this lovely new event.

Referencing an external custom control in an XAML window

OK so you think you know how to make a reference to a DLL which contains a custom control. You just create a new tab on the toolbar, and browse to the DLL and any of the contained controls to the toolbar. Right. Well that didn't seem to work. So what do you have to do. Is Add a project reference (right click on references) and browse to the assembly (DLL) with the custom control(s), only one in this articles case.

So that's step 1. Then we actually want to use the custom control within a XAML window. So we have to add an extra directive to the XAML Windows root element. The important part to add is as follows:

That's part of the story. We have now successfully referenced the external user control in the XAML, but we still don't have an instance of the control in the markup yet. So how do we do that. Well we do something like this:

OK so now we have done the XAML part, but what about the code behind file. We still need to do that part. So how is that done. Well, luckily that part is easier. Its just a normal using statement we need:

using ColorPicker;

Where is the InitializeComponent() method anyway ?

Now we really do have a fully referenced external DLL, which contains a user control, which we now have an instance of within our XAML window, that is also now known about by the code behind logic because of the two steps just carried out.

But just how does the XAMLs code behind file know about the user control contained within the XAML file. Well the answer to that, is that when Visual Studio compiles a project, it creates a new generated source file, which is placed into the DEBUG\OBJ or RELEASE\OBJ (depends on how you are compiling the project). This file is called the same as the current XAML window file, but the extension will be g.cs for c# or g.vb for VB.

It can be seen that this source file provides the missing parts, most noticeably the InitializeComponent() method and also notice that there are a few instance fields which represent the components within the XAML file. So this is how both the code behind and XAML files are compiled to form a single assembly with all the required information.

Demo Of The Attached Application

The last thing I should show is the running app. That part is probably not so important, as it is the concepts I was trying to share really.

That's it

Well although we've only created a simple control and used it within a single XAML page, I hope you can see that there are quite a few core concepts that were covered here.

So What Do You Think ?

I would just like to ask, if you liked the article please vote for it, as it lets me know if the article was at the right level or not.

Conclusion

I have quite enjoyed constructing this article. I hope you liked it. I think it will help you a lot when you get time to do some XAML / WPF type apps. I have only just started out with XAML and I truly believe it is set to totally change the sort of applications we are all going to see.

History

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.