The Missing .NET #3: An AutoComplete TextBox in WPF, Part 4 – WPF Flourishes

The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a new series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that should be in the framework but isn’t.


Well, we’re getting close. Part 1 showed that the standard controls in WPF were all you needed to make autocomplete happen. Part 2 started us on the road to packaging it up into a reusable component; Part 3 went neck deep into advanced WPF territory to finish the hard part of our implementation. In this final segment, I’ll cover some neat features of WPF that we can take advantage of to make our AutoComplete TextBox even better.

There is one more thing to discuss: improvements over the Win32 implementation. The code has a little more in it than what I’ve shown. When creating this, I based it on the ComboBox in the Windows Run dialog. What’s the point of doing this in WPF if we don’t take advantage of the new platform? I touched on Templates earlier when I replaced the TextBox template with my own in Part 3. The ListBox (more accurately, the ItemsControl) allows us to template the UI for our data objects with DataTemplates. What if we exposed that so we could change the look of the autocomplete list? Say we wanted to add an image for each item, as well as text.

Also, what if I wanted to index on more than one property? Currently, my implementation works on the ToString() method for each object, keeping the instances in the list that correspond to what’s typed in the TextBox. Wouldn’t it be cool if we could arbitrarily choose the properties to index on? Then we could get the same behaviour as the Outlook addressee textboxes in the New Mail Window.

I’ll deal with first one, um, first, since it’s the easiest: just expose a DependencyProperty or another Attached property of type DataTemplate. In the PropertyChanged event handler, assign it to the ListBox.ItemTemplate property which you can see in the code.

The second is just a matter of adding a new Dependency Property and changing the CollectionViewSource.Filter event handler like so:

private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
   AutoCompleteFilterPathCollection filterPaths = GetAutoCompleteFilterProperty();
   if (filterPaths != null)
   {
      Type t = e.Item.GetType();
      foreach (string autoCompleteProperty in filterPaths)
      {
         PropertyInfo info = t.GetProperty(autoCompleteProperty);
         object value = info.GetValue(e.Item, null);
         if (TextBoxStartsWith(value))
         {
            e.Accepted = true;
            return;
         }
      }
      e.Accepted = false;
   }
   else
   {
      e.Accepted = TextBoxStartsWith(e.Item);
   }
}

where AutoCompleteFilterPathCollection is a custom Collection<string> class with a TypeConverter applied so that we can write the list of properties in a property attribute as a comma-separated list in XAML thusly:

<TextBox ac:AutoComplete.FilterPath="LastName,Email"
         ac:AutoComplete.Source="{Binding Source={StaticResource people}}" 
         Name="textBox2"></TextBox>

Then we can get an autocomplete textbox that behaves similar to the Outlook To address bar, that indexes on Name and Email. Easy.

API Design Aside: Now we have three Dependency Properties; the client XAML is looking a little cluttered. At this point I may want to make my own AutoComplete object and have one attached DependencyProperty of that type that you set on the TextBox. This has the advantage of enabling sharing AutoComplete data across many controls. But, on the other hand, that design sacrifices the ease of use. There are a couple of ways to present this to the developer, now, is my point. I’ll leave that as an exercise for the reader.

The final thing I wanted to do was show how simple it is to enable this to work on ComboBoxes. It requires just a quick refactoring to parameterize a few things when we set the control in the AutoComplete instance, as shown in Part 3, which I reproduce here:

private static void OnSourcePropertyChanged(DependencyObject d, 
                                    DependencyPropertyChangedEventArgs e)
{
   AutoComplete ac = new AutoComplete();
   ac.TextBox = (Control)d;
   ac.ViewSource.Source = e.NewValue;
   d.SetValue(AutoCompleteInstancePropertyKey, ac);
}

internal Control TextBox
 {
    set 
    {
       control = value;
       Style s = (Style)this["autoCompleteTextBoxStyle"];
       viewSource = (CollectionViewSource)control.GetViewSource(s);
       viewSource.Filter += CollectionViewSource_Filter;
       value.SetValue(Control.StyleProperty, this["autoCompleteTextBoxStyle"]);
       value.ApplyTemplate();
       autoCompletePopup = (Popup) value.Template.FindName("autoCompletePopup", value);
       value.AddHandler(System.Windows.Controls.TextBox.TextChangedEvent, 
                                new TextChangedEventHandler(textBox1_TextChanged));
       value.LostFocus += textBox1_LostFocus;
       value.PreviewKeyUp += textBox1_PreviewKeyUp;
    }
 }

As you see, I’ve typed the TextBox property to Control so I can set this to a ComboBox as well, but there are a few things we’ll have to move into a custom type. For starters, the Style for ComboBox is different than TextBox, so we’ll have to repeat the steps that we took when extracting the TextBox style, namely (deep breath) open XamlPadX, extract the ComboBox style, put it in my ResourceDictionary, add the ListBox control to the visual tree and add the CollectionViewSource to the Style’s Resources.

Once we’ve done that, we want to change the TextBox property above. The two things that we need to change are the hard-coded resource key, "autoCompleteTextBoxStyle"; and we have to parameterize where the CollectionViewSource comes from which you can tell from the two Styles. You can see the code for all the details, but the TextBox property (which I should rename) now looks like this:

internal Control TextBox
{
   set 
   {
      control = AutoCompleteControl.Create(value);
      Style s = (Style)this[control.StyleKey];
      viewSource = control.GetViewSource(s);
      viewSource.Filter += CollectionViewSource_Filter;
      value.SetValue(Control.StyleProperty, this[control.StyleKey]);
      value.ApplyTemplate();
      autoCompletePopup = (Popup) value.Template.FindName("autoCompletePopup", value);
      value.AddHandler(System.Windows.Controls.TextBox.TextChangedEvent, 
                                    new TextChangedEventHandler(textBox1_TextChanged));
      value.LostFocus += textBox1_LostFocus;
      value.PreviewKeyUp += textBox1_PreviewKeyUp;
   }
}

My parameterization class is slightly more complicated because of other methods in the AutoComplete class. One thing that is truly magic in this case is setting the TextChangedEvent handler on the ComboBox. Notice that I’m adding a handler to the TextBox.TextChangedEvent. Look at the ComboBox API, and you won’t see a TextChangedEvent! Yet it works just as you’d expect it to. That’s some magic that I don’t understand. Magic or no, the ease with which we’ve introduced autocomplete for ComboBox can’t go unnoticed. Note also that the ComboBox’s own Items are unaffected by autocomplete (you can set them both to the same data source, though).

Phew! As you’ve seen over this massive edition of the Missing .NET, creating behaviour in WPF needn’t involve custom controls, but it does require a solid understanding of the underlying design concepts of WPF. There is definitely more we can do with this AutoComplete stuff as well. Hopefully, I’ve shown you the start of what’s possible.

The Missing .NET #3: An AutoComplete TextBox in WPF, Part 3 – Control Templates

The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a new series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that should be in the framework but isn’t.


In Part 1, I roughed in my AutoComplete Textbox with standard WPF controls. In Part 2, I decided to deploy this as an attached property but ran into some trouble with inserting my WPF controls into an control’s visual tree. In this part below, I show how I solved the visual tree problem using ControlTemplates.

Charles Petzold has an example of creating a ControlTemplate in code in his Applications = Code + Markup: A Guide to the Microsoft Windows Presentation Foundation (Pro – Developer). It involves creating a nested set of factories: truly painful. So I quickly abandoned it as a tenable method for replacing the ControlTemplate. That meant a XAML solution for writing out the ControlTemplate.

But a XAML solution creates its own problems, especially since I’ll have to access the objects created by the template in code (the CollectionViewSource for one, and another control that has yet to make its appearance in this saga). Again, my ignorance with these advanced WPF concepts forced a solution that may not be the best one: I decided to use a ResourceDictionary.

The ResourceDictionary is damn near ubiquitous in WPF. Both FrameworkElement and FrameworkContentElement have a Resources property that allow you to store arbitrary .NET objects, so every control has a Resources property. This is often where styles or data sources are stored, but it can be any .NET object. You can also create your own ResourceDictionary as a standalone class, typically as App-level resources or as a Theme. The cool thing about ResourceDictionary, if you associate it with a class is that you can combine XAML and code like you do in a Window class. Since I’ve already got my AutoComplete class started, what I did was add a ResourceDictionary to my project and used the Class attribute (in the XAML namespace) to associate it with my AutoComplete class.

Now I have to write my own ControlTemplate for TextBox that will allow me to stick my ListBox to it. I could start from scratch, but then I’d have to recreate all the behaviour of the TextBox, including borders, colours, mouse over behaviour, etc, and I want to get this done. I have XamlPadX, so why not pull out the default TextBox style and manipulate it? It’s got the standard look and everything. So that’s what I do: stick that in my ResourceDictionary and change the template to add the ListBox, like this:

<ControlTemplate TargetType="TextBoxBase">
    <StackPanel>
        <mwt:ListBoxChrome Name="Bd">
            <ScrollViewer Name="PART_ContentHost" />
        </mwt:ListBoxChrome>
        <Popup x:Name="autoCompletePopup" 
               Placement="Bottom" 
               PlacementTarget="{Binding ElementName=Bd}"
               StaysOpen="False"
               AllowsTransparency="True">
            <ListBox x:Name="AutoCompleteListBox"
                     ItemsSource="{Binding Source={StaticResource viewSource}}" />
        </Popup>
    </StackPanel>
    <ControlTemplate.Triggers ...>
</ControlTemplate>

This is the relevant piece where I set the Template property on the Control. You can view the entire ResourceDictionary here (Or Download the source). It differs from the standard one in a few places: 1) The StackPanel that contains the TextBox and 2) the Popup containing the ListBox with the name AutoCompleteListBox. Why use the Popup? I’ll leave that as an exercise for the reader. πŸ™‚ Note the ListBoxChrome element with the ScrollViewer inside it. The ListBoxChrome element resides in the Presenation.Aero assembly. Not listed is the Style.Resources property where I add the CollectionViewSource with the Filter event handled.

The methods for handling the CollectionViewSource.Filter and the TextBox.TextChanged events remain the same, I just have to move them to the AutoComplete class and hook them up to the TextBox when it’s passed to me in the OnSourcePropertyChanged event handler when my attached property changes, about which I mentioned earlier in Part 2. I did this with a private, read-only DependencyProperty that creates an AutoComplete instance to associate with the TextBox as the code below shows:

private static void OnSourcePropertyChanged(DependencyObject d, 
                                    DependencyPropertyChangedEventArgs e)
{
   AutoComplete ac = new AutoComplete();
   ac.TextBox = (Control)d;
   ac.ViewSource.Source = e.NewValue;
   d.SetValue(AutoCompleteInstancePropertyKey, ac);
}

internal Control TextBox
 {
    set 
    {
       control = value;
       Style s = (Style)this["autoCompleteTextBoxStyle"];
       viewSource = (CollectionViewSource)control.GetViewSource(s);
       viewSource.Filter += CollectionViewSource_Filter;
       value.SetValue(Control.StyleProperty, this["autoCompleteTextBoxStyle"]);
       value.ApplyTemplate();
       autoCompletePopup = (Popup) value.Template.FindName("autoCompletePopup", value);
       value.AddHandler(System.Windows.Controls.TextBox.TextChangedEvent, 
                                new TextChangedEventHandler(textBox1_TextChanged));
       value.LostFocus += textBox1_LostFocus;
       value.PreviewKeyUp += textBox1_PreviewKeyUp;
    }
 }

In the AutoComplete.TextBox setter is where I set the TextBox’s Style to my style and grab my CollectionViewSource and a reference to the Popup.

That’s essentially it. We’ve created an autocomplete TextBox in WPF! But what’s the point when you don’t take advantage of the new tech? Next time I’ll explain a couple of improvements we can make to the AutoComplete TextBox and show that adding support from ComboBox is really straightforward.

The Missing .NET #3: An AutoComplete TextBox in WPF, Part 2 – Making it reusable

The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a new series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that should be in the framework but isn’t.


In Part 1 last time, I started creating an AutoComplete TextBox in WPF using only the controls given to us by Microsoft and the concepts of WPF. I showed how you can quickly get the meat of the problem solved using a custom ICollectionView that filters based on the text in the TextBox. In this part, I’ll discuss what’s needed to make it reusable.

Reusa-ma-bility

Alright. So we have a pretty good idea of what’s required, how are we going to package this up to be reused elsewhere? Right now, my implementation is good for the window that I implemented it in. I could make a new control, and add this logic to it, but I already said at the outset that that wasn’t going to happen.

What I decided to use was an attached property. The guidance on using Attached Properties was what finally sold me. See, I also want to use this on ComboBoxes eventually, but ComboBox and TextBox, which both have a Text property, don’t have a common ancestor past Control. One of the scenarios that the docs describe, but don’t provide an example of is wanting to have a property on different, unrelated parts of the control hierarchy. I don’t know why Microsoft can’t provide an example, but I can: the TextSearch class defines two attached properties with this scenario in mind. (Seriously, the docs for .NET 1.1 were awesome. What the hell happened to msdn?)

OK, so I’m going to use an attached property. What that looks like is the following:

public sealed partial class AutoComplete
{
  public static readonly DependencyProperty SourceProperty;

  static AutoComplete()
  {
     SourceProperty = DependencyProperty.RegisterAttached("Source",
                        typeof (object), typeof (AutoComplete),
                        new FrameworkPropertyMetadata(null,OnSourcePropertyChanged));     
  }

  public static object GetSource(DependencyObject o)
  {
     return o.GetValue(SourceProperty);
  }

  public static void SetSource(DependencyObject o, object value)
  {
     o.SetValue(SourceProperty, value);
  }
}

This is pretty standard stuff that you can find in the docs. The one piece that’s missing in that snippet is the event handler method OnSourcePropertyChanged that’s declared in the call to DependencyProperty.RegisterAttached. I’ll get to that in Part 3.

What this allows is I can use this on any DependencyObject, like so:

<StackPanel >
    <TextBox Name="textBox1" 
         local:AutoComplete.Source="{Binding Source={StaticResource people}}"
         VerticalAlignment="Top" 
         HorizontalAlignment="Stretch" 
         TextChanged="textBox1_TextChanged" />    
</StackPanel>

where local is my declared namespace for my assembly (Visual Studio does this for you).

Awesome. I can put this on a ComboBox now, or anything else that allows text input. Now we have an auto-completing TextBox. Your welcome.

Yes, you have a question? There’s some parts missing? Like what? Oh, right the ListBox, it’s not there anymore.

A Look-less Autocomplete TextBox

I’ve already solved the hard problem of getting the List to show up when the user types something; I just need to make that work on any TextBox. The trouble is, I’m manipulating the visual tree, which, to my belated discovery, is really hard to do in code after the TextBox is created. Turns what I want to do is create a ControlTemplate that contains my ListBox and replace the TextBox’s Template with my own.

One of the key concepts in WPF is what the folks at Microsoft call "look-less controls". The canonical example is the button. There are a bajillion — at my last count — samples of making buttons look different than the standard Windows button in WPF. They do this by manipulating either the Content property of the button, or its ControlTemplate. Either way, you still have a button that can be clicked, but you’ve changed the look of the button. All WPF controls act like this, more or less, to some degree: I was asked to make a ListBox turn into a TabControl and that’s non-trivial, nigh impossible, even though they are related in the control hierarchy.

Another example is the ComboBox. I mentioned in the first edition of The Missing .NET that the traditional Win32 ComboBox is made up of three controls: a button, a listbox, and a textbox. Well, so is the WPF ComboBox! Only, the WPF is a little more explicit about it, and more flexible. The place where this is done is the Control.Template dependency property; it’s a dependency property hanging off Control that lets you set the visual tree of your control. The standard controls manipulate this property in their default Style. One tool you want in your WPF developer toolbox is something that will deconstruct the default Styles of the standard controls; I use XamlpadX. Bombing around the styles should give you an understanding of how they work.

Deconstructing the ComboBox in XamlPadX, sure enough, we see the TextBox, the ToggleButton and the ItemsControl, of which ListBox is a descendent.

We’re getting into some seriously advanced, yet fundamental WPF stuff here, which is a little beyond the scope of this blog post, at least if I wanted to finish quickly. If you’re interested in learning about Templates and Styles, Google can be big help; if you’d prefer to learn offline, then any of the WPF books will be quite helpful. Start small, and work your way up. Learning how templates and styles work is definitely worth the effort.

So the only way to stick my ListBox into the visual tree is to replace the ControlTemplate of the TextBox.

This is where the internets came up short for me and I went out on my own. I have no idea if my solution is a good idea. It seems to work, and work well, but I don’t know enough about WPF to tell if this will work in every situation. Every solution creates its own problems and I ran into a few while solving this one.

OK, so what did I do?

You’ll have to wait ’til next time. πŸ™‚

The Missing .NET #3: An AutoComplete TextBox in WPF, Part 1 – A rough first draft

The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a new series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that should be in the framework but isn’t.


The more I use WPF, the more I’m impressed and confounded by it. Impressed because it is really well-designed, thoughtful, and quite rich right out of the gate; I’m confounded by the things it’s lacking. I realize they had to ship something sooner than later, but some of the things Microsoft left out seem pretty trivial to implement given what I know about WPF. One of these is an auto-completing TextBox (It was even late to the Windows forms party, but still…). The most famous example is the address ComboBox in the browser. Start typing to see that the computer remembers what you typed previously. Auto-complete is everywhere in the OS, and you can see it on the web in spots too, now: Compose a message in Facebook and you’ll see your contact list drop down and filter out as you type.

I’ve seen suspiciously little from The Google on auto-completing text boxes using WPF. This can lead me to possible two explanations:

  1. Auto-complete is obviously trivial and so everyone just implements it in two lines in their own projects, and I’m a complete idiot for searching The Google in the first place; or
  2. No one is using WPF for anything  usable with normal-looking controls — they just want the 3-D light show with lasers.

In either case, I figure I’ll just keep writing this post. There are definitely more complete idiots out there, if 1 is the case. If 2 is the case, I just have to wait a few months or years for this post to be relevant.

When I set out, I had a goal to make a TextBox with auto-complete, I was going to use WPF’s idioms to the fullest, meaning no custom controls or inheriting from TextBox to add what I want. Also, I detest making custom controls because they are so hard to maintain and they aren’t just there in the IDE to use, like the default controls; the case would have to be pretty compelling to replace something as fundamental as the text box, and autocomplete ain’t it.

Besides, I think it’ll be a rare thing to create a custom control in WPF, at least a custom control the way a WinForms developer would think about a custom control: there’s just too much you can do with element composition and templates in WPF.

After some digging, I noticed that the bits and pieces of AutoComplete are already there in WPF; all I had to do was stitch them up together in a nice little package. So what I’d like to do is talk about those parts before I explain how I made the control. In the first part, I’ll talk about filtering the list as the user types; you know, the part that gives a textbox its autocomplete-y-ness.

List-Filtering: CollectionViewSource

People like lists in their blog posts I’ve found; so here’s a list: the Best Thing about WPF

  • Data-binding

The end.

You can write an RSS reader in like 100 lines of XAML and zero lines of code, all with data-binding. Representing custom classes is a matter of a moment, creating a DataTemplate for them. Hierarchical data? No problem. XML? No problem. Database? Um, not sure, don’t use ’em, but probably.

WPF was designed with data-driven apps as one of the key scenarios, and it shows. What’s even nicer is that you can get started right away without knowing too much about how databinding works. But dig a little deeper and you can see how well-designed it is.

For instance, the ListBox can represent a list of items and, with DataTemplates, you can customize the look of each item. You can also track the currently selected item and bind other controls to that item. What if you had two ListBoxes, though, both pointing to the same collection, and you wanted one to show a subset of the collection? Could you do that?

Absolutely.

When you bind to a list source WPF wraps the source in an ICollectionView. The ICollectionView manages the currency (the currently selected item) of the list for the ListBox. Each ListBox gets a different ICollectionView instance. If you look at the API for ICollectionView, you’ll see some methods and properties for grouping, sorting, and filtering.

We’re interested in filtering lists! If you want to filter a list, you can create your own ICollectionView through it’s XAML representation, CollectionViewSource; bind it to your source; bind your list box to your CollectionViewSource and then register for the Filter event on the view.

The XAML below provides an example of this.

<Grid Name="grid1">
     <Grid.Resources>
        <ObjectDataProvider x:Key="people" 
                            ObjectType="{x:Type local:People}" 
                            MethodName="GetPeople" />
        <CollectionViewSource x:Key="viewSource" 
                              Source="{StaticResource people}" 
                              Filter="CollectionViewSource_Filter"/>
    </Grid.Resources>
    <ListBox ItemsSource="{Binding Source={StaticResource viewSource}}" />
</Grid>

The CollectionViewSource_Filter event handler is where your filtering code goes. If you hook it up in XAML, you get a nice event with specific event args, but you could also do it in code, in which case, the Filter property is a Predicate<T> delegate. The event deals with each item in the data source at a time.

So where am I going with this ICollectionView thing? Well, if you look at what constitutes an autocomplete textbox in Win32, it’s a just a textbox with a listbox below that shows up when typing happens and filters the items in the list based on what’s typed.

So why not start there in WPF?

Autocomplete TextBox First Draft

My first iteration wasn’t a control or anything more complicated than the XAML below

<StackPanel >
    <TextBox Name="textBox1" 
         VerticalAlignment="Top" 
         HorizontalAlignment="Stretch" 
         TextChanged="textBox1_TextChanged" />
    <ListBox Name="listBox1" 
         Visibility="Hidden"
         ItemsSource="{Binding Source={StaticResource viewSource}}"
         HorizontalAlignment="Stretch" 
         Focusable="False"/>
</StackPanel>

The viewSource in the ListBox.ItemsSource Binding is the same as the previous XAML snippet. In the code behind file, I have the following event handlers:

private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
    CollectionViewSource viewSource = (CollectionViewSource) grid1.FindResource("viewSource");
    this.listBox1.Visibility = this.textBox1.Text != "" 
                                    ? Visibility.Visible : Visibility.Hidden;

    viewSource.View.Refresh();
}

private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
    e.Accepted = e.Item.ToString().StartsWith(textBox1.Text, 
                        StringComparison.CurrentCultureIgnoreCase);
}

When the text changes, I ask the viewSource’s ICollectionView to Refresh. This in turn raises the Filter event that determines if each item in the list should still be there based on the text in the TextBox. Cool, eh? That’s all that’s needed

Run it with your favourite IDE with some suitable data, start typing and you have the basic concept of an autocompleting TextBox. That was easy.

Next time: we package this up in a reusable way.

The Missing .NET #2: Collection<T> AddRange()

The .NET framework is huge, but not so huge that it does everything for everyone; there are things that they in Redmond miss or don’t do for whatever reason but is still generally applicable to many developers. So, dear reader, I present to you a new series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer. It could be a useful class, a technique, a good practice or documentation that should be in the framework but isn’t.


One of the sad, unfortunate truths about Windows Forms development is that you don’t get to use it. That’s right: LINQ, WCF, WPF, maybe even generics, iterators, and the awesomest Winforms control ever, ToolStrip. All of it may be off limits to you, dear WinForms developer, because real people don’t know what the .NET framework is, and don’t care that your app depends on it; nor are they willing to sit through a 24 MB download, apparently. That last one seems really weird to me, a broadband user for 8 years, but, the numbers don’t lie: your users don’t have the framework on their computers. Now, there is hope with Vista β€” if Microsoft could just advertise it better so everyone’s perception of it isn’t that it sucks balls; it has .NET 3.0 installed by default, but .NET 3.5? Still a separate download.

That never-ending march forward of the .NET framework was a little disheartening to me: I felt the pressure to constantly stay on top of new stuff (and, oh, man is there ever a lot of new stuff since .NET 2.0: WPF, WCF, Workflow, LINQ, C# 3.0, not to mention all libraries the fast-moving ASP.NET team is pumping out), but there was a huge disconnect when I’d have to toil daily in the doldrums of .NET 1.1. So I unplugged, stopped blogging, just gave up on keeping up. “What was the point?” I’d ask.

I don’t really know what has spurred me on lately, but now I’m starting to get that passion back. So, I’ve been looking into some of the new stuff. Rather than jump right in with LINQ, I figured I’d start with some of the language improvements in C# 3.0, and in this post I’m going to go through an example of one of the easiest to grok, and one of the more powerful ones: extension methods.

One of the greatest classes in .NET 2.0 is List<T>. It is seriously awesome and, I assume, quite popular. What makes it so useful isn’t its strongly-typed nature, but the methods it exposes to access the strongly-typed collection, like Find(Predicate<T> match) and Foreach(Action<T> action). We’ve all written methods like this for arrays and ArrayList:

MyType Find(List<MyType> list)
{
    foreach (MyType t in list)
    {
        if (t.MyInt == 42)
            return t;
    }
    return null;
}

to find an element in the list. Or, something like this to perform an operation on every element in the list:

void Find(List<MyType> list)
{
    foreach (MyType t in list)
    {
        DoSomething(t);
    }
}

They’re both standard .NET 1.1 idioms. They clutter your code, it’s boilerplate, but you didn’t really have a choice. With List<T>, you can do these operations more succinctly:

MyType myType = list.Find(delegate(MyType t) { return t.MyInt == 42; });

and

list.ForEach(delegate(MyType t) { DoSomething(t); };

Beautiful!

So, why don’t we see List<T> being used everywhere? Well, the framework design guidelines say you shouldn’t publicly expose List<T>, that you should use Collection<T> instead. Krzysztof Cwalina, co-author of the excellent .NET Framework Design Guidelines, says why here. He has a point: you don’t want to expose methods unnecessarily, but those two above (Find(Predicate) and ForEach(Action) and let’s not forget AddRange()) are so useful. And it’s not unreasonable to want to find an element in a Collection<T> or do something to each element in the collection.

To do this is in the old-fashioned .NET 2.0 days, every time you wanted these methods, you’d have to create a custom collection and implement the method: Yuck. We’re also assuming that you control the collection class; perhaps you’re using a third-party component that exposes a Collection<T>, in which case, you’ll probably have to revert back to the .NET 1.1 idiom.

Now, in the latest and greatest .NET 3.5, you can write those methods once and use them wherever Collection<T> is exposed with extension methods! These things are a great way to add functionality that got missed to classes you don’t own. Consider this convoluted way of printing “Hello world”:

static void Main(string[] args)
{
    MyType[] array = {
                       new MyType{MyString="Hello", MyInt=42},
                       new MyType{MyString="World", MyInt=84},
                       new MyType{MyString="Jason", MyInt=92}
                     };

    List<MyType> list = new List<MyType>();
    list.AddRange(array);

    MyType myType = list.Find(delegate(MyType t) { return t.MyInt == 42; });

    Console.Write(myType.MyString);

    Console.Write(", ");

    Collection<MyType> collection = new Collection<MyType>();
    collection.AddRange(array);

    myType = collection.Find(delegate(MyType t) { return t.MyInt == 84; });
    Console.WriteLine(myType.MyString);
    Console.ReadLine();
}

class MyType
{
    public string MyString { get; set; }
    public int MyInt { get; set; }
}

Note the collection class to print the world half. It’s got the AddRange() and the Find() method that List<T> does, which isn’t in its API. Those are extension methods.

The code that enables that is thus:

public static void AddRange<T>(this Collection<T> collection, IEnumerable<T> values)
{
    foreach (var item in values)
    {
        collection.Add(item);
    }
}

public static T Find<T>(this Collection<T> collection, Predicate<T> predicate)
{
    foreach (var item in collection)
    {
        if (predicate(item))
            return item;
    }
    return default(T);
}

The magic happens with the ‘this’ keyword in the method signature. Extension methods are truly cool: very powerful, and with great power, comes great responsibility. You should use it wisely.

Download the extension methods for Collection<T> here.