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.

Monday, November 2, 2009

Halloween candy consolidation?

It occurred to me while raiding looking through my son’s Halloween candy yesterday, that all people bought the same candy to give out to treaters. In fact, I think if I held up my son’s loot next to the Costco "mixed" snack size candy, they would be identical.

Apart from M and M’s, snickers, butterfinger, and Hersheys snack size candy, there were no unique candies. If I’m not mistaken, most of the treats came from the same manufacturer, Mars Inc. (or Hersheys). There were also a lot less houses participating, my guess is every second house did not give out treats. My era? 1 in 10 did not participate.

Next year I am going to search for some unique treats, and buy a lot of the full size bars for the cool costumes – let’s treat the kids right!

Thursday, October 8, 2009

My dad was right!


Sometimes I'll admit my dad does things differently (ok, a lot of the times), but after reading a post from my fellow namesake Tim Kadlec, it turns out I've been opening a banana the wrong way my whole life!

My family has made fun of my dad for the past decade for the way he opens the banana, but he was being way more efficient the whole time. A humble lesson for me today, always keep an open mind. Lesson #2, you're never too old to learn a thing or two from your folks.

Check out the video, stem down from now on!

Sunday, July 19, 2009

45 miles of Bongo

I've created a new route that I would like to share with anyone that would like to join me on a killer route that will destroy your legs.

Click here for more detail



The route starts in West Seattle, goes through the heart of Seattle up a neverending ascent up Jackson Street, then goes around Mercer Island. Once around Mercer, you can stop at washrooms and fill your water up because guess what? You are only halfway done. Go back to the Sound, across to West Seattle and loop around the North End of Alki. For the finish take an uninteresting ride through an industrial area to the killer climb known as Highland Park drive. Next to Montreax, this thing will leave you spent.

Monday, July 13, 2009

STP in a day - epilogue

RAD and I got up at 03:15, ate breakfast and drove up to meet the team at 04:30. Nothing like doing an all day ride on 4 hours sleep!

Felt pretty good riding in the morning, Spiz got a flat but overall everything was going smoothly. We ate and rested in Centralia, but soon encountered pretty strong headwinds and most notably the heat! It was 30C outside but felt like 40 on the bike. Frequent water stops helped.

There were plenty of stops, by estimate I ate 6 Peanut butter and jelly sandwiches, 3 turkey wraps, 10 bananas, 6 slices of Banana bread, 10 Fig newtons, 10 Oreos, 5 SweetNSalty bars, 2 Cliff bars, 2 oranges, 2 Gels, 5 bottles of Gatorade, and 10 bottles of water.

We crossed the finish at 8:45p and after stopping to change at the hotel, I enjoyed some tequila and Pork sliders.

Yes, we look like dorks but c'mon, it 05:00 at this point...



Thursday, July 9, 2009

2 days before the Seattle to Portland (STP)

Another sold out event at Cascade so there will be 10,000 riders to contend with on Saturday at 05:00, I'll definitely need a coffee before the race.

I've set a goal this year of riding the STP in a day. It's 330 km and most will ride this in two days. I am one of the insane 2500 riders that will attempt in a single day.
The good news is that the ride is very organized and there are plenty of stops for food and rehydration. I've also trained for this cause I think it will be a long day in the saddle. Hope to finish in under 12 hours.

Team Bike Run Swig consists of The Guth, Spiz, RAD, Suzie, and myself. We will meet at Suzie's at 04:30 (like I said, I'll need coffee!) and bike over to Husky Stadium for pictures and the start.

Pack List:
Bike Shoes
Socks
Shorts and BRS Jersey
iPod Shuffle
Pump
2 Gels/Bars
2 Bottles Gatorade
ID and $$
Cellphone
Sunglasses
Helmet
MultiTool
Spare tube
Tire levers
Race Packet with bib number
Sunscreen

Sunday, June 14, 2009

2009 Flying Wheels Century

Yesterday I rode the 2009 Flying Wheels Century, basically my first organized ride and it was definitely eventful. I learned first hand to "expect the unexpected". I rode with The Guth, Spiz, and Guth's friend Olson AKA "Olly".

We set out from Marymoore at exactly 08:00, I packed only a couple of gels since I heard that the pit stops have tons of food and water. The first hour had a pretty steep hill that left everyone out of breath, but everything seemed pretty normal.

Mile 35 - I pull a muscle in my left calf. Great, I now have 65 more miles gritting my teeth in pain. I decide to just not bend my left ankle for the rest of the ride which semi-works. I thought of Tyler Hamilton at the Tour de France years ago and sucked it up.

Mile 38 - Olly pukes on the side of the road.

Mile 40 - I get a front flat for no apparent reason. Russian guy stops to help me pump - I owe him a beer but don't see him again.

Mile 80 - Everyone is pretty tired and guess what's in store...a 3 mile hill! The folks at Cascade have a sense of humour. :)

Mile 85 - The Guth and I unexpectedly create our killer drink mix. The Guth aptly describes it as "A lemon-lime roundhouse" that nearly knocked us off of our bikes.

Mile 99.5 - Blow my rear tire out. Yes, that number is correct, literally 1/2 mile from the finish I hear a loud gunshot blast and jump off my bike. The photographer 100 yards away yelled "Whoa dude, was that your tire?". I completely blow my rear tire out and have to walk across the finish line.

All in all a great day, very hot conditions but I think we fared pretty well. The pit stops were incredible, I ate delicious food and snacks throughout the day. Spiz had his GPS running so here are the details of the ride. Next stop, STP in a day!