Header Ads

WPF: Auto Complete/Suggestion Text Box Control

A Good product requires a good user interaction. Products that are using search boxes will be expected to have auto completion/suggestion feature. In WPF platform, default text box control does not have any built-in auto completion/suggestion feature. There are many 3rd party libraries out there which provide auto complete/suggestion text box control as a replacement to default WPF text box control. Most of these libraries are available in paid version and those which are available for free, are difficult to get integrated with your existing code. So, I have created a very simple Auto Complete/Suggestion control for WPF platform without using any external library. You can easily integrate my control in your project.
Today, I shall be demonstrating the creation of text box with auto complete/suggestion feature along with its integration within your code in WPF platform.


Prerequisites:

Following are some prerequisites before you proceed any further in this tutorial:
  1. Knowledge about Windows Presentation Form (WPF).
  2. Knowledge of C# Programming.
  3. Knowledge about C# LINQ.
You can download the complete source code for this tutorial or you can follow the step by step discussion below. The sample code is being developed in Microsoft Visual Studio 2017 Professional.

Download Now!

Background

In order to create the WPF auto complete/suggestion text box control. I have used a composite of built-in controls i.e. StackPanel, TextBox control, Popup control and ListBox default controls. Following is the hierarchy that I have used in my user control to combine these default controls i.e.


Usage

In order to use my auto complete/suggestion text box control, you need to include my user control namespace into your target XAML file and following line of code i.e.



You also need to set your auto suggestion list in the target XAML.CS file i.e.



Let's begin now.

1) Create a new WPF application project and name it "WPFAutoCompleteTextBox".

2) Create "Views\UserControls\AutoCompleteTextBoxUserControl.xaml" file and replace following code in it i.e.

<UserControl x:Class="WPFAutoCompleteTextBox.Views.UserControls.AutoCompleteTextBoxUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFAutoCompleteTextBox.Views.UserControls"
             mc:Ignorable="d" 
             d:DesignHeight="480" d:DesignWidth="640">

    <Grid>
        <StackPanel Orientation="Vertical"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Center">

            <!-- Text Box -->
            <Border x:Name="autoTextBoxBorder"
                        Width="220"
                        Height="50">

                <Border.Background>
                    <ImageBrush ImageSource="/WPFAutoCompleteTextBox;component/Content/img/text-box_bg.png"/>
                </Border.Background>

                <TextBox x:Name="autoTextBox"
                             Width="220" 
                             Height="50"
                             FontSize="18"  
                             HorizontalAlignment="Center" 
                             VerticalAlignment="Center" 
                             BorderThickness="0"
                             VerticalContentAlignment="Center"
                             HorizontalContentAlignment="Center"
                             Padding="0,0,0,0"
                             Background="Transparent"
                             Foreground="Black"
                             TextChanged="AutoTextBox_TextChanged"/>
            </Border>

            <!-- Auto Suggestion box -->
            <Popup x:Name="autoListPopup"
                   Visibility="Collapsed"                
                   Height="100"
                   StaysOpen="False"
                   Placement="Bottom">

                <ListBox x:Name="autoList"
                         Visibility="Collapsed"
                         Width="500"
                         Height="100"
                         SelectionChanged="AutoList_SelectionChanged" />
            </Popup>
        </StackPanel>
    </Grid>
</UserControl>

In the above code, I have created my auto complete/suggestion user control hierarchy from the built-in WPF control with default settings.

3) Now open, "Views\UserControls\AutoCompleteTextBoxUserControl.xaml.cs" file and replace following code in it i.e.

//-----------------------------------------------------------------------
// <copyright file="AutoCompleteTextBoxUserControl.xaml.cs" company="None">
//     Copyright (c) Allow to distribute this code and utilize this code for personal or commercial purpose.
// </copyright>
// <author>Asma Khalid</author>
//-----------------------------------------------------------------------

namespace WPFAutoCompleteTextBox.Views.UserControls
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;

    /// <summary>
    /// Interaction logic for Autocomplete Text Box UserControl
    /// </summary>
    public partial class AutoCompleteTextBoxUserControl : UserControl
    {
        #region Private properties.

        /// <summary>
        /// Auto suggestion list property.
        /// </summary>
        private List<string> autoSuggestionList = new List<string>();

        #endregion

        #region Default Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="AutoCompleteTextBoxUserControl" /> class.
        /// </summary>
        public AutoCompleteTextBoxUserControl()
        {
            try
            {
                // Initialization.
                this.InitializeComponent();
            }
            catch (Exception ex)
            {
                // Info.
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion

        #region Protected / Public properties.

        /// <summary>
        /// Gets or sets Auto suggestion list property.
        /// </summary>
        public List<string> AutoSuggestionList
        {
            get { return this.autoSuggestionList; }
            set { this.autoSuggestionList = value; }
        }

        #endregion

        #region Open Auto Suggestion box method

        /// <summary>
        ///  Open Auto Suggestion box method
        /// </summary>
        private void OpenAutoSuggestionBox()
        {
            try
            {
                // Enable.
                this.autoListPopup.Visibility = Visibility.Visible;
                this.autoListPopup.IsOpen = true;
                this.autoList.Visibility = Visibility.Visible;
            }
            catch (Exception ex)
            {
                // Info.
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion

        #region Close Auto Suggestion box method

        /// <summary>
        ///  Close Auto Suggestion box method
        /// </summary>
        private void CloseAutoSuggestionBox()
        {
            try
            {
                // Enable.
                this.autoListPopup.Visibility = Visibility.Collapsed;
                this.autoListPopup.IsOpen = false;
                this.autoList.Visibility = Visibility.Collapsed;
            }
            catch (Exception ex)
            {
                // Info.
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion

        #region Auto Text Box text changed method

        /// <summary>
        ///  Auto Text Box text changed method.
        /// </summary>
        /// <param name="sender">Sender parameter</param>
        /// <param name="e">Event parameter</param>
        private void AutoTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            try
            {
                // Verification.
                if (string.IsNullOrEmpty(this.autoTextBox.Text))
                {
                    // Disable.
                    this.CloseAutoSuggestionBox();

                    // Info.
                    return;
                }

                // Enable.
                this.OpenAutoSuggestionBox();

                // Settings.
                this.autoList.ItemsSource = this.AutoSuggestionList.Where(p => p.ToLower().Contains(this.autoTextBox.Text.ToLower())).ToList();
            }
            catch (Exception ex)
            {
                // Info.
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion

        #region Auto list selection changed method

        /// <summary>
        ///  Auto list selection changed method.
        /// </summary>
        /// <param name="sender">Sender parameter</param>
        /// <param name="e">Event parameter</param>
        private void AutoList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                // Verification.
                if (this.autoList.SelectedIndex <= -1)
                {
                    // Disable.
                    this.CloseAutoSuggestionBox();

                    // Info.
                    return;
                }

                // Disable.
                this.CloseAutoSuggestionBox();

                // Settings.
                this.autoTextBox.Text = this.autoList.SelectedItem.ToString();
                this.autoList.SelectedIndex = -1;
            }
            catch (Exception ex)
            {
                // Info.
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion
    }
}

In the above code, I have created a public property "AutoSuggestionList" to which you will provide your auto suggestion list. I have then created "OpenAutoSuggestionBox(..)" method, which will open the auto suggestion box as the end-user types in the text box. Then, I have created "CloseSuggestionBox(...)" method, which will close the auto suggestion box when the end-user selects the target suggested item from the auto suggestion list. Then, I have created "AutoTextBox_TextChanged(...)" method, which will update the auto suggestion list according to the text typed in the text box by the end-user. Finally, I have created "AutoList_SelectionChanged(...)" method which will update the text box according to the selected suggested item from the auto suggestion list by the end-user.

4) Now, create a new "Views\Pages\HomePage.xaml" file and replace the following code in it i.e.

<Page x:Class="WPFAutoCompleteTextBox.Views.Pages.HomePage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WPFAutoCompleteTextBox.Views.Pages"
      xmlns:uc ="clr-namespace:WPFAutoCompleteTextBox.Views.UserControls"
      mc:Ignorable="d" 
      d:DesignHeight="480" d:DesignWidth="640"
      Title="Home Page">

    <Grid>
        <DockPanel>
            <Border Grid.Row="1"
                        Width=" 400"
                        Height="300" 
                        BorderThickness="1" 
                        BorderBrush="Black" 
                        CornerRadius="20" 
                        Opacity="1">
                
                <Border.Background>
                    <ImageBrush ImageSource="/WPFAutoCompleteTextBox;component/Content/img/bg_2.png">
                        <ImageBrush.RelativeTransform>
                            <TransformGroup>
                                <ScaleTransform CenterY="0.5" CenterX="0.5" ScaleX="1.5" ScaleY="1.5"/>
                                <SkewTransform CenterY="0.5" CenterX="0.5"/>
                                <RotateTransform CenterY="0.5" CenterX="0.5"/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </ImageBrush.RelativeTransform>
                    </ImageBrush>
                </Border.Background>

                <StackPanel Orientation="Vertical" 
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Width=" 400"
                                Height="300" >

                    <TextBlock Text="Enter Your Country Name"
                                   VerticalAlignment="Center"
                                   HorizontalAlignment="Center" 
                                   Margin="0,110,0,0" 
                                   FontWeight="Bold" 
                                   FontSize="18" 
                                   Foreground="Black" />

                    <!-- Auto suggestion -->
                    <uc:AutoCompleteTextBoxUserControl x:Name="autoSuggestionUseControl" />
                </StackPanel>
            </Border>
        </DockPanel>
    </Grid>
</Page>

In the above code, I have created a simple page which will contain my auto complete/suggestion text box for user to provide input and select target information accordingly. I am using country list as my auto suggestion list.

5) Open "Views\Pages\HomePage.xaml.cs" file and replace the following code in it i.e.

//-----------------------------------------------------------------------
// <copyright file="HomePage.xaml.cs" company="None">
//     Copyright (c) Allow to distribute this code and utilize this code for personal or commercial purpose.
// </copyright>
// <author>Asma Khalid</author>
//-----------------------------------------------------------------------

namespace WPFAutoCompleteTextBox.Views.Pages
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using WPFAutoCompleteTextBox.Model.BusinessLogic;

    /// <summary>
    /// Interaction logic for Home Page
    /// </summary>
    public partial class HomePage : Page
    {
        #region Default Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="HomePage" /> class.
        /// </summary>
        public HomePage()
        {
            try
            {
                // Initialization.
                this.InitializeComponent();

                // Loaded.
                this.Loaded += this.HomePage_Loaded;
            }
            catch (Exception ex)
            {
                // Info.
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion

        #region Page Loaded event method.

        /// <summary>
        /// Page Loaded event method
        /// </summary>
        /// <param name="sender">Sender parameter</param>
        /// <param name="e">Event parameter</param>
        private void HomePage_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                // Auto suggestion list.
                this.autoSuggestionUseControl.AutoSuggestionList = HomeBusinessLogic.LoadCountryList();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                Console.Write(ex);
            }
        }

        #endregion
    }
}

In the above code, I have created "HomePage_Loaded(...)" method in which I am loading my auto suggestion list into my auto suggestion text box user control.

6) Now, execute the project and you will be able to see the following in action i.e.


Conclusion

In this article, you will learn to create auto complete/suggestion text box control using built-in UI controls in WPF platform. You will also learn to integrate this auto complete/suggestion text box user control into your own target WPF page.

Disclaimer

The background image use in this article has been taken from freepike.

5 comments: