C#|XAML : ListBox – Search, Filter, and Highlight (1/3)

C#|XAML : ListBox – Search, Filter, and Highlight (1/3)

In this 3 part series we will go through c#/XAML code to setup Listbox with multiple rows of information having ability to search, filter and highlight the text in searched items. To see the actual running code of this ListBox in live app, you can check my app. The topics of different parts in this series are as follows:

  • Part 1: Set-up form with TextBox and ListBox with example model class
  • Part 2: Add search and filter ability
  • Part 3: Highlight searched text

Setup Test XAML Form

This is our default MainPage.XAML. We will add a TextBox control and a ListBox control to this page. TextBox control is where we will input the text to be searched in the ListBox items. ListBox will show items. Each item has three information fields. These fields are: Name, Address, and Note. Let’s first update the XAML created by Studio.

Replace the default “ContentPanel” control with following Grid:

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="80"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <TextBox Grid.Row="0" x:Name="textBoxSearch" KeyUp="textBoxSearch_KeyUp"/>
            <ListBox Grid.Row="1" x:Name="listBoxTextItems"></ListBox>
        </Grid>

Create ViewModel Class

The class which feeds data to the ListBox is Profile and contains three basic properties : Name, Address, and Note. For the sake of keeping this example simple, let’s write this class in the code-behind, MainPage.xaml.cs (please note, in real world, ViewModel classes do not go in the code-behinds and they usually have mechanism to broadcast change messages to UI. To keep the focus on the subject in hand, we are only writing just the essential code).

    public class Profile
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string Note { get; set; }
        public Profile(string name, string add, string note)
        {
            Name = name;
            Address = add;
            Note = note;
        }
    }

Create List and connect View and ViewModel

Let’s first update MainPage.XAML to add CollectionViewSource to its resources and bind it to the ListBox. We need CollectionViewSource to filter our data in the view.

    <phone:PhoneApplicationPage.Resources>
        <CollectionViewSource x:Name="textListViewSource">
        </CollectionViewSource>
    </phone:PhoneApplicationPage.Resources>

Update the ListBox definition to add the CollectionViewSource:

            <ListBox Grid.Row="1" x:Name="listBoxTextItems" ItemsSource="{Binding Source={StaticResource textListViewSource}}">

We also want our ListBox to show these items in different sizes and colors so that three different rows in each item can be differentiated visually. So, we will add a visual template for ListItem and assign it to the ListBox.

The style definition will go in the Resources section:

        <Style x:Key="styleInfoTextListBox" TargetType="ListBoxItem">
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid x:Name="gridDataTemplate" Margin="15,5,5,5">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <TextBlock Grid.Row="0" x:Name="templateTextBlockName" Text="{Binding Name}" FontFamily="Segoe WP Black" FontSize="{StaticResource PhoneFontSizeExtraLarge}" Foreground="White"/>
                            <TextBlock Grid.Row="1" x:Name="templateTextBlockAdd" Text="{Binding Address}" FontFamily="Segoe WP" FontSize="{StaticResource PhoneFontSizeLarge}" Foreground="White" Opacity="0.8"/>
                            <TextBlock Grid.Row="2" x:Name="templateTextBlockNote" Text="{Binding Note}" FontFamily="Segoe WP Light" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="White" Opacity="0.8"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Update the ListBox definition one last time to apply the style on ListItems to add the CollectionViewSource:

<ListBox Grid.Row="1" x:Name="listBoxTextItems" ItemsSource="{Binding Source={StaticResource textListViewSource}}" ItemContainerStyle="{StaticResource styleInfoTextListBox}">

Our ListBox is ready to show the data. Now let’s switch back to MainPage.xaml.cs. We will create an ObservableCollection of Profile type and add some example data to it. We will write this code in MainPage.xaml.cs. Also in the constructor of our page we will set CollectionViewSource’s source and ListBox’s DataContext to connect our list with the data. Our MainPage.xaml.cs will look like this:

    public partial class MainPage : PhoneApplicationPage
    {
        ObservableCollection<Profile> _infoList = new ObservableCollection<Profile>();
        // Constructor
        public MainPage()
        {
            InitializeComponent();

            _infoList.Add(new Profile("A Kejriwal", "New Delhi, India", "I am common man A"));
            _infoList.Add(new Profile("Bill Gates", "One Microsoft, Redmond", "I am not a common man"));
            _infoList.Add(new Profile("Bill Burr", "Comedy Central", "Don't say there is no reason"));
            _infoList.Add(new Profile("Kartavya Sharma", "Street dhimka", "What do you mean?"));
            _infoList.Add(new Profile("Louis CK", "HBO One Night", "Bill curses a lot in comedy"));
            _infoList.Add(new Profile("Sanjay Sharma", "Street falana", "What do you mean?"));
            _infoList.Add(new Profile("Z Kejriwal", "New Delhi, India", "Don't underestimate the power"));

            textListViewSource.Source = _infoList;
            listBoxTextItems.DataContext = _infoList;
        }
    }

Let’s F5 our form. You should see this on your emulator:
List

In next post we will write code to respond to search query in TextBox and filter data in ListBox.

To be contd… Part 2

Advertisements

7 thoughts on “C#|XAML : ListBox – Search, Filter, and Highlight (1/3)

  1. Pingback: C#|XAML : ListBox – Search, Filter, and Highlight (2/3) | Sharp Statements

  2. Pingback: Dew Drop – March 3, 2014 (#1734) | Morning Dew

  3. Pingback: C#|XAML : ListBox – Search, Filter, and Highlight (3/3) | Sharp Statements

  4. I have a doubt ,

    Situation:
    i have a main page xaml whose data context is set to MainVieweModelSampleData.xaml , i have a MainViewModel class that contains a collection named “Problems” of type ItemViewModel class , i have a loadData function in MainviewModel class where ItemViewModel class is instantiated and instances are added to Problems collection , i want to implement the Search box in my main page .

    My doubt is :
    1.where do i put the statements
    textListViewSource.Source = Problems;
    listBoxTextItems.DataContext = Problems;
    if i put them in loadData() function , i get red lines saying textListViewSource and listBoxTextItems are not ecognized .
    if i put them in mainPage constructor that Problems is not recognized , where do i put them .

    2.What is the difference between datacontext and Itemsource tag of listbox control ?

  5. Hi Varun, I would strongly recommend that you go through all the the three blog posts in the series, create project and copy/paste the code from posts into the project as mentioned in the posts. Most of the things are explained in the posts step-by-step.

    As far your specific problem, you should this:

    1. Ensure “Problems” collection is public
    2. One your page is loaded, call your LoadData method from your main page.
    3. Have an event in your class, when your LoadData finishes, fire this event.
    4. In your MainPage (where your search is) have an EventHandler to attach to the event you defined in step 3.
    5. In the constructor of MainPage, register EventHandler to the event of the class.
    6. In the method, which this EventHandler points to, write those two lines of code which are giving you red lines. Remember, you can access XAML controls in your code-behind only (not in the class as you are trying), in your case it is MainPage.xaml.cs.

    Hope this helps!

  6. I strictly followed yr steps but still i am not seeing any data in the emulator (Though the red lines are gone ) . Sir i have messaged u the link for my app source code in yr facebook account

    i request u to please unzip the file and check whether i have commited any mistakes in executing yr
    steps or not

    and one more thing sir , inorder to see the data in the designer window please change the Itemsource
    property to Itemsource={Binding Problems}.

    please help me out sir ,
    Thank you sir

  7. Pingback: Dynamically highlighting textbox parts when filtering | Around computing

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s