Export (0) Print
Expand All

How to: Change the Appearance and Behavior of the AutoCompleteBox Control

Silverlight

The AutoCompleteBox control is highly customizable in appearance and behavior. This topic shows you how to change the appearance and behavior of the AutoCompleteBox by setting its properties, handling events, and calling methods on the control. For information about how to perform advanced customization of the AutoCompleteBox's appearance and behavior by creating a new default template, see Control Customization and AutoCompleteBox Styles and Templates.

This topic contains the following sections:

The AutoCompleteBox enables you to change its appearance by creating new styles.

To change the appearance of the text box part of the control

  • Create a style that targets the TextBox type and set the TextBoxStyle property to the style. The following XAML shows a style declared as a resource and set as the value for the TextBoxStyle property.

    
        <Style  x:Key="myTBStyle" TargetType="TextBox">
        <Setter Property="Background" Value="LightYellow" />
        <Setter Property="Foreground" Value="DarkSlateGray" />
        <Setter Property="Margin" Value="5" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="FontSize" Value="14" />
        <Setter Property="BorderBrush" Value="DarkGray" />
    </Style>
    
    
    ...
    
    
    <sdk:AutoCompleteBox Width="150"  Height="30" x:Name="myACB" 
        TextBoxStyle="{StaticResource myTBStyle}" 
        ItemContainerStyle="{StaticResource myLBStyle}" />
    
    
    

To change the drop-down part of the control

  • Create a style that targets the ListBox type and set the ItemContainerStyle property to the style. The following XAML shows a style declared as a resource and set as the value for the ItemContainerStyle property.

    
    <Style  x:Key="myLBStyle" TargetType="ListBoxItem">
        <Setter Property="Background" Value="Khaki" />
        <Setter Property="Foreground" Value="DarkSlateGray" />
        <Setter Property="Margin" Value="5" />
        <Setter Property="FontStyle" Value="Italic" />
        <Setter Property="FontSize" Value="14" />
        <Setter Property="BorderBrush" Value="DarkGray" />
    </Style>
    
    
    ...
    
    
    <sdk:AutoCompleteBox Width="150"  Height="30" x:Name="myACB" 
        TextBoxStyle="{StaticResource myTBStyle}" 
        ItemContainerStyle="{StaticResource myLBStyle}" />
    
    
    

You can specify how the AutoCompleteBox filters items. For example, you can specify whether it looks for matches at the start of a word, in a word, or other choices. You may also need a custom text or object filter for the objects displayed in the AutoCompleteBox, but you are not able to change the object. In this case, you can create a custom text or object filter for the AutoCompleteBox by setting the TextFilter or ItemFilter properties to a method that matches the signature of the AutoCompleteFilterPredicate<T> delegate.

To change how the AutoCompleteBox filters items

  • Set the FilterMode property to a AutoCompleteFilterMode value.

    The following XAML shows how to set the FilterMode property to look for a string that contains another string and is case sensitive.

    <input:AutoCompleteBox FilterMode="ContainsCaseSensitive" 
       Height="40" Width="200" x:Name="ACB" />
    

To create a custom string filter

  • Set the TextFilter property to a method that matches the signature of the AutoCompleteFilterPredicate<T> delegate type that accepts a string. The method should perform the necessary string filtering for your AutoCompleteBox.

    The following example code shows associating the property with the delegate method, and the custom string filtering.

    
    List<Employee> employees = new List<Employee>();
    public MainPage()
    {
        InitializeComponent();
        // Add some items to the employee list.
        employees.Add(new Employee("Sells", "Chris", "csells", 1234));
        employees.Add(new Employee("Cabatana", "Reina", "rcaba", 5678));
        employees.Add(new Employee("Sprenger", "Christof", "cspreng", 9123));
        employees.Add(new Employee("Brandel", "Jonas", "jbrandel", 4567));
        employees.Add(new Employee("Bye", "Dennis", "dbye", 8912));
        employees.Add(new Employee("Reid", "Miles", "mreid", 3456));
    
        // Set the item source.
        myACB.ItemsSource = employees;
    
    
    ...
    
    
    // Set the TextFilter property to the search method.
    myACB.TextFilter += SearchEmployees;
    
    
    ...
    
    
    }
    
    
    ...
    
    
    bool SearchEmployees(string search, string value)
    {
        value = value.ToLower();
        // Split the string a new line.
        string[] words = value.Split(System.Environment.NewLine.ToCharArray(),
            StringSplitOptions.RemoveEmptyEntries);
    
        string[] names = words[0].Split(' ');
    
        // Look for a match in the first line; discarding the "employee:" entry.
        foreach (string name in names)
        {
            if (name != "employee:")
                if (name.StartsWith(search))
                    return true;
        }
        // If no match, return false.
        return false;
    }
    
    
    ...
    
    
    public class Employee
    {
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string EmailName { get; set; }
        public int ID { get; set; }
        public Employee(string empLastName, string empFirstName, string empEmail, int empID)
        {
            LastName = empLastName;
            FirstName = empFirstName;
            EmailName = empEmail;
            ID = empID;
        }
        public override string ToString()
        {
            return "Employee: " + FirstName + " " + 
                LastName + System.Environment.NewLine + 
                "Email: " + EmailName + System.Environment.NewLine + "ID: " +
                ID.ToString();
        }
    }
    
    
    
    
    <StackPanel x:Name="LayoutRoot" Background="LightGray">
         <TextBlock FontWeight="Bold" Text="AutoCompleteBox Custom Filter Example" Margin="5"/>
         <StackPanel  Orientation="Horizontal">
             <TextBlock Text="Employee:" Margin="5" HorizontalAlignment="Left"  VerticalAlignment="Center"/>
             <sdk:AutoCompleteBox Height="75" Width="200" VerticalAlignment="Center" HorizontalAlignment="Right" 
             x:Name="myACB" FilterMode="Custom" ToolTipService.ToolTip="Enter employee name."/>
         </StackPanel>
         </StackPanel>
    
    
    

To create a custom object filter

  • Set the ItemFilter property to a method that matches the signature of the AutoCompleteFilterPredicate<T> delegate type that accepts a object. The method should perform the necessary object filtering for your AutoCompleteBox.

    The following code shows an example of setting the ItemFilter property and the custom object filtering.

    
    List<Employee> employees = new List<Employee>();
    public MainPage()
    {
        InitializeComponent();
        // Add some items to the employee list.
        employees.Add(new Employee("Sells", "Chris", "csells", 1234));
        employees.Add(new Employee("Cabatana", "Reina", "rcaba", 5678));
        employees.Add(new Employee("Sprenger", "Christof", "cspreng", 9123));
        employees.Add(new Employee("Brandel", "Jonas", "jbrandel", 4567));
        employees.Add(new Employee("Bye", "Dennis", "dbye", 8912));
        employees.Add(new Employee("Reid", "Miles", "mreid", 3456));
    
        // Set the item source.
        myACB.ItemsSource = employees;
    
    
    ...
    
    
    // Set the ItemFilter property to the search method.
    myACB.ItemFilter += SearchEmployees;
    
    
    ...
    
    
    }
    
    
    ...
    
    
    bool SearchEmployees(string search, object value)
    {
        // Cast the value to an Employee.
        Employee emp = value as Employee;
        if (emp != null)
        {
            // Look for a match in the first and last names.
            if (emp.LastName.ToLower().StartsWith(search))
                return true;
    
            else if (emp.FirstName.ToLower().StartsWith(search))
                return true;
        }
        // If no match, return false.
        return false;
    }
    
    
    ...
    
    
    public class Employee
    {
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string EmailName { get; set; }
        public int ID { get; set; }
        public Employee(string empLastName, string empFirstName, string empEmail, int empID)
        {
            LastName = empLastName;
            FirstName = empFirstName;
            EmailName = empEmail;
            ID = empID;
        }
        public override string ToString()
        {
            return "Employee: " + FirstName + " " + 
                LastName + System.Environment.NewLine + 
                "Email: " + EmailName + System.Environment.NewLine + "ID: " +
                ID.ToString();
        }
    }
    
    
    
    
    <StackPanel x:Name="LayoutRoot" Background="LightGray">
         <TextBlock FontWeight="Bold" Text="AutoCompleteBox Custom Filter Example" Margin="5"/>
         <StackPanel  Orientation="Horizontal">
             <TextBlock Text="Employee:" Margin="5" HorizontalAlignment="Left"  VerticalAlignment="Center"/>
             <sdk:AutoCompleteBox Height="75" Width="200" VerticalAlignment="Center" HorizontalAlignment="Right" 
             x:Name="myACB" FilterMode="Custom" ToolTipService.ToolTip="Enter employee name."/>
         </StackPanel>
         </StackPanel>
    
    
    

You may want to populate the AutoCompleteBox with the result of an asynchronous call to a Web service, or other data source, and therefore populate the drop-down manually. You can easily override the default filtering behavior of the AutoCompleteBox to do this.

To populate the AutoCompleteBox drop-down manually

  1. Optionally, set the MinimumPopulateDelay to 100 or more to delay the populate operation. This decreases the number of calls to populate the AutoCompleteBox as the user types.

  2. Optionally set the MinimumPrefixLength to a value greater than 1 to decrease the number of calls to the populate operation.

  3. Handle the Populating event and cancel it by setting the PopulatingEventArgs.Cancel property to true. This notifies the control that you will populate it manually.

  4. Call the method that will perform the filtering operation. If you are calling a Web service, this will involve a callback method. In this method, when the filter operation is complete, call PopulateComplete. This notifies the control that you are finished populating the control.

    The following code shows how to set MinimumPopulateDelay an MinimumPrefixLength properties handle the Populating event, and call PopulateComplete when the operation is finished. The code calls a Web service asynchronously and uses the returned XML to populate the AutoCompleteBox.

    
       <StackPanel x:Name="LayoutRoot" Background="White" Orientation="Horizontal">
        <TextBlock Text="News Topic:" HorizontalAlignment="Left"  VerticalAlignment="Center"/>
        <sdk:AutoCompleteBox VerticalAlignment="Center" HorizontalAlignment="Right" Height="30" 
            Width="100" MinimumPopulateDelay="200" MinimumPrefixLength="3" x:Name="myACB" Populating="AutoCompleteBox_Populating" />
    </StackPanel>
    
    
    
    
        // Handle the Populating event, but cancel it. Make the call to the web service.
        private void AutoCompleteBox_Populating(object sender, PopulatingEventArgs e)
        {
            e.Cancel = true;
            CallToWebService();
        }
    
        // Call the topic service at the live search site.
        WebClient wc;
        private void CallToWebService()
        {
            wc = new WebClient();
            wc.DownloadStringAsync(new Uri
                ("http://api.search.live.net/qson.aspx?query=" + myACB.SearchText +
                "&sources=news"));
            wc.DownloadStringCompleted +=
                new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);
        }
    
        void wc_DownloadStringCompleted(object sender,
            DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                return;
            }
    
            List<string> data = new List<string>();
            try
            {
                JsonObject jso = ((JsonObject)JsonObject.Parse(e.Result))
                    ["SearchSuggestion"] as JsonObject;
                string originalSearchString = jso["Query"];
                if (originalSearchString == myACB.SearchText)
                {
                    foreach (JsonObject suggestion in (JsonArray)jso["Section"])
                    {
                        data.Add(suggestion.Values.First());
                    }
    
                    // Diplay the AutoCompleteBox drop down with any suggestions
                    myACB.ItemsSource = data;
                    myACB.PopulateComplete();
                }
            }
            catch { }
        }
    }
    
    
    

Community Additions

ADD
Show:
© 2015 Microsoft