Kiwi Ingenuity

Thoughts from another perspective

A WPF Text Box Autocomplete Extender using Reactive Extensions

My objective is to design an WPF auto complete text box that I can use to make calls to a web service. I was aware of the Reactive Extensions technology, but have never up to now had an opportunity to deploy an RX solution


Reactive Extensions

Reactive Extensions appealed to me because the amount of code required to set up an observe / search routine is minimal. The syntax is very powerful.  

As an introduction to RX I worked through the example published by PeteGoo called Building an Auto Complete control with Reactive Extensions (Rx). When I had completed the exercise I had a code snippet that showed me how to create a synchronous (or asynchronous) call to a web service, which catered for:

· Throttling (idle periods before searching)

· Merging multiple event streams

· Removing duplicate consecutive events

· Cancelling previous searches

All the above attributes were important features for my auto complete text box.

I highly recommend that before you proceed any further that you read and understand Pete Goo’s example.


Popup Control

What was missing from Pete Goo’s example was a Popup that would display each time text was entered into the textbox. I also wanted to have a reusable user control which would contain the repetitive code base.

The solution that appealed was the creation of Ioan Lazarciuc called Auto Complete for Textboxes in WPF. Ioan was inspired by the AutoCompleteTextBoxAutoCompleteExtender in the ASP.NET Ajax control toolkit and also because his solution requires minimum intervention of existing WPF code.

What Ioan’s solution lacked was the ability to do an asynchronous search while the operator keyed the search phrase. PeteGoo’s solution has taken care of this for us, so we have all the code snippets required to build an autocomplete textbox. All we have to do now is put it all together.

The attached solution is my suggestion how to implement an auto complete textbox in WPF that allows asynchronous search capabilities to a web service. I will not be going over what my two contributors have already scripted, so you may want to study their solutions first before proceeding.



My extender is a WPF user control that handles all the background tasks when the operator keys a search into the selected textbox.

To call my extender is very simple.

   <!--Set up a ObjectDataProvider which contains the data we 
   intend to lookup-->
   <ObjectDataProvider ObjectType="{x:Type local:MyDataProvider}"
                       x:Key="doSearch" >
                <x:Static Member="system:String.Empty" />
    <Label Content="Type in Search Phrase:" />
    <TextBox x:Name="textBox" />
    <ac:TextBoxAutoCompleteExtender x:Name="autoTxtBox"
                                    TargetControl="{Binding ElementName=textBox}"
                                    SearchDataProvider="{Binding Source={StaticResource doSearch}, 
				                                    BindsDirectlyToSource=True}" />

And that it!

Execute the application and the popup will display suggestions as you are typing characters into you TextBox.  You can use your keyboard or the mouse to select the correct phrase.

You can download my source code and example here.

Drag and drop solution for your WPF application

Last week I needed to include drag / drop capabilities on a Tree View on a WPF application.


As usual I started cutting the code required to give me the required capabilities. After some time it became obvious that Drag Drop functionality in the MVVM world was more complicated than what I first thought. All my code was residing in code behind instead of the view model?


I took some time out to search the internet to find out how others have resolved this issue. There are many solutions to found.


I did however discover one solution that I thought was very well done. Steven Kirk (back in 2009) has created a library that he calls gong-wpf-dragdrop.


His web site says:


The GongSolutions.Wpf.DragDrop library is a drag'n'drop framework for WPF. It has the following features:

  • Works with MVVM : the logic for the drag and drop can be placed in a ViewModel. No code needs to be placed in codebehind, instead attached properties are used to bind to a drag handler/drop handler in a ViewModel.
  • Works with multiple selections.
  • Can drag data within the same control to re-order, or between controls.
  • Works with TreeViews.
  • Can insert an item into a collection, or drop one item onto another.
  • Can display Adorners to give the user visual feedback of the operation in progress.
  • Has sensible defaults so that you have to write less code for common operations

I found this library very easy to use and would recommend you consider this solution if you want to add drag drop capabilities to your WPF application.

Temporary Storage Service for WPF

Sometimes there is a requirement to temporarily store an object that can be later retrieved.  My particular problem at the time was that I wanted to share a View Model with a second view, but alas neither view knows about one another.

My first thought was to store the view model object temporarily in a Unity Container.  That way I could easily retrieve the object at a later time. This solution was not satisfactory however because this was only suppose to be a temporary storage solution and Unity does not support any unregister operation.  Not having the ability to remove (unregister) the object was not an option.

My solution was to create a Temporary Storage Service. The service I am demonstrating here allows for the Deposit and the Withdrawal of data (objects).  Some people may want to store the data for a little bit longer than straight in and straight out.  This solution could easily be modified to suit.

My Temporary Storage Service looks like this.

public class TemporaryStorageService : ITemporaryStorageService
    public void Deposit<T>(Object o, string key)
        System.Windows.Application.Current.Properties[key] = o;

    public T Withdraw<T>(string key)
    {   T o = (T)System.Windows.Application.Current.Properties[key];
        return o;


The Interface

publicinterface ITemporaryStorageService
   void Deposit<T>(Object o, string key);
   T Withdraw<T>(string key);

Register the service with Unity

// Temporary Storage Service
ITemporaryStorageService temporaryStorageService = new TemporaryStorageService();


Now I can call my Service whenever I need to store any Objects temporarily.  As I said above my immediate need was to store a view model temporarily.  So this is what I did.

My first view creates a new view model and immediately puts it in temporary storage

public class SomeWindow : Window
    ITemporaryStorageService _temporaryStorageService; 

    public SomeWindow(ITemporaryStorageService temporaryStorageService)
        this._temporaryStorageService = temporaryStorageService;

    public SharedViewModel VM
            this.DataContext = value;

            // We will store the view model in the Application Properites
            this._temporaryStorageService.Deposit<SharedViewModel>(value, "SharedViewModel");


Then when I initialise my second view I call upon the stored viewmodel.

public CashBook.MVVM.Services.ITemporaryStorageService TemporaryStorageService
      this.DataContext = value.Withdraw<SharedViewModel>("SharedViewModel");


Works like a charm!

My First WPF Report

My first WPF application is near completion, but one of the last items on the list is report printing. After a couple of hours on the internet I really did not see an ideal solution. There were however some aspects of the solutions I saw that appealed so I decided that I would pick out the best bits of what I had found and script my own Report Writer.

One example that got my attention on the internet was Azam Sharp. I thought his Flow Document example was simple and clean solution. What I wanted to do was take Azam’s example to the next level and give myself a tool to quickly design a report for my new project.

My Requirement list went like this.

  1. Print Preview
  2. Page Header
  3. Page Footer
  4. Full control of the report layout
  5. Keep it simple.

I will demonstrate my solution using a similar Business Entity as Azam did.

    public class Customer
        public string FirstName { get; set; }
        public string LastName { get; set; }

        // I'll add another column as one should always try and improve a copied solution <g>.
        public string Phone { get; set; }

My Customers Class will mange the Customer Collection

    public class Customers
        List<Customer> _customers = new List<Customer>();

        public Customers()
            for (int i = 1; i <= 80; i++)
                Customer customer = new Customer();
                customer.FirstName = "FirstName " + i;
                customer.LastName = "LastName " + i;
                customer.Phone = "Phone " + i;

        public List<Customer> FullCustomerList { get { return _customers; } }

        public int CustomerCount { get { return _customers.Count(); } }

        public Customer[] GetReportLineItems(int skipCount, int takeCount)
            var list = (from c in _customers
                        select c).Skip(skipCount).Take(takeCount);
            return list.ToArray(); ;

The operator will select and confirm the printing properties from the standard Print Dialog. I have designed a small class to record the values from the print dialog which we will use for formatting our report.

    internal class PageLayout
        public PageLayout(double height, double width)
            this.PageHeight = height;
            this.PageWidth = width;
            this.Margin = new Thickness(80, 50, 80, 50);
            this.ListViewItemsCount = 48;

        public double PageHeight { get; private set; }
        public double PageWidth { get; private set; }
        public Thickness Margin { get; private set; }
        public double PrintAreaHeight { get { return PageHeight - Margin.Top - Margin.Bottom; } }
        public double PrintAreaWidth { get { return PageWidth - Margin.Left - Margin.Right; } }
        public int ListViewItemsCount{ get; private set; }

The 'ListViewItemsCount' is most probably not the flashest coding mythology. I will elaborate in this later in this paper.

Next we want to design a Customer Report Template. We do this using XAML. The rules are no different, than if we where designing a form.

    <DockPanel x:Name="LayoutDockPanel" LastChildFill="True">
        <!-- Header -->
        <StackPanel DockPanel.Dock="Top" Height="80">
            <TextBlock FontSize="24" >Customer Report</TextBlock>
            <TextBlock FontSize="24" >Full Listing</TextBlock>
        <!-- Report Footer -->
        <StackPanel DockPanel.Dock="Bottom" Height="20" >
            <TextBlock HorizontalAlignment="Center" Margin="0,5,0,0" >Printing via a Flow Document</TextBlock>
        <!-- Report Body -->
        <ListView Name="ListView" HorizontalAlignment="Center" BorderThickness="0" >
                    <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" Width="110"  />
                    <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding LastName}" Width="110" />
                    <GridViewColumn Header="Phone" DisplayMemberBinding="{Binding Phone}" Width="110"  />

The Print Layout I have placed in a user control and it is here where I have total control over my report content. There is a page header, page body and a page footer section. If you think this through your layout options a virtually unlimited?

Now let put this altogether! I create a Print Preview window. The XAML looks like this.

    <DockPanel Width="Auto" Height="Auto" LastChildFill="True">
        <Button Width="100" Height="50" DockPanel.Dock="Top" Click="SendReportToPrinterButtonClick">Send to Printer</Button>
        <FlowDocumentReader >
            <FlowDocument x:Name="customerReport" Background="White" />

The Code behind looks like this.

    public partial class PrintPreview : Window
        private Customers _vm;
        private PrintDialog _printDialog;

        public PrintPreview()

            _vm = new Customers();

            _printDialog = new PrintDialog();
            if (_printDialog.ShowDialog() == true)
                PageLayout pageLayout = new PageLayout(_printDialog.PrintableAreaHeight, _printDialog.PrintableAreaWidth);

        private void BuildReport(PageLayout pageLayout)
            // Set the page Size and Margins
            this.customerReport.PagePadding = pageLayout.Margin;
            this.customerReport.PageHeight = pageLayout.PageHeight;
            this.customerReport.PageWidth = pageLayout.PageWidth;
            this.customerReport.ColumnWidth = pageLayout.PageWidth;
            this.customerReport.ColumnGap = 0;

            // Body Content
            for (int i = 0; i < _vm.CustomerCount; i += pageLayout.ListViewItemsCount)
                CustomerReportTemplate layout = new CustomerReportTemplate();
                // The next two lines are important as it will place the 
                // header and footer in place and the rest of the page area
                // is for the page body content.
                layout.LayoutDockPanel.Height = pageLayout.PrintAreaHeight;
                layout.LayoutDockPanel.Width = pageLayout.PrintAreaWidth;

                layout.ListView.ItemsSource = _vm.GetReportLineItems(i, pageLayout.ListViewItemsCount);

                InlineUIContainer inlineContainer = new InlineUIContainer();
                inlineContainer.Child = layout;

                this.customerReport.Blocks.Add(new Paragraph(inlineContainer));


This is the code that drives the report content. Although you may see some evidence of MVVM in this snippet, it is not an objective in this paper to provide a true MVVM example.

The above snippet achieves:

  • Connecting to the data source.
  • Showing the Print Dialog, so that the user can select the desired printer.
  • Using the information from the print dialog set up report layout.
  • Calls on the data source for the report body content data.
  • After the operator has studied the print preview, send the report to the printer.

I want to bring your attention to how I defined the page layout (page size, margins) and also how I have completely avoided scripting a Document Paginator. Neil Knobbe has a blog where he deployed this this mythology, which I have borrowed. He emphasises how it is important to configure the flowdocument page, column and margin sizes.

List View Item Count

In my example I assigned a value to the ListViewItemCount. This property returns the number of rows I wish to print in the body of the my document. Now obviously this value depends on the paper orientation and the paper size in your printer. So really it needs to be calculated based on these other variables. The good news is that it can be calculated. At least it can be calculated if you are happy to agree with the following logic.

  1. This is a business report that accompanies your application. Once this report is designed it will not change much. We may want to give the operator the choice of Portrait or Landscape. The font and font size will be pretty much static. The paper size could possibly change, but in the majority of cases you will have designed your report to fit one paper size.
  2. If you study my Customer Report Template above you will see I have started with a DocPanel. Added a Header and a Footer and the rest of the space is for the Page Body. The height of the body area is dependent on the Print Dialog Printable area height, our margin and the space taken up by the header and footer.
  3. This suggests that the item count value could be as simple as providing a portrait orientation value or a Landscape orientation value. What are these values? If you go now and change the value for ListViewItemCount to a large number (say 130) and run the reports in both portrait and landscape the the answer will be quickly evident. Give it a go.
  4. If you do have several paper sizes that your operator has to choose from then it's a bit more complicated. However as I leaded to above, we can easily calculate the page body height and we can also easily calculate the height of each row. The rest I will leave up to you.

This example is a good base for printing Business Reports. If I was printing many reports on my project then a lot of the above code is reusable, so it would not take a long time to push out other reports as they are required.

Source Code

You can download the Source here.