Tutorials Books Videos Forums

Change the theme! Search!
Rambo ftw!

Customize Theme


Color

Background


Done

Data Binding to CLR Objects

by kirupa   | filed under .NET and C#

This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.

One of the nice features in Windows Presentation Foundation (WPF) is data binding. In a nutshell, data binding is about binding various .NET objects together. To be more precise, you are creating a relationship between a source and a target object. When the source is updated, your target is informed and reacts accordingly. Likewise, depending on how you setup your binding, your source can be notified of any changes by your target.

The words source and target are pretty generic, so let's get more specific. In the context of GUI applications, the source of a binding is some data, and the target is a UI element that updates based on a change to your source. In this tutorial, we are going to explore a very basic scenario of data binding where you have a collection of data that needs to be represented in our UI. Beyond that, we'll take some scenic detours that explain some other features of data binding.

The following is the application you will have created by the end of this tutorial:

fontpreview

[ the Font Preview application ]

To run the above application, click here or on the above screenshot. You'll need the .NET Framework 3.0 installed, and if you are using Firefox, be sure to download the FFClickOnce extension to easily run ClickOnce applications.

The Font Previewer Application

Before we begin, let me first describe the application you will be creating. In the above application, you select a font from a list of fonts, and the preview text updates itself to display in the font you selected. Beyond that, each font name in the combobox is styled in the very font it is describing. Those are the important UI/functionality details.

Under the hood, the list of fonts is generated from a CLR source, and your combobox binds itself to the CLR source to display those fonts. Data binding, as you'll find out towards the end of this tutorial, can also exist between elements. Both the styled text in your combobox and textbox rely on you data binding the FontFamily value with the text displayed in your combobox. By the end of this tutorial, you should have enough practice with data binding between CLR objects and UI elements.

Let's Get Started - Creating the Interface

In the following sections, you'll learn how to create the above application with all of its neat features. Let's first start by creating the interface:

  1. Launch Blend and create a new Standard EXE called Font Previewer. Make sure your language is set to Visual C# and press the OK button to close the Create New Project window:

[ create a new Standard Application (.exe) called FontPreviewer ]

  1. I don't want you to spend too much time fiddling with the interface, for that isn't an important goal of this tutorial. To save you some time, I'll provide all of the XAML you need for your application's UI. Don't worry - you'll have the opportunity to add all of the data binding stuff yourself. Click on the XAML tab to view your current application's XAML:

[ click on the XAML tab to leave the Design view ]

  1. Once you clicked on the XAML tab, you'll see a few lines of markup defining your application:

 

Let's replace all of the above code with some code I'll provide. Select all of your code and replace it with the following XAML:

  1. After you have copied and pasted the above code, click on the Design tab to go back to your Design view. Your Artboard should now look like the following image:

[ what your interface looks like right now ]

Your interface is now complete, but the important under-the-hood functionality still remains to be implemented. We'll tackle that in the next and following sections.

In the previous section, you created a new project and used some existing XAML code to create the interface. In this page, let's create the CLR object that we will later use for data binding purposes.

Creating our CLR Data Source

To recap what our application does, in a nutshell, we have a combobox that displays a list of fonts. The font list is provided by a CLR data source that takes all of the fonts your computer has and stores them in an easily accessible list. Let's look at how to do that by picking up from where we left off earlier and creating our CLR data source:

  1. In Blend, click on the Project tab to view all the files currently used by your FontPreviewer app:

[ the Project view displays all of the files used by your Project ]

  1. Let's add a new C# source file that will generate a list of font names. Right click on the FontPreviewer C# solution icon and select Edit Externally:

[ right click on your solution and select Edit Externally ]

  1. After you have selected the Edit Externally item, Visual Studio (or the free Visual C# Express) will launch. You may receive a Security Warning dialog window informing you of the pitfalls of opening this project. Don't worry, and select the Load project normally option and select OK:

[ Load the project normally ]

  1. Once your project has been opened, find the Solution Explorer panel towards the top-right corner. Notice that this is similar to the Project view in Blend because it too displays a list of all files in your project:

[ the Solution Explorer displays a list of all files used by your project ]

  1. Right click on your FontPreviewer C# solution icon and select Add | New Item:

[ right click on your solution and go to Add | New Item ]

  1. The Add New Item window will appear. From this window, select the Class template:

[ select the Class template o create a new class ]

Also from this window, towards the bottom, set the file name of this class to FontCollection.cs:

[ your new class the name FontCollection.cs ]

After you have made the above changes, press the Add button to close the Add New Item window. After your Add New Item window closes, the FontCollection.cs file will be opened for you to edit:

[ code that is already provided for you in your FontCollection.cs file ]

  1. Select all of your code and replace it with the following:

  1. Press F6 to build your application to make sure you aren't running into errors. You may be prompted to create a new Visual Studio solution file, so go ahead and do so if you are asked.

You just created a data source consisting of CLR objects. Don't worry if you are not sure what the C# code does. I'll cover in greater detail what each line of code does towards the end of this tutorial. For now, just remember that the code you pasted is responsible for providing your combobox with a list of fonts.

In the previous section, you created the data source. In this page we'll make good use of our data source and display it in our interface.

Displaying Font Names in the Combobox

Creating the data source is just one part of the equation. The next part is letting your UI know about it. Let's go about doing:

  1. Go back to Blend. Because you made some modifications to your project in Visual Studio / C# Express, you will be prompted with a Project Modified dialog:

[ because you edited your project outside of Blend, you may be prompted to reload the project to make sure everything is in sync and working with Blend ]

Press the YES button to reload the project. If you glance at your Project panel (exposed via the Project tab), you'll see the FontCollection.cs file you created in Visual Studio / C# Express appear:

[ your FontCollection.cs file will appear after you reloaded ]

  1. From the same Project panel, look towards the bottom where you will find the Data panel. From the Data panel, click on the +CLR Object button:

[ add a CLR object by clicking the +CLR Object button ]

  1. After you clicked on the +CLR Object button, the Add CLR Data Source window will appear. From this window, change the Data Source name to FontSource. Next, find and select the FontCollection class:

[ rename your data source to FontSource and select the FontCollection class ]

After you have renamed your data source to FontSource and selected the FontCollection class, press the OK button to close your Add CLR Object Data Source window.

  1. If everything went well, your Data panel will now display your newly added FontSource CLR data source:

[ your FontSource data source appears in the Data panel ]

  1. Now, let's get the data from the FontSource into your combobox. Right click on your ComboBox and select the Bind ItemsSource to Data... item:

[ right click on your combobox and select Bind ItemsSource to Data ]

  1. After selecting the Bind ItemsSource to Data item, the Create Data Binding window will appear. From this window, under Data Sources, select the name of our data source FontSource:

[ select FontSource under the the Data Sources area ]

After selecting FontSource, on the right-hand side under Fields, select the FontCollection (Array) item:

[ under fields, select the FontCollection class ]

  1. After completing the preceding step, press the Finish button to accept the selections and to close the Create Data Binding window. If you look at your combobox, you probably won't see anything, but if you preview the application by pressing F5 and click on the combobox, you will see your fonts displayed:

[ how your application looks and behaves right now ]

  1. That odd behavior where your combobox seems empty until you click it is because we haven't specified the default selected item. With your combobox selected in Blend, look in the Common Properties panel for the SelectedIndex property. Enter a 0 for your SelectedIndex:

[ set the first item as default by entering 0 for our SelectedIndex ]

  1. After you set your SelectedIndex value to 0, you will see that your combobox now displays the first font from the list of fonts bound to it::

[ your first font is now selected by default ]

If you run your application by pressing F5, you will see your combobox in action. Although, at this point, it does not do much beyond simply displaying the fonts:

[ what  your application looks like at this stage of your tutorial ]

We've made some great progress so far. In this page, you successfully bound your CLR data source to your combobox. As you saw, the result was you were able to expand your combobox to display a list of all of your system fonts.

In the next section, let's make it so that the font you select in the combobox displays the preview text in the selected font.

In the previous section, you used data binding to display the font names in our combobox. In this page, we'll make UI modifications based on what font was displayed.

Updating our Preview TextBox

One of the main features of our application is being able to see how your sample text looks like based on the font selected in your combobox. In this section, you will learn how to implement that feature....using data binding:

  1. Select your font preview textbox by selecting the [TextBox] item in your Objects and Timeline panel:

[ select the textbox from the Objects and Timeline panel ]

You can also select your TextBox by clicking on the sample text in the Artboard:

[ you can also select the textbox by clicking on it directly in the Artboard ]

  1. Once you have selected the TextBox, look in your Properties panel's Text panel. Find the FontFamily combo box where you can select your text's font. To the right of that combobox, you'll see a small square known as the Advanced Properties button:

[ the small square to the right of many properties is the Advanced Properties button ]

Click on that button to display the Advanced Properties menu.

  1. Once you have clicked the FontFamily's Advanced Properties button, a menu will appear:

[ a menu will appear with advanced options ]

From this menu, click on the Data Binding item.

  1. After you have clicked on the Data Binding item, the Create Data Binding window will appear. You should be familiar with this window from a previous section! From this window, click on the Element Property tab:

[ click on the Element Property tab to bind element properties ]

  1. Once you have clicked on the Element Property tab, look in the Scene Elements area on the left-half of your Create Data Binding window. It should resemble your Objects and Timeline panel. Keep expanding your objects until you find the combobox  control:

[ expand your controls to find your ComboBox control ]

Once you have found the ComboBox control in your Scene elements, select it.

  1. After your combobox has been selected, look in the Properties area on the right-half of your Create Data Binding window. What we want is to select the combobox's property that represents the text displayed inside your combobox.

    In the Properties area, you will see the combobox properties that might seem to work:

[ on the right side, you will see the properties for the control you selected on the left side ]

The property you want is the Text property, so select it from the displayed ComboBox properties. Press the Finish button to create the binding and to close the Create Data Binding window. You will notice that your preview text now changes to display in the font name selected by your combobox:

[ your text displays in the combobox's selected font ]

Whereas, before, your text was displayed in a default font:

[ your text always displays in just the default font ]

  1. Test your application by pressing F5. Notice that now, depending on the font you select, your preview text now changes to display in the font selected in your combobox:

[ your preview text displayed in everyone's favorite Comic Sans MS font ]

All right! We are almost done working on our application. The last thing that remains for us to do is to change the font of the displayed text in each item in our combobox. Let's learn how to do that in the next section.

In the previous section, you implemented a feature where your preview text's font changes depending on the combobox item you selected. In this and the next section, you'll learn how to change the font of each of your combobox items.

Changing the Font of Each Combobox Item

Right now, all of your combobox items display in the same font:

The goal is to have each item display in the font it is representing:

In this section, let's implement this feature. There are quite a number of steps that seem pretty random, but I'll try to recap all that you have done towards the end of this tutorial to provide you with a better understanding of why what you did worked:

  1. To change the font of each displayed item, we first need to define a DataTemplate for your combobox. A DataTemplate helps you specify how your data will be displayed. To define a DataTemplate, you'll need to go back to your Create Data Binding window.

    There are two ways to do that. The way you are already familiar with is by by right-clicking on your combobox and selecting Bind ItemsSource to Data:

[ right click on the combobox and select Bind ItemsSource to Data... ]

The other, equally valid way, is by accessing the Advanced Properties button located to the right of your ItemsSource property under your Common Properties panel:

[ access advanced properties for your ItemsSource ]

Once you have clicked the Advanced Properties button, select the Data Binding menu item:

[ from the menu that appears, select Data Binding ]

Regardless of which approach you use, the end result is that you will see the Create Data Binding window appear for your combobox.

  1. From the Create Data Binding Window, click on the Define DataTemplate button:

[ click on the Define DataTemplate button to specify how your data will be displayed ]

  1. Once you have clicked the Define DataTemplate button, the Create Data Template window will appear. It is in this window that you specify exactly which pieces of data from your data source you want and how that data will be displayed.

    Ensure the New Data Template and Display Fields option is selected, and let's change the Name to FontDataTemplate:

[ change the name of your data template to FontDataTemplate ]

  1. Below the Name field, you will see all of the accessible properties and methods of your FontCollection class. Uncheck everything except the checkbox for Source (string) and, for obvious reasons, the parent checkbox FontCollection: (FontFamily):

[ specify the data you want displayed ]

  1. To point out some other interesting things, to the right side of of your Create Data Template window, you have a Preview area that shows you exactly what data will be displayed:

[ only the fonts from your FontCollection will be displayed ]

That is especially useful if you are planning on displaying various pieces data from multiple locations in your class. To specify how your data will be displayed, look to the right of your FontCollection class's properties and methods:

[ choose which controls will host your data ]

In that area you can see what type your data will be returned in, and more importantly, you can specify which control will be hosting/displaying your data. For example, our entire FontCollection class will store its data in a StackPanel, and our Source (the name of the font) will be displayed in a TextBlock.

  1. Just to recap, make sure only your Source (string) and FontCollection (FontFamily) properties are checked and press OK to create the new data template and to close the Create Data Template window.

We still have some more work left before this feature is fully implemented.

In the previous section, you started implementing the custom font feature for each combobox feature. Let's pick up from where we left off and finish this feature on this page.

  1. With our data template created, let's edit the StackPanel and TextBlock controls that were created as a result. Right click on your combobox and, from the menu that appears, go to Edit Other Templates | Edit Generated Items (ItemTemplate) | Edit Template:

[ edit your Generated Items' Template ]

  1. After you have navigated the horde of menu-items to select the Edit Template item, you'll see your combobox's ItemTemplate exposed for you to edit:

[ you now have access to the controls that specify the ItemTemplate ]

If you glance at your Objects and Timeline panel, you'll see that the controls you saw in the Create Data Template window are the only controls that are displayed:

[ the controls you specified in your data template are displayed ]

Getting back to our task at hand, select your TextBlock with the mouse so that it is highlighted. You can select the textblock directly from the Artboard or from the Objects and Timeline panel.

  1. With your textblock selected, find the FontFamily's Advanced Property button under Common Properties just like you did earlier:

[ click on the font family's Advanced Properties button ]

Click on the Advanced Property button and select the Data Binding item:

[ select the Data Binding item to access the binding properties for your FontFamily ]

  1. After clicking the Data Binding item, you'll be back once again to your Create Data Binding window. Click on the Element Property tab, and from the Scene Elements area, select your textblock:

[ select your TextBlock under Scene elements ]

  1. On the right half of your Create Data Binding window, where the Properties area is, select the Text : (String) property:

[ under Properties, select the Text property ]

  1. After you have selected the Text property, press the Finish button to accept the binding and to close the Create Data Binding window. Blend will take a few seconds to process what you did, but your end result will be that each of your combobox's items - the textblock - now display in the same font as the text they are displaying:

[ how your combobox's items look like right now ]

  1. Even though you are still in this special ItemTemplate editing mode, that is nothing more than just another way of saying you want to edit the internals of how your control displays its data. You are free to make the usual modifications that you normally are capable of. Let's look at one such modification.

    Right now, all of the TextBlocks seem closely stuck together. Let's increase the spacing by adjusting the padding. With your textblock selected, search for the Padding property in your Properties panel:

[ typing the letter pad in the Search field returns the Padding property ]

You should find the Padding properties after typing in only a few letters in padding. In the Padding fields, set the left and top padding values to 3:

[ set your top and left padding values to 3 ]

Your combobox's textblocks should now have some extra breathing room!

  1. Ok, let's go back and leave this ItemTemplate editing mode. To return to your main Artboard, press the Scope Up button in your Objects and Timeline panel:

[ use the Scope Up button to exit the ItemTemplate editing mode ]

  1. Run your application one more time by pressing F5. Notice that now, your combobox's items are displayed in the very font they are displaying:

fontpreview

[ your application is finally complete ]

If you experience a delay when you click on your combobox, that is a sideffect of displaying lost of complex visual data in our implementation. Check out my blog post on this topic to learn how to fix it.

Phew. This was one long tutorial. In the next section, you'll learn more details about why you did some of the things you did. After all, it isn't good enough to memorize the steps I have provided. You should be able to explain why I used the steps that I did and be able to apply what you learned in creative ways that go beyond the basic information in this tutorial.

In the previous section, you wrapped up this tutorial. In this page, let's take a look back at why you did some of the things you did.

Review: Tying up Loose Ends

In this section, let's look back at parts of this tutorial that I rushed through and take a step back to better understand why we made some of the choices we did. Let's first take a look at the C# code I hastily made you copy and paste:

Examining the Code

In a nutshell, our C# code defines a program that simple returns a list of all fonts currently installed on our system:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.Windows.Media;
namespace FontPreviewer
{
  class FontCollection : ObservableCollection<FontFamily>
  {
  public FontCollection()
  {
  foreach (FontFamily f in Fonts.SystemFontFamilies)
  {
  this.Add(f);
  }
  }
  }
}

Let's go through the code line by line:

namespace FontPreviewer

In the above line, you specify the namespace your code belongs to. It is pretty important that your namespace name matches the name of your WPF application's namespace. If you used a program like Visual Studio / C# Express to add your new class file, the namespace information is automatically provided for you.


class FontCollection : ObservableCollection<FontFamily>

In this line, I provide my class name - FontCollection. Beyond just specifying the class name, more importantly, I am extending my class by the ObservableCollection class. An ObservableCollection is one of a number of classes that notify the UI when changes are made, and this class implements the INotifyCollectionChanged interface.

That last detail is important because one of the goals of data binding is to separate your data source (Model) from your UI (View). When updates are made to your data, you ideally want your UI to automatically be notified of the change and update itself without you manually targeting each UI/View and forcing it to do a refresh. The refresh and update properties are not used in this tutorial because you do not add or remove fonts while running your application.


public FontCollection()

This is just the name of our constructor. There really isn't really more to say about this line except that it's name matches the name of our class.


foreach (FontFamily f in Fonts.SystemFontFamilies)
{
  this.Add(f);
}

In the above line, I go through each font in our Fonts.SystemFontFamilies collection and add each FontFamily to ourselves: this.Add(f). Even though I did not explicitly define the Add method, I am able to use the Add method on our parent class because our FontCollection class extends ObservableCollection which does contain an Add method for us to use.


Another Type of Data Binding: UI to UI

There is no hard set rule on what makes a valid data binding. All you need for a data binding in WPF is a target and a source. In this tutorial, you encountered two types of data binding. One type was the binding between a CLR data source and a UI element. The other type of binding was where you bound properties of one UI element to the properties of another UI element.

Let's examine the latter case of the UI property to UI property binding in greater detail. In one part of your tutorial, you set your TextBlock's FontFamily property to the Text property used by a TextBlock. In many ways it seems a bit baffling that even works.

On one hand, the font of your text is determined by an object of type FontFamily. Your data from the Text property is of type String. In procedural code in C#, you would have run into an error if you attempted to set the FontFamily equal to the Text value. You are able to get away with this, though, because of type conversions that go on in the background.

Let's look at our FontCollectionTemplate data template's XAML:

<DataTemplate x:Key="FontCollectionTemplate">
<StackPanel>
<TextBlock Text="{Binding Path=Source, Mode=OneWay}" x:Name="TextBlock" FontFamily="{Binding Path=Text, ElementName=TextBlock, Mode=Default}" Padding="3,3,0,0"/>
</StackPanel>
</DataTemplate>

Notice that your binding already knows that what it is looking for is of type FontFamily. The rest is just matching what you need from your TextBlock's Text property. That matching  works because there is a type converter in FontFamily that takes String information and creates a working FontFamily object.

For a sanity check, if you were to look in Blend's FontFamily property for your textblock, notice what value is displayed:

The value displayed in your FontFamily property is the name of the font - a name that is  represented in String format.

One thing to be careful is if you are binding to an invalid value - such as passing in a value for which the target has no default converter for - you will run into an exception. Data binding exceptions are not the easiest of things to find and fix, so be careful when setting up your bindings.


Fixing Poor ComboBox Performance

After your ComboBox items began to be styled in the font they were displaying, you may have noticed the performance of your combobox decrease drastically when you tried expanding it for the first few times. For the solution and a better explanation of the problem, my blog post on this topic should help you out.


Download Source Files

If you are curious to look at my implementation of the Font Previewer application, download and extract the final source files for this project:


Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy my books, became a paid subscriber, watch my videos, and/or interact with me on the forums.

Your support keeps this site going! 😇

Kirupa's signature!

The KIRUPA Newsletter

Thought provoking content that lives at the intersection of design 🎨, development 🤖, and business 💰 - delivered weekly to over a bazillion subscribers!

SUBSCRIBE NOW

Creating engaging and entertaining content for designers and developers since 1998.

Follow:

Popular

Loose Ends

:: Copyright KIRUPA 2026 //--