I’m using AutoComplete to enhance the functionality of a TextBox and make it act like the below image, where the user enters the customer accountnumber, which is then displayed together with their name (the blurry stuff in the picture :-)
| As I have to use this functionality on many pages, I needed it to be a UserControl. I wanted to use a PageMethod (instead of a Web Service) to populate the AutoCompleteExtender, but since the page method must reside on the page (in the .aspx.cs file, it does not work if it’s placed in the .ascx.cs file – dammit MS), I wanted to limit the code needed on the .aspx.cs page to a bare minimum. The number of entries displayed in the AutoComplete DropDown list had to be limited, but the user need to know how many matches the prefix entered. |
The Page Method (ServiceMethod) of the AutoCompleteExtender requires a string[] to work and I wanted the Page Method to contain as little code as possible. I ended up with this:
[System.Web.Services.WebMethodAttribute(),
System.Web.Script.Services.ScriptMethodAttribute()]
public static string[] GetDataCustomerAccountNo(string prefixText,
int count, string contextKey)
{
CustomerRepository customerRepository = new CustomerRepository();
return customerRepository.GetCustomerAccountNumbersByPrefix(prefixText);
}
The GetCustomerAccountNumbersByPrefix looks like this:
/// <summary>
/// Retrieves all AccountNumbers which match prefix (AutoComplete)
/// </summary>
/// <param name="prefix">Prefix to match</param>
public string[] GetCustomerAccountNumbersByPrefix(string prefix)
{
var customers = from e in db.Customers
where e.AccountNumber.StartsWith(prefix)
orderby e.AccountNumber
select e;
int count = customers.Count();
string[] result = customers.Take(21).Select(x => x.AccountNumber + " – "
+ x.NameAlias).ToArray<string>();
if (result.Count() > 20)
{
result[20] = ">> antal: " + count.ToString();
}
return result;
}
If the ResultSet contains more than 20 rows I want to provide information about this to the user, displaying the total number of rows, which is why I do a Count() before Take()
I use .Select() to transform the properties AccountNumber and NameAlias into a single string, which is then returned as a string[] using ToArray(), in the process I limit the number of rows to a maximum of 21 using Take()
And all there’s left to do is to optionally change the 21th entry to show the total number of rows information. As the string[] is fixed it’s much easier simply to take out an extra row - Take(21) – and use this last row to show the information.
Hope the above example is useful to others who might want to use the AutoCompleteExtender in a UserControls only to find out that the PageMethod actually DO have to reside in the .aspx.cs file.