Skip to main content Skip to footer

Using the Windows 8 Search Charm with C1CollectionView and C1FlexGrid

With the C1CollectionView class you can filter your data collection in an easy and familiar fashion. C1CollectionView is a more powerful implementation of the ICollectionView interface that includes support for sorting, filtering and grouping. If you come from WPF or Silverlight and are used to working with CollectionView, then you will love C1CollectionView for WinRT. In this blog post I show how you can hook up the Windows 8 Search Charm to apply a filter on a C1FlexGrid control using C1CollectionView. This sample could also apply to any UI control that is bound to a C1CollectionView too. The Windows 8 Search charm is a fast and simple way for users to search across their computer. They can search within the running app, across files, settings or even search within terminated applications. Let’s say you have an application containing some data and you would like to filter that data when the user performs a search using the Search charm. Here are the basic steps you need to follow:

  1. Declare the Search contract in your Package.appmanifest file. This lets Windows know that your app can be activated from the search charm.
  2. Handle the OnSearchActivated event in your App.xaml.cs file. This is the entry point to your app from Windows which is invoked when your app is activated to show search results.
  3. (Optionally) Give search term suggestions to Windows that show below the search box. I won’t demonstrate this in this blog post.
  4. Perform your search or filter logic given the search query. This is where we will take advantage of C1CollectionView to do our filtering for us.

The first two steps are very easy to implement. Infact, if you add a Search Contract file (see figure on right) to your application Visual Studio wires up these two steps for you including creating your own Search Results page. Regardless of how you declare the Search contract, we won’t be using the standard Search Results page because we will display our results on the same page hosting our FlexGrid control by simply filtering the data. The C1CollectionView class makes it easy to achieve step 4. All you have to do is add a Filter predicate to the view. Sound confusing? Once you see an example it will make a lot more sense. First, we add the Search Declaration in the Package.appmanifest file. Second, we handle the OnSearchActivated event in App.xaml.cs. Here we can access the search query from the user and pass this to our page containing FlexGrid by way of navigation parameters.


/// <summary>  
/// Invoked when the application is activated to display search results.  
/// </summary>  
/// <param name="args">Details about the activation request.</param>  
protected async override void OnSearchActivated(Windows.ApplicationModel.Activation.SearchActivatedEventArgs args)  
{  
    await EnsureMainPageActivatedAsync(args);  

    // If the Window isn't already using Frame navigation, insert our own Frame  
    var previousContent = Window.Current.Content;  
    var frame = previousContent as Frame;  

    frame.Navigate(typeof(MainPage), args.QueryText);  
    Window.Current.Content = frame;  

    // Ensure the current window is active  
    Window.Current.Activate();  
}  

Lastly, we handle the search query parameter on our main page containing C1FlexGrid (or SearchResultsPage if you added the Search Contract template). Here’s the XAML to create the C1FlexGrid and C1CollectionView.


<common:LayoutAwarePage.Resources>  
    <!--  
        C1CollectionView created in XAML  
    -->  
    <c1:C1CollectionView x:Name="customersView" />  
</common:LayoutAwarePage.Resources>  
<!-- Horizontal scrolling grid used in most view states -->  
<c1fg:C1FlexGrid x:Name="itemFlexGrid"  
                 AutomationProperties.AutomationId="ItemFlexGrid"  
                 AutomationProperties.Name="All Items"  
                 ItemsSource="{Binding Source={StaticResource customersView}}"  
                 Margin="116, 0, 40, 46"  
                 SelectionMode="Row">  

</c1fg:C1FlexGrid>  

In this sample I’m using a LayoutAwarePage that you can create by adding the “Basic Page” template to your project. In the LayoutAwarePage.LoadState event we create the Filter predicate on the C1CollectionView class based upon the search query parameter. In this case we only filter against the Name and Country fields from our data source.


protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)  
{  
    // bind c1CollectionView to our source collection from view model  
    var customers = CustomerDataSource.GetCustomers();  
    customersView.SourceCollection = customers;  

    if (navigationParameter != null)  
    {  
        // set filter based on search query  
        string query = navigationParameter.ToString().ToLower();  
        customersView.Filter = delegate(object item)  
        {  
            Customer c = item as Customer;  
            if (c != null)  
            {  
                if (c.Country.ToLower().Contains(query) ||  
                    c.Name.ToLower().Contains(query))  
                    return true;  
            }  
            return false;  
        };  
    }  
}  

Conclusion

Download the complete sample below. It’s modeled after the GridApp and SplitApp project templates which do not strictly follow MVVM principles. While the C1CollectionView class is designed especially for MVVM usage, this sample shows how you can use it in a non-MVVM way like the project templates provided by Microsoft. Download FlexGrid Search

ComponentOne Product Manager Greg Lutz

Greg Lutz

comments powered by Disqus