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.

It’s in the Framework, Dummy!

No one who knows me would describe me as humble. I guess if everyone thinks I’m not humble, maybe I’m not, I don’t know.

One thing I do approach with humility is my ability as a programmer. It took some concentration to “get” the fancy algorithms in university; I’d always try to solve the problem with brute force and “move up” as needed. I still do. I don’t think that’s wrong, either; worse is better. I practice TDD when I’m writing something that matters. I also remind myself that the first question isn’t “How do I do this?”, but “How has everyone done this before?”

Judging by the code I’ve read from my colleagues and online, a lot of people don’t share this perspective. They blindly assume that they have to solve every programming problem that crops up and that they can solve every problem better than everyone else who programmed before them ever. I doubt most programmers think that way but the results in the code could support that notion.

There are lots and lots of developers out there, all with a lot of the same types of problems to solve; some times – I’d say rarely – you need to revisit the problem yourself, but chances are, you can just use what other people have done. You can see this trend with the technologies and languages in use today verses, say 50 years ago. There’s a definite progression from machine code, to assembly, to procedural, to OO, to runtimes and frameworks. The code in J2EE or .NET or Python or Rails embodies thousands of little problems already solved for you.

To be a good programmer, therefore, one must get pretty good at searching the docs of your particular framework; learn to read source code; and always remember that someone already solved your problem. Even Isaac Newton didn’t do it alone. Being a humble programmer allows you to progress passed solved problems.

Before I end this post, a few examples from .NET:

  • File paths are something everyone has to deal with if you’re writing a desktop app. You have a directory path and a file name and you need to concatenate the two to work with the file on disk. You could write

    string path = dirPath + fileName;

    but that assumes that dirPath ends with ‘\’ on Windows (let’s not consider Mono right now). So, now we have to check to see if dirPath ends with ‘\’. Or, you could just use Path.Combine! It’s been in the framework since 1.0! That Path class has all kinds of good stuff on it. Use it! Stop reinventing the wheel.

  • Here’s one that I didn’t know about until a few weeks ago: Title case for a string involves capitalizing the first letter in every word. I’ll admit I’ve written functions in production scenarios, but I didn’t have to, and now I never will again because of the TextInfo.ToTitleCase method. TextInfo hangs off of CultureInfo, and it’s in the System.Globalization. I bet your naive implementation wouldn’t have considered internationalization. Microsoft has to deal with that a lot, they’re probably really good at it. Solve your problem, not one that Microsoft already has; it’s in the framework!

Here’s a rule I usually follow: if there is a requirement to do something, always, always, always, check the Google, or your favourite search engine to see what others have done.

Have you got any methods or classes that are in the framework but nobody uses?

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.

The Missing .NET #1: Cue Banners in Windows Forms (EM_SETCUEBANNER, Text Prompt)

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, hopefully weekly, series of posts on stuff I find missing in .NET, typically where even the Google fails to find the answer.


One of the subtle UI improvements we’ve seen over the past few windows versions, and on the web, is the cue banner, or text prompt. They are hardly groundbreaking — putting them in your app probably won’t win you awards, but they do serve to make your applications that much more polished and usable.

They are used increasingly more often now that Vista has come out, which solved a few problems that I’ll address later. You can see them used in the popular browsers IE 7 and Firefox in the search boxes, denoting the search engine of choice for the user in a subtle grey tone. Click inside those textboxes, however, and the text disappears. That’s all a cue banner is, that grey text, informing the user what exactly she is supposed to use the text control for.

Cue banners work great in places where a formatted string is required, say an email address or a URL or a phone number. Instead of cluttering up the window with tons of labels, explaining examples or ranges of valid values, you can put those in a cue banner. It makes the UI a tad more elegant and self-explanatory.

Firefox and IE 7 Search boxes displaying a cue banner of the default search engine.These aren’t exactly missing on the web though. Search for ‘cue banner’ in your favourite search engine and you’ll find all kinds of examples, but none of them cover everything, or in a way that seems satisfactory to me. An example of an inherited textbox for Winforms can be found at this Channel 9 post. Daniel Moth has a version that works for the .NET Compact Framework as well as the main framework and decided to eschew the OS support and do it completely in managed code. He’s braver than I; I’d prefer to have MS do all that work and then use it.

[ad]

The Code

Download the code I’ve covered in this article.

OK, so now we know what a cue banner is, how do we include them in our apps?

The first thing to remember is that this is all done in Win32 which requires P/Invoke. All we’re doing is sending a Win32 message on the window handle of the control. That’s pretty straightforward boilerplate code that you can find on pinvoke.net. The one thing you may have to search for is the value of the msg parameter, EM_SETCUEBANNER, but I got you covered.

private const int EM_SETCUEBANNER = 0x1501;
private const int EM_GETCUEBANNER = 0x1502;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SendMessage(IntPtr hWnd, int msg,
int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

You can certainly do what buddy did on Channel 9: inherit from TextBox, add the required property, call the P/Invoke method and call it a day but then you’d be missing something important. Cue banners can be placed on edit controls, not just textboxes. The unfortunate thing about WinForms is that it’s essentially a facade over Win32. It does a very good job, make no mistake, but if you push it in the wrong place you end up exposing what’s underneath. And what’s underneath is Win32 which identifies all controls with its corresponding HWND. As a consequence, Windows Forms has a pretty flat hierarchy (cf. with WPF which was designed when OO was the prevailing wisdom; a very deep hierarch). Therefore, if you want to display a cue banner in a ComboBox or a RichTextBox, which the OS allows, then you’d have to subclass ComboBox and RichTextBox. Well, that’s just not scalable or portable. You’d always have to import your own controls and use those in your projects. I’ve found that most custom controls suck when used in the designer, so who wants to use them?

Besides, all the info that’s required to make cue banners work is already there in the control! So let’s use it instead. It’s not ideal, but I prefer to keep it all in a static class. We only need to use the Handle property which Control owns and we should also parameterize the actual cue banner text so we write the following method to set cue banners:

public static void SetCueText(Control control, string text)
{
   SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
}

Easy or what? So now drop a text box on a form. Call SetCueText in the form constructor for the text box and you’re set. Now drop a ComboBox and do the same for it. Hit F5 and prepare to bask in the glo… Hey! Why isn’t the cue banner set in the ComboBox? This is where other articles completely fall down on this stuff. You see, the ComboBox is actually made up of three controls: a text box and a list box and a button; think of it as a really old and ubiquitous UserControl. ComboBox.Handle is the handle for the combined control, not the text control, so we’ll need a way to get its handle. For that, we need more P/Invoke:

[DllImport("user32.dll")]
private static extern bool GetComboBoxInfo(IntPtr hwnd, ref COMBOBOXINFO pcbi);

[StructLayout(LayoutKind.Sequential)]
private struct COMBOBOXINFO
{
   public int cbSize;
   public RECT rcItem;
   public RECT rcButton;
   public IntPtr stateButton;
   public IntPtr hwndCombo;
   public IntPtr hwndItem;
   public IntPtr hwndList;
}

[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
   public int left;
   public int top;
   public int right;
   public int bottom;
}

OK, now we’re ready to add some more logic to the SetCueText method above:

public static void SetCueText(Control control, string text)
{
   if (control is ComboBox)
   {
      COMBOBOXINFO info = GetComboBoxInfo(control);
      SendMessage(info.hwndItem, EM_SETCUEBANNER, 0, text);
   }
   else
    {
        SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
    }
}

private static COMBOBOXINFO GetComboBoxInfo(Control control)
{
   COMBOBOXINFO info = new COMBOBOXINFO();
   //a combobox is made up of three controls, a button, a list and textbox;
    //we want the textbox
    info.cbSize = Marshal.SizeOf(info);
    GetComboBoxInfo(control.Handle, ref info);
   return info;
}

Hit F5 on your test app again, and voila: cue banner on ComboBox!

Notes

This only works on Windows XP and Vista.

On Windows XP, this conflicts with the East Asian Language packs, so if you have them installed, cue banners won’t work. Vista fixes this.

On Windows Vista, they’ve added a use for wParam parameter in the SendMessage() call. If you set it to TRUE, then the cue banner text will remain when the control gets focus.

I’ve found no use for the corresponding GetCueText, but if you want it, make sure you use a StringBuilder as the last parameter in SendMessage(), which requires another declaration of SendMessage.

Important: If you’ve done everything above and you still don’t see the wonderful cue banner text, check to see that before you call Application.Run(), you call Application.EnableVisualStyles(). That has to be called else cue banner won’t show up no matter what OS your are using.

Exercises

A few exercises for the reader:

  • SetCueText() is an ideal candidate for an extension method, if you’re allowed to use .NET 3.5. It’ll make the code just a little more readable. I’ll let you figure out how to do that.
  • There is a way you can have this on the designer. Just provide a component that implements IExtenderProvider to be dropped on the design surface.

A Fast Equals() – Remember to Always Measure

For years, I thought I had the one, true answer to Equals() from seeing something in some MSDN article a long, long time ago – like 2002 or 2003. Or maybe it was on Brad’s or Krystof’s blog and freaked out because I wasn’t doing it. Whatever the case, I’d make sure to point out the “proper” way to do Equals() to my colleagues. And I always made sure that I’d do it the same way for all my types that needed Equals overridden. Then I decided to measure it.

So, what did I think the best way to do Equals was? Consider this type:

    class MyClass
    {
        public int NumberValue;
        public string StringValue;
    }

If I were to write Equals the way I used to, I would write it the following way:

        public override bool Equals(object obj)
        {
            if (obj == null || obj.GetType() != GetType())
                return false;
            if (ReferenceEquals(obj, this))
                return true;
            MyClass other = (MyClass) obj;
            return other.NumberValue == this.NumberValue &&
                   other.StringValue == this.StringValue;
        }

Note that the above implementation suffices the conditions for a robust Equals. The important part of Equals() is that it covers all the following cases:

  • it returns false if obj is null;
  • it returns false if obj is not the same type as this;
  • it returns true if the references are the same;
  • it doesn’t throw Exceptions; and
  • it doesn’t allocate memory.

The actual evaluation of equality is per class and changes for every class. In the example above, the equality evaluation is the return statement comparing the string and the int of both MyClass instances. The above list of conditions is boilerplate and should be met for every Equals method you write.

So what’s the problem? My Equals method does everything in that list just fine. Right?

Two of the conditions are trivial to meet: the check for null and check for reference equality. The hard one to meet, perhaps because are there so many ways of doing it, is checking for the right type. In my method above, I check the type by comparing GetType() of both obj and this. If they aren’t equal, I return false. That turns out to be 5 times slower than the other two ways of doing it: the is and as operator.

The .NET Design Guidelines recommend you use the as operator to check the type rather than the is operator because it does the type check and assignment all at once. So let’s re-write the Equals method to use the as operator:

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, this))
                return true;
            MyClass other = obj as MyClass;
            if (other != null)
              return other.NumberValue == this.NumberValue &&
                     other.StringValue == this.StringValue;
            return false;
        }

This method meets all the conditions of a good Equals, but has the advantage of being pretty fast, faster than the first way I did it anyway. Since the gurus in Redmond recommend the as operator, you’d think that it’s the fastest: wrong! Check it:

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(obj, this))
                return true;
            if (obj is MyClass)
            {
                MyClass other = (MyClass) obj;
                return other.NumberValue == this.NumberValue &&
                       other.StringValue == this.StringValue;
            }
            return false;
        }

Equals with the is operator and then casting is actually the fastest of them all (by about 10% when compared to the as operator). All three methods meet the conditions of a good Equals method, but the least intuitive one – to me at least – has the advantage of being the fastest. And it’s cheap speed, too: you get it just by implementing Equals the same way everytime for every type. You generally want Equals to be pretty fast because it will show up a lot in loops and operations on collections.

My point? Always measure – don’t assume you’re doing things right. It’s good to go back and think about the fundamentals once in a while.