Advertisement

Getting started with Silverlight: Part 5 – Integrating other controls

This is part 5 in a series on getting started with Silverlight.  To view the index to the series click hereYou can download the completed project files for this sample application in C# or Visual Basic.

In our previous step we added better data binding and saved some data to our isolated storage area.  Let’s start integrating some other controls to make our experience a little better.

AutoCompleteBox

Remember the history data we save every time a search term is used?  Let’s help our users search better, by providing them a history of their searches in the TextBox while they type.  We’re going to use a control from the Silverlight Toolkit to accomplish this, AutoCompleteBox.

To do this we need to add a reference to the System.Windows.Controls.Input assembly.  Then add an xmlns to your Search.xaml file:

   1: xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"

With this in place, change the control named SearchTerm from TextBox to input:AutoCompleteBox:

   1: <input:AutoCompleteBox x:Name="SearchTerm" FontSize="14.667" Margin="0,0,10,0" Width="275"
   2:      IsTextCompletionEnabled="True" />

Now we need to provide data for the AutoCompleteBox.  In our Helper.cs class I added the following function:

   1: internal static string[] GetSearchTermHistory()
   2: {
   3:     List<string> searchHistory = new List<string>();
   4:  
   5:     foreach (var item in IsolatedStorageSettings.ApplicationSettings.Keys)
   6:     {
   7:         searchHistory.Add(item.ToString());
   8:     }
   9:  
  10:     return searchHistory.ToArray();
  11: }

Then in the Loaded event handler for Search.xaml.cs I added a call to Helper.GetSearchTermHistory():

   1: void Search_Loaded(object sender, RoutedEventArgs e)
   2: {
   3:     SearchResults.ItemsSource = pcv; // bind the DataGrid
   4:     _timer.Start(); // start the timer
   5:     SearchForTweetsEx(); // do the initial search
   6:     SearchTerm.ItemsSource = Helper.GetSearchTermHistory(); // populate autocomplete
   7: }

The result of which now is that when the application loads it will give the user some hinting while they search:

AutoCompleteBox in action

Helpful!

Adding our History view

Now that we have our search history, we can provide some data in a new view called History.xaml.  You should have already created this in the Views folder in a previous step, but if you haven’t, do so now (using the Silverlight Page item template).  Here we’ll want to show perhaps a simple list of all the terms.  We can easily do this using a ListBox in our XAML like this:

   1: <StackPanel>
   2:     <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}" 
   3:                    Text="Serach Term History"/>
   4:     <ListBox x:Name="SearchTermHistory" />
   5: </StackPanel>

Then using a function we already have in Helper.cs, we can bind new data to the listbox like this in History.xaml.cs:

   1: protected override void OnNavigatedTo(NavigationEventArgs e)
   2: {
   3:     SearchTermHistory.ItemsSource = Helper.GetSearchTermHistory();
   4: }

So we are able to make re-use of a function to display a complete history of our terms:

History pane view

Adding some more navigation functionality

Now that we have a couple of views in the application, notice the navigation framework working.  You can navigate using the buttons, but also the back/forward browser buttons will also trigger the same functionality!

We can actually take this to the next level with the History view now.  In the ListBox I’m adding a SelectionChanged event handler:

   1: <ListBox x:Name="SearchTermHistory" SelectionChanged="SearchTermHistory_SelectionChanged" />

The function looks like this in History.xaml.cs:

   1: private void SearchTermHistory_SelectionChanged(object sender, SelectionChangedEventArgs e)
   2: {
   3:     this.NavigationService.Navigate(new Uri(string.Format("/Search/{0}", 
   4:             SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));
   5: }

Notice the URI format I’m using?  It will end up being /Search/{term}.  We need to instruct our Navigation Frame in the application to map that accordingly.  Go back to MainPage.xaml and find the UriMapper content and add this line:

   1: <uriMapper:UriMapping Uri="/Search/{term}" MappedUri="/Views/Search.xaml?term={term}" />

Now we need to make our Search.xaml page understand this.  In Search.xaml.cs in the OnNavigatedTo I add this functionality:

   1: protected override void OnNavigatedTo(NavigationEventArgs e)
   2: {
   3:     if (this.NavigationContext.QueryString.ContainsKey("term"))
   4:     {
   5:         SearchTerm.Text = this.NavigationContext.QueryString["term"].ToString();
   6:         SearchForTweetsEx();
   7:     }
   8: }

Now when a user goes to the History page and selects an item, it automatically executes the search!

Summary

Integrating other controls and 3rd party controls like this will help define your user experience and hopefully provide an better experience for your users of the application.  There are a bunch of 3rd party control vendors producing great sets of components.  Visit my Silverlight Controls post for a list of them.  Be sure to check out the Silverlight Toolkit for others from Microsoft and a sample application showing all the controls.

We’ve got our application pretty well working, but the UI could use some more polish, in the next step in part 6 let’s show how we can better template this without affecting functionality.


This work is licensed under a Creative Commons Attribution By license.

  1. 10/10/2009 2:19 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Really helpfull tutorial!

    Just to avoid that others run in the same trap too:
    The mentioned additional line in the UriMapper content:

    <uriMapper:UriMapping Uri="/Search/{term}" MappedUri="/Views/Search.xaml?term={term}" />

    has to be inserted before

    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/> !

    Adding it after will end up with some navigation error messages, because the first matching Mapping is used.
  2. 10/13/2009 11:13 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Very Helpful, thank you!

    Probably, it would be better to fill the AutoCompleteBox items after each search, so the auto-complete suggests recent user entries too. As for now it only suggests strings from previous application runs.

    Move this:
    SearchTerm.ItemsSource = Helper.GetSearchTermHistory(); // populate autocomplete

    from loaded event:
    void Search_Loaded(object sender, RoutedEventArgs e)

    to somewhere like:
    SearchForTweetsEx();
  3. Gravatar
    11/3/2009 7:36 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Very Helpful.Thank you very much
  4. 11/10/2009 4:03 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Where did I miss the creation of the SearchForTweetsEx function?
  5. 11/10/2009 4:19 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Mark M - you didn't...thanks for calling me out -- it wasn't clear in this section: timheuer.com/.../...ted-part-3-accessing-data.aspx
  6. 11/10/2009 5:02 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Ok, now that that is straightended out :-) tks, but..
    Each time I select an item in the history list an error is thrown Page not Found: "/Search/twitpic".

    Why?

    Below is code for selectionchanged event handler and the UriMapper and
    private void SearchTermHistory_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    this.NavigationService.Navigate(new Uri(String.Format("/Search/{0}", SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));
    }

    <navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
    Source="/Search" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
    <navigation:Frame.UriMapper>
    <uriMapper:UriMapper>
    <uriMapper:UriMapping Uri="" MappedUri="/Views/Search.xaml"/>
    <uriMapper:UriMapping Uri="/{pageName}/{searchtext}" MappedUri="/Views/{pageName}?term={searchterm}"/>
    <uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
    </uriMapper:UriMapper>
    </navigation:Frame.UriMapper>
    </navigation:Frame>
  7. 11/10/2009 5:21 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Mark M - I can't reproduce that error. I even changed my mapper to match yours. Feel free to send me your project offline to see if it fails on my box.
  8. 11/10/2009 6:06 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Hi Tim,

    I would send you my project but I don't know how I can do this from here. Perhaps you could respond with instructions to my email address?
  9. 11/10/2009 6:10 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    nvn Tim. found it. Thanks again!
  10. Gravatar
    11/25/2009 9:06 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    I have the same problem as Marc M and I don't know how to fix the problem
  11. 11/25/2009 9:07 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Max -- Marc fixed his issue. Make sure that your UriMapping is corrrect and doesn't have any mismatched parameters.
  12. Gravatar
    11/25/2009 9:18 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    I found an error! Our uriMapper must be the first in the list. Here's the code:

    <navigation:Frame.UriMapper>
    <uriMapper:UriMapper>
    <uriMapper:UriMapping
    Uri="/Search/{term}"
    MappedUri="/Views/Search.xaml?term={term}"/>
    <uriMapper:UriMapping
    Uri=""
    MappedUri="/Views/Search.xaml"/>
    <uriMapper:UriMapping
    Uri="/{pageName}"
    MappedUri="/Views/{pageName}.xaml"/>
    </uriMapper:UriMapper>
    </navigation:Frame.UriMapper>
    My URI was the last and how I think its something catch before
  13. 12/31/2009 4:15 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    hello Tim. MANY thanks for this awesome tutorial. i have learned so much about silverlight and am stoked to finish it out. one thing i noticed while testing this lesson is that the tweets are duplicated when clicking on a search term in the history view (i downloaded your source and was able to duplicate it).

    after setting some breakpoints, leveraging the callstack, and nosing around i believe this is happening because two SearchForTweetsEx calls are made when the search view is navigated to: one from the OnNavigatedTo event and one from the Loaded event (wired up to Search_Loaded). both async calls come back with the same tweets for me since the _lastId loaded from the IsolatedStorageSettings were the same when both calls to the twitter api were made. i suppose if the first async call came back, processed the first (latest) response from twitter and immediately stored the is of this latest tweet in IsolatedStorageSettings before the second call is sent then this problem wouldn't occur? my head hurts...

    if you decide to step in the code to observe this behavior i would recommend commenting out the DispatchTimer's Tick event wireup. at any rate i fixed mine by commenting out the call to SearchForTweetsEx in OnNavigatedTo and allowing the Loaded event to take care of calling SearchForTweetsEx. please let me know your thoughts. my apologies if i did something stupid and am not troubleshooting this correctly (wouldn't be the first time). again--thanks so much for this INCREDIBLE tutorial. you rock!
  14. Gravatar
    1/11/2010 1:52 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Hello Tim. Excellent blog series! I played around with Silverlight in the past and was a bit disappointed with it's RAD capabilities and use in the Enterprise space. However, in light of the advancements since 1.0, I thought I'd give it another go. While I still don't believe the tools and data-binding capabilities are on par with other Microsoft development solutions, Silverlight has come a long way in a short period of time. Kudos to your team. I look forward to the future of Silverlight and quit possibly implementing a Silverlight Enterprise application in the Government space. Oh and BTW, good luck with that dive shop of yours... -Dan
  15. 1/17/2010 9:34 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    Look at /Search/ onwards...

    this.NavigationService.Navigate(new Uri(string.Format("/Search/{0}", SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));

    should be changed to

    this.NavigationService.Navigate(new Uri(string.Format("/Search?term={0}", SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));

    Cheers, Christian
  16. 2/9/2010 1:38 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    I'm following along and everything works great so far, except that I'm getting the tweets repeated. In other words, when I search on a term the first time it works fine, then if I do nothing, and the timer event kicks off, the search is done again, and the results are added to the current list (sorted) so now at this point, I'm seeing doubles of everything. I'm not sure if there's something that I missed. Anyone else having this problem?
  17. 2/22/2010 9:07 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    I for some reason can not get any scroll bars, I don't understand why.

    Thanks
  18. 3/10/2010 10:10 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
    I am also getting duplicate entries. I have commented out the call to searchfortweetsEx() in the navigated_to event handler yet the issue remains. I will have to debug some to find the cause.

    Also, I am getting inconsistent results with the search...sometimes it wants to bring me stuff and other times it doesn't. Sometimes it acts like my searchterm is an invalid twitterID but I can search the same term a few seconds later and sometimes I get results. Not sure what is going wrong here.

 
Please add 1 and 3 and type the answer here:
First time here? You are looking at the most recent posts. You may also want to check out older archives. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS or email. Thank you for visiting! (hide this)