Thursday, November 5, 2009

Silverlight Autocompletebox with custom dropdown

I needed to create an Autocompletebox for selecting staff. I wanted a robust select so you can type in the first name of the employee, last name, staff id, or even the office the staff member resided in, and the list would be filtered and selectable in the dropdown.

Once selected, the box could fire an event that would load additional info about the employee. Here is what it looks like, this is before I put in pretty formating, keep in mind I'm a coder, not an artist. :)

I decided to get the staff member via a WCF call, here is the GetStaffList() call I defined and am returning a custom class so I can specify the exact search criteria.

[OperationContract]
public List GetStaffList()
{
   Csla.ApplicationContext.ClientContext["HostName"] = // I used CSLA, put address here;

   List staffList = new List();
   StaffViewListClass staffListClass = StaffViewListClass.GetStaff();

   foreach (StaffViewClass staff in staffListClass)
   {
      staffList.Add(new StaffSearchClass(staff.FullName, staff.FirstName,
                  staff.OfficeName, staff.StaffId));
   }
   return staffList;
}

And here is the custom class definition:

[DataContract]
    public class StaffSearchClass
    {
        [DataMember]
        public string FullName { get; set; }
        [DataMember]
        public string StaffId { get; set; }
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string OfficeName { get; set; }
        [DataMember]
        public string DisplayValue { get; set; }

        public StaffSearchClass(string fullName, string firstName, string officeName, string staffId)
        {
            FullName = fullName;
            FirstName = firstName;
            OfficeName = officeName;
            StaffId = staffId;
            DisplayValue = StaffId + " " + FullName;
        }
    }

Note the use of [DataContract] and [DataMember] attributes. These are important so the ServiceReference knows about them.

The next phase was to create a custom searchable Autocomplete box. Jeff Wilcox Microsoft MVP has a great "missing guide"

Step 1: In your Silverlight project, add a Service Reference to your WCF Service.

Step 2: Get the Staff Data Asyncronously. Here is my MainPage() method:
public MainPage()
        {
            InitializeComponent();

            SilverlightAuto.StaffService.StaffServiceClient client = new SilverlightAuto.StaffService.StaffServiceClient();

            client.GetStaffListCompleted += new EventHandler(client_GetStaffListCompleted);

            client.GetStaffListAsync();

        }

        void client_GetStaffListCompleted(object sender, SilverlightAuto.StaffService.GetStaffListCompletedEventArgs e)
        {
            List list = e.Result.ToList();
            uxAuto.ItemsSource = e.Result.ToList();

            uxAuto.ItemFilter += SearchStaff;

        }

Important to note: In my ServiceReference completed event, I've added an ItemFilter to my Autocompletebox control (uxAuto). This is necessary to custom bind my search criteria (remember that I wanted to search on First name, last name, etc). Autocompletebox can't assume what you want to search on, but makes it pretty easy to customize.

Here is the SeachStaff method, you can put whatever search criteria you want, but be aware of performance if you are parsing a lot of data.

bool SearchStaff(string search, object value)
        {
            search = search.ToLower();
            SilverlightAuto.StaffService.StaffSearchClass staff = value as SilverlightAuto.StaffService.StaffSearchClass;

            if (staff != null)
            {
                if (staff.StaffId.StartsWith(search))
                    return true;
                else if (staff.FullName.ToLower().StartsWith(search))
                    return true;
                else if (staff.FirstName.ToLower().StartsWith(search))
                    return true;
                else if (staff.OfficeName.ToLower().StartsWith(search))
                    return true;
            }

            return false;
        }

As a reference, here is the Xaml for the autocomplete box. Note you need to add the System.Windows.Controls.Input declarative.

  
        
            
                
                    
                        
                        
                    
                
            
        

So remember the requirement that I needed to populate some other stuff once the staff member has been selected? That was tricky, there is no obvious event to hook into when the user has been selected, but if you look, I have an event on DropDownClosed. Seems like an odd event to tie into, but works exactly like I wanted it to since when a staff member is selected the box closes!

Overall I am really impressed with this control. I used to have to do a lot of custom coding to re-create this behaviour in web forms, and it's really kludgy to do in AJAX, if you are lucky enough to get something close to this functionality.

5 comments:

Mark Kadlec said...

There was a delay issue on the initial keystroke, here is the thread with solution:

ADmin said...

Depending on if you have custom dissertation sufficient energy to compose the paper then you can brainstorm the theme,

Anonymous said...

Its a great pleasure reading your post.Its full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work. great-term-paper.com

paulsmith198914@gmail.com said...

It was a real journey to read your genuine content. I just stopped by to welcome you to our custom writing essay website, if you need a fully-fledged essay done in less than 24 hours!

Professional Writers Online said...

This is a great post. Are you in search of reliable reliable Nursing PICO Essay Writers UK online who can help you. Link with reliable Dissertation Writing Help online for best dissertation writing services at affordable rates. We also offer cheap essay writing services at affordable rates.