Friday 14 January 2011

AutoCompleteBox to auto complete data entry.

I ran into a situation where, I need a way to provide a user with auto complete text box with predefined list of data. If the data already exists in the list, then user select it and continue, if the data does not contain in the list, the user data will be added to the list thus it is available for the future auto completion. It is pretty simple, if you know there is a control called ‘AutoCompleteBox’ available in the toolkit.

In my case the auto completion is part of the grid, so I will stay on the same sample to illustrate how easy to implement this. This is a very rudimentary implementation and can be improved a lot to meet your needs.

First thing we start by adding a cell edit template to the the column in question where we need to provide the auto completion. A simple XAML definition would look like the following

 1: <c1:Column.CellEditingTemplate>
2: <DataTemplate>
3: <sdk:AutoCompleteBox Text="{Binding ReferencePath,Mode=TwoWay}"
4: Populating="tester_Populating" MinimumPrefixLength="0" IsDropDownOpen="True" LostFocus="tester_LostFocus"/>
5: </DataTemplate>
6: </c1:Column.CellEditingTemplate>

There are few important pieces in line 4. The first one is the event called ‘tester_Populating’ event. This event, will filter the data collection and return only matching values as the user types to show in the drop down.

MinimumPrefixLength to 0 will show the drop down even when there is no data entered in the text box.

IsDropDownOpen set to true will open the drop down on double click on the cell.

LostFocus event will trigger a method to check and see if the data user enter already in the list and if it is not available then add it to the collection to show in the future.

Lets look at the events implementation

tester_Populating:

 1: private void tester_Populating(object sender, PopulatingEventArgs e)
2: {
3: if (_names == null)
4: {
5: _names = new List<string>();
6: _names.Add("Kumar");
7: _names.Add("Ram");
8: _names.Add("Krishna");
9: _names.Add("John");
10: }
11: List<string> data = new List<string>();
12: AutoCompleteBox box = sender as AutoCompleteBox;
13: foreach (string name in _names)
14: {
15: if (name.ToUpper().StartsWith(box.Text.ToUpper()))
16: data.Add(name);
17: }
18: box.ItemsSource = data;
19: box.PopulateComplete();
20: }

Line 3-10 to create first time collection. Line 13-17 is where you check and see if the user input data matches any in our collection and if so, then add it to temperory collection and binding it to auto complete box. As done in line 18.

 1: private void tester_LostFocus(object sender, RoutedEventArgs e)
2: {
3: AutoCompleteBox box = sender as AutoCompleteBox;
4: if (box.Text.Length > 0)
5: {
6: bool found = false;
7: foreach (string name in _names)
8: {
9: if (name.ToUpper().Equals(box.Text.ToUpper()))
10: {
11: found = true;
12: break;
13: }
14: }
15: if (!found)
16: _names.Add(box.Text);
17: }
18: }

Hope this helps.

0 comments:

Post a Comment