Intersoft ClientUI Documentation
Walkthrough: Use UXSearchBox to Show Search Results with MVVM Pattern

This walkthrough shows you how to create a UXSearchBox to search item in collection of data. This walkthrough demonstrates the following concept:

Prerequisites

You need the following components to complete this walkthrough:

Creating a new ClientUI MVVM Application Project

The first step is to create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template in Visual Studio.

To create the ClientUI MVVM Application project

  1. Start Visual Studio 2010.
  2. Create a new ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template. To learn more, see Walkthrough: Create New Intersoft ClientUI MVVM Application Template.
  3. In project reference, add System.Xml.Linq.dll. This assembly is required to perform LINQ query to xml data.

To add the data file

  1. In your project, copy the Samples.xml from [Intersoft Installation Folder]\Intersoft WebUI Studio 2010 R1\Samples\SL4\ClientUI Samples\Intersoft.ClientUI.Samples.InputControls].
  2. Click on the Samples.xml file and press F4 to open the Property Window. Change the Build Action property to Resources

Creating the Model

This section shows how to create a Model class in SampleData.cs. The model will map  information in the data entity to a property.

To create the SampleData model

  1. Create SampleData.cs in the Models folder and inherit the ModelBase class.
  2. Create a private variable and a public property to hold DisplayName attribute with a String data type. OnPropertyChanged method must be called after the property is assigned a new value.
    C#
    Copy Code
    private string _displayName;
    
    public string DisplayName
    {
        get { return this._displayName; }
        set
        {
            if (this._displayName != value)
            {
                string description = value;
                description = description.Replace("||", "\r\n");
    
                this._displayName = description;
                this.OnPropertyChanged("DisplayName");
            }
        }
    }
  3. Repeat the above process for Name and Uri attribute. Both require String data type.
  4. Create SampleData constructor using XElement parameter to map each attribute to the property.
    C#
    Copy Code
    public SampleData(XElement i)
    {
        this.Name = i.Attribute("Name").Value.ToString();
    
        string displayName = i.Attribute("DisplayName").Value.ToString();
        this.DisplayName = (string.IsNullOrEmpty(displayName) ? this.Name : displayName);
    
        this.Uri = i.Attribute("Uri").Value.ToString();          
    }

Creating the ViewModel

This section shows how to create a ViewModel to hold the collection of SampleData and the selected SampleData model object . In order to implement search, the UXSearchBox requires IsSearching, QueryText and SearchResult property.

To create the SearchViewModel ViewModel

  1. Create the SearchViewModel.cs in ViewModels folder.
  2. Create two collection to hold SampleData object. One will be used to hold all the SampleData object and the other one will hold the search result. The search result property need to call OnPropertyChanged method after a new value is assigned.
    C#
    Copy Code
    public ObservableCollection<SampleData> Samples { get; set; }
    
    private ObservableCollection<SampleData> _searchResult;
    
    public ObservableCollection<SampleData> SearchResult
    {    get { return this._searchResult; }
        set
        {
            if (this._searchResult != value)
            {
                this._searchResult = value;            this.OnPropertyChanged("SearchResult");
            }    }
    }
  3. Create a property to hold the text inputted in the UXSearchBox.
    C#
    Copy Code
    private string _queryText;
    
    public string QueryText
    {
        get { return this._queryText; }
        set
        {
            if (this._queryText != value)
            {
                this._queryText = value;
                this.OnPropertyChanged("QueryText");
            }
        }
    }
  4. Create a constructor which will load and parse the SampleData.xml.
    C#
    Copy Code
    public SearchViewModel()
    {
        this.LoadSamples();
    }
    
    private void LoadSamples()
    {
        StreamResourceInfo resource = System.Windows.Application.GetResourceStream(new Uri("/ClientUIMVVMSearchBox;component/Samples.xml", UriKind.Relative));
    
        XDocument doc = XDocument.Load(resource.Stream);
        var samples = from d in doc.Descendants("SampleItem")
                        select new SampleData(d);
    
        foreach (SampleData sample in samples)
        {
            this.Samples.Add(sample);
        }
    
        resource.Stream.Close();
    }
  5. Create a property to indicate the searching status of the UXSearchBox. Assigning a new value triggers the searching logic. The searching logic is implemented in the next step using a method.
    C#
    Copy Code
    private bool _isSearching;
    
    public bool IsSearching
    {
        get { return this._isSearching; }
        set
        {
            if (this._isSearching != value)
            {
                this._isSearching = value;
                this.OnPropertyChanged("IsSearching");
                this.DoSearch();
            }
        }
    }
  6. Create a method to implement the searching logic.
    C#
    Copy Code
    private void DoSearch()
    {
        var query = from q in this.Samples
            where q.DisplayName.ToLower(CultureInfo.InvariantCulture).Contains(this.QueryText.ToLower(CultureInfo.InvariantCulture))
            select q;
    
        ObservableCollection<SampleData> data = new ObservableCollection<SampleData>();
        foreach (SampleData d in query)
        {
            data.Add(d);
        }
    
        this.SearchResult = data;
        this.IsSearching = false;
    }
  7. Add a new private variable and public property to hold the UXSearchBox SelectedItem. Selecting a new item cause a MessageBox with the Uri information to appear.
    C#
    Copy Code
    private SampleData _selectedSampleData;
    
    public SampleData SelectedData
    {
        get
        {
            return _selectedSampleData;
        }
        set
        {
            if (_selectedSampleData != value)
            {
                _selectedSampleData = value;
                this.OnPropertyChanged("SelectedData");
    
                MessageBoxServiceProvider.Show("Navigate to uri: " + _selectedSampleData.Uri, null);
            }
        }
    }

Creating the View

This section describes how to create the view with the UXSearchBox.

To create the Search view

  1. Add a new UXPage to the Views folder in your Silverlight project and name it Search.xaml.
    For more information on how to add a new item in Visual Studio, see Walkthrough: Add New Item such as Page, Dialog Box and Window in VS 2010
  2. Declare the namespace that maps to the SearchViewModel class.
    XAML
    Copy Code
    <Intersoft:UXPage 
        ...
        xmlns:ViewModels="clr-namespace:ClientUIMVVMSearchBox.ViewModels"
        ...
        >
        ...
    </Intersoft:UXPage>
  3. Reference the SearchViewModel as the page DataContext.
    XAML
    Copy Code
    <Intersoft:UXPage.DataContext>
        <ViewModels:SearchViewModel/>
    </Intersoft:UXPage.DataContext>
  4. Add UXSearchBox. Set the following properties:
    Property Value
    HorizontalAlignment Left
    VerticalAlignment Top
    Margin 12,12,0,0
    Width 300
    DisplayMemberPath DisplayName
    AutoShowResultBox True
    WatermarkTextVisibility Visible
    WatermarkText Enter keyword
    WatermarkForeground Black
    Locate the IsSearching property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding Options...
    3. From the Tab Path, select IsSearching 
    4. From the Tab Options, set Mode to TwoWay
    Locate the QueryText property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding Options...
    3. From the Tab Path, select QueryText
    4. From the Tab Options, set Mode to TwoWay
    Locate the SearchResult property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding Options...
    3. From the Tab Path, select SearchResult
    Locate the SelectedData property.
    1. Click the ellipsis button in the header property column, a context menu will appear
    2. Select the Apply DataBinding Options...
    3. From the Tab Path, select SelectedData
    4. From the Tab Options, set Mode to TwoWay
    XAML
    Copy Code
    <Intersoft:UXSearchBox HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="300" DisplayMemberPath="DisplayName" WatermarkTextVisibility="Visible" WatermarkText="Enter keyword" AutoShowResultBox="True" WatermarkForeground="Black" IsSearching="{Binding IsSearching, Mode=TwoWay}" QueryText="{Binding QueryText, Mode=TwoWay}" SearchResult="{Binding SearchResult}" SelectedItem="{Binding SelectedData, Mode=TwoWay}"/>
            

Viewing the Result

In order to view the result, you will need to build the Silverlight project and run the test page in the browser.

To view the result

  1. Try inputting or in the UXSearchBox.
  2. The dropdown will be populated with SampleData which contains or in its DisplayName.
  3. Selecting an item will popup a MessageBox with the Uri information.

Conclusion

In this walkthrough, you have learned how to create ClientUI MVVM Application project using Intersoft ClientUI MVVM Application project template, and create classes and page based on the MVVM pattern. You also learned how to utilize search feature in UXSearchBox.

For more information about application development using MVVM pattern, see MVVM Pattern Overview. For more information about UXSearchBox control, see UXSearchBox Overview.

Complete Code Listing

This section lists the complete code used in this walkthrough.

SampleData.cs

C#
Copy Code
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;
using ClientUIMVVMSearchBox.ViewModels;

namespace ClientUIMVVMSearchBox.Models
{
    public class SampleData : ModelBase
    {
        #region Constructors

        public SampleData()
        {
        }

        public SampleData(XElement i)
        {
            this.Name = i.Attribute("Name").Value.ToString();

            string displayName = i.Attribute("DisplayName").Value.ToString();
            this.DisplayName = (string.IsNullOrEmpty(displayName) ? this.Name : displayName);

            this.Uri = i.Attribute("Uri").Value.ToString();          
        }

        #endregion

        #region Fields

        private string _displayName;
        private string _name;
        private string _uri;

        #endregion

        #region Properties

        public string DisplayName
        {
            get { return this._displayName; }
            set
            {
                if (this._displayName != value)
                {
                    string description = value;
                    description = description.Replace("||", "\r\n");

                    this._displayName = description;
                    this.OnPropertyChanged("DisplayName");
                }
            }
        }

        public string Name
        {
            get { return this._name; }
            set
            {
                if (this._name != value)
                {
                    this._name = value;
                    this.OnPropertyChanged("Name");
                }
            }
        }



        public string Uri
        {
            get { return this._uri; }
            set
            {
                if (this._uri != value)
                {
                    this._uri = value;
                    this.OnPropertyChanged("Uri");
                }
            }
        }

        #endregion
    }
}

SearchViewModel.cs

C#
Copy Code
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using ClientUIMVVMSearchBox.Models;
using System.Globalization;
using System.Linq;
using System.Windows.Resources;
using System.Xml.Linq;

namespace ClientUIMVVMSearchBox.ViewModels
{
    public class SearchViewModel : ViewModelBase
    {
        public SearchViewModel()
        {
            this.LoadSamples();
        }

        private bool _isSearching;
        private string _queryText;
        private ObservableCollection<SampleData> _samples;
        private ObservableCollection<SampleData> _searchResult;
        private SampleData _selectedSampleData;

        public bool IsSearching
        {
            get { return this._isSearching; }
            set
            {
                if (this._isSearching != value)
                {
                    this._isSearching = value;
                    this.OnPropertyChanged("IsSearching");
                    this.DoSearch();
                }
            }
        }

        public string QueryText
        {
            get { return this._queryText; }
            set
            {
                if (this._queryText != value)
                {
                    this._queryText = value;
                    this.OnPropertyChanged("QueryText");
                }
            }
        }


        public ObservableCollection<SampleData> Samples
        {
            get
            {
                if (this._samples == null)
                    this._samples = new ObservableCollection<SampleData>();

                return this._samples;
            }
        }

        public ObservableCollection<SampleData> SearchResult
        {
            get { return this._searchResult; }
            set
            {
                if (this._searchResult != value)
                {
                    this._searchResult = value;
                    this.OnPropertyChanged("SearchResult");
                }
            }
        }

        private void DoSearch()
        {
            var query = from q in this.Samples
                        where q.DisplayName.ToLower(CultureInfo.InvariantCulture).Contains(this.QueryText.ToLower(CultureInfo.InvariantCulture))
                        select q;

            ObservableCollection<SampleData> data = new ObservableCollection<SampleData>();

            foreach (SampleData d in query)
            {
                data.Add(d);
            }

            this.SearchResult = data;
            this.IsSearching = false;
        }

        private void LoadSamples()
        {
            StreamResourceInfo resource = System.Windows.Application.GetResourceStream(
                    new Uri("/ClientUIMVVMSearchBox;component/Samples.xml", UriKind.Relative));

            XDocument doc = XDocument.Load(resource.Stream);
            var samples = from d in doc.Descendants("SampleItem")
                          select new SampleData(d);

            foreach (SampleData sample in samples)
            {
                this.Samples.Add(sample);
            }

            resource.Stream.Close();
        }

        public SampleData SelectedData
        {
            get
            {
                return _selectedSampleData;
            }
            set
            {
                if (_selectedSampleData != value)
                {
                    _selectedSampleData = value;
                    this.OnPropertyChanged("SelectedData");

                    MessageBoxServiceProvider.Show("Navigate to uri: " + _selectedSampleData.Uri, null);
                }
            }
        }
    }
}

Search.xaml

XAML
Copy Code
<Intersoft:UXPage 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Intersoft="http://intersoft.clientui.com/schemas"
    xmlns:ViewModels="clr-namespace:ClientUIMVVMSearchBox.ViewModels"
        mc:Ignorable="d"
        x:Class="ClientUIMVVMSearchBox.Views.Search" 
        Title="Search Page"
        d:DesignWidth="640" d:DesignHeight="480">
        
    <Intersoft:UXPage.DataContext>
        <ViewModels:SearchViewModel />
    </Intersoft:UXPage.DataContext>
    
        <Grid x:Name="LayoutRoot">
        <Intersoft:UXSearchBox HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="300" DisplayMemberPath="DisplayName" WatermarkTextVisibility="Visible" WatermarkText="Enter keyword" AutoShowResultBox="True" WatermarkForeground="Black" IsSearching="{Binding IsSearching, Mode=TwoWay}" QueryText="{Binding QueryText, Mode=TwoWay}" SearchResult="{Binding SearchResult}" SelectedItem="{Binding SelectedData, Mode=TwoWay}"/>
        </Grid>
</Intersoft:UXPage>
See Also

Concepts

Other Resources