How to create Silverlight autosuggest control - 1
|
|
|
|
|
Downloads
If you are seeing this section and do not see download links, this means that you are not logged into our site. If you already are a member, click on the login link
and login into site and come back to this page for downloading the control files. If you are not a member, click on registration link to
become a Winista member and download the control for free.
This article is about utilizing concepts from previous article How to use ASP.Net web services in SilverLight and
creating an autosuggest control text box. This article will be building block for a more sophisticated autosuggest control. In this article I will
not discuss more advanced UI layout techniques. I will be doing that in next article.
User Interface Layout
There are 2 basic building blocks to create an autosuggest control, a text box and a list box. The idea is pretty simple that
when a user starts typing in the text box, fetch the suggestions based on the text entered so far, add enties in the list
box and disply to use.
TextBox - Input for text
ListBox - List box to show suggestion entries
Following code snippet shows how the mark up for the control looks like.
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
<TextBox x:Name="ctlMenuItemNameInput" Height="30" Width="200"
LostFocus="MenuItemNameInput_LostFocus"
TextChanged="MenuItemNameInput_TextChanged"></TextBox>
<ListBox x:Name="ctlMenuItemsList" Width="200" MaxHeight="200"
SelectionChanged="MenuItemsList_SelectionChanged"></ListBox>
</StackPanel>
</Grid>
Mechanics of control
Notice the mark up for the control. You will find that I am handling two events on TextBox control,
TextChanged and LostFocus. After user has entered text, TextBox control fires
TextChanged event. In this event, I grag the text and call a web service to get list of suggestions and
then populate ListBox control with those entries. Since we do not want the drodown to be visible all the
time, we handle LostFocus event on TestBox. As soon as text box looses focus we get the event and
clear the entries in listbox and collapse it. So you can see how easy it is to implement a quick AutoSuggest control
in solverlight. Following code snippet shows event handlers for TextChanged and LostFocus events.
private void MenuItemNameInput_TextChanged(object sender, TextChangedEventArgs e)
{
if (_supressTextChangeEvent)
{
this._supressTextChangeEvent = false;
return;
}
this.ctlMenuItemsList.Visibility = System.Windows.Visibility.Collapsed;
this.ctlMenuItemsList.Items.Clear();
string nameSuffix = this.ctlMenuItemNameInput.Text;
if (string.IsNullOrEmpty(nameSuffix))
{
return;
}
if (this._soapCallInProgress)
{
// cancel the previous call.
this.CancelSoapRequest();
}
this.GetMenuItemsWithNameLike(nameSuffix);
}
private void MenuItemsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxItem item = e.AddedItems[0] as ListBoxItem;
this._supressTextChangeEvent = true;
this.ctlMenuItemNameInput.Text = item.Content as string;
}
private void MenuItemNameInput_LostFocus(object sender, RoutedEventArgs e)
{
this.ctlMenuItemsList.Visibility = System.Windows.Visibility.Collapsed;
}
protected void GetMenuItemsWithNameCompleted(object sender,
GetMenuItemsWithNameLikeCompletedEventArgs e)
{
try
{
if (!e.Cancelled)
{
this.ctlMenuItemsList.Items.Clear();
_menuItemsWithNameLike = (MenuItem[]) e.Result;
for (int i = 0; i < this._menuItemsWithNameLike.Length; i++)
{
ListBoxItem item = new ListBoxItem();
item.Content = this._menuItemsWithNameLike[i].Name;
this.ctlMenuItemsList.Items.Add(item);
}
this.ctlMenuItemsList.Visibility =
System.Windows.Visibility.Visible;
}
}
catch (Exception ex)
{
this._errorMessage += ex.Message;
this._errorMessage += ex.StackTrace;
}
this._soapCallInProgress = false;
}
If you look at the code snippet above, you will notice some impleemntation that needs little bit more explanation.
Populating ListBox
Since all web service requests in Silverlight are asynchronous, we populate suggestion list in service request
completion handler which in my case is GetMenuItemsWithNameCompleted.
Cancel WebService Request
You will notice that there is a boolean value GetMenuItemsWithNameCompleted being tracked throughout
the event handlers. When a user is typing fast, textChanged event handlers will be fired at the same
rate. This could mean that previous web service request for suggestions may not have finished yet. And displaying
results for previous text will not make sense to user. So we keep track of calls in progress. If a new web request
comes before previous one has finished, I abort the previous request. And in completion routine, I check if the
last request was cancelled, do not take any action for populating list box.
Supress TextChanged
Once list of suggestions has been presented in listbox, the next action from user will be to select an item
in ListBox if that is one of the suggestions that user was looking for. So we handle SelectionChanged
event for ListBox. And I set the selected item's text in TextBox. That would mean a new TextChanged
event will fire for control. We do not want to send another web service request for this selected text. Therefore I keep track of
a boolean flag that is checked in TextChanged event which decides if any action needs to be taken for this event or not.
Test It
Following snippet shows how I dropped this control on an ASP.Net page and tested it.
<asp:ScriptManager ID="ctlScriptManager2" runat="server"></asp:ScriptManager>
<div>
<div style="height:100%;">
<asp:Silverlight ID="ctlSilverSpiceSuggest" runat="server"
Source="~/SLControls/SilverSuggest.xap" Version="2.0"
Width="100%" Height="100%" />
</div>
</div>
More
This is a very bare bone implementation of Autusuggest control in Silverlight. It does not attempt to make UI more smoother or slick.
In next article i will go in depth about UI layout of control and make it use on a real page along with other HTML content on a web page.
|