WPF: Using controls as content

One of the fantastic new features in WPF is the way many controls can use other controls (and a lot of other things apart from what would usually be regarded as controls) as content. I wanted to try this out, and I created a little sample program.

I started with a small WPF application that has a window with a ListBox control in it. Then I created the following class:

   public class WowContent: StackPanel {
        public WowContent(params string[] entries) {
            Orientation = Orientation.Horizontal;

            Button button = new Button();
            button.Content = "Click!";
            Children.Add(button);
            listBox = new ListBox();
            data = new List<string>(entries);
            listBox.ItemsSource = data;
            Children.Add(listBox);
        }

        ListBox listBox;
        List<string> data;
    }

This class derives from a WPF StackPanel, which is one of the container classes. In this case, the controls inside the StackPanel are just “listed”, one behind the other. The extended StackPanel I created contains a button and a ListBox, which in turn is bound to a list of strings.

Now I wanted to initialize the main ListBox on the form with a list of WowContent instances. I created the following method for this:

        public void BindStuff() {
            List<WowContent> list = new List<WowContent>();
            list.Add(new WowContent("Hi", "there"));
            list.Add (new WowContent());
            list.Add (new WowContent("Another", "entry", "with", "more", "text"));
            listBox1.ItemsSource = list;
        }

My first try was to call this method in the window’s constructor, after the call to InitializeControl. But I found that this is not possible for some reason, it always results in an exception thrown from the Application.Run method: Error at element '' in markup file 'Window2.xaml' : Exception has been thrown by the target of an invocation. I guess this has something to do with the initialization process of XAML windows.

I created this method instead, which made things work:

        protected override void OnInitialized(EventArgs e) {
            base.OnInitialized(e);

            BindStuff();
        }

The result of all this, magically, looks like this:

Contentcontrols

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s