Giving custom look and feel to the ListBox control in Silverlight

SheoNarayan
Posted by in Silverlight category on for Intermediate level | Views : 18601 red flag

This article describes how to give a customize look and feel of the ListBox control in Silverlight. It also explains how to get the selected item value in code behind.
Introduction
Recently, I was working on Silverlight ListBox control and was struggling with giving custom look and feel like we used to do with Data Controls in ASP.NET (Repeater, DataList controls etc.). Fortunately, it is possible is Silverlight ListBox control too. Even we can get the selected record items value in the code behind, the way we used to get in ASP.NET OnRowCommand or OnRowEditing events of Data controls.

If you are new to Silverlight, please read http://www.dotnetfunda.com/articles/article217.aspx article to know few basics and how to start with Silverlight.


Let's see how to do that
In order to explain above mentioned objectives, I shall take example of a an object (a csharp class) having few properties like AutoID, UserName, Contents, ThisDateTime, Active. I shall popuate this object to my ListBox control.

First lets see how to render a ListBox control in Silverlight.

<ListBox x:Name="listScraps" Canvas.Left="12" Canvas.Top="144" Height="450" Width="590">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal" Margin="3">
                            <StackPanel Orientation="Vertical">
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding UserName}" Foreground="Brown"></TextBlock>
                                        <TextBlock Text=" says at "></TextBlock>
                                    <TextBlock Text="{Binding ThisDateTime}" Foreground="Blue"></TextBlock>
                                    <HyperlinkButton Content="Report as spam" Canvas.Left="500" Click="HyperlinkButton_Click" FontSize="8"></HyperlinkButton>
                                </StackPanel>
                                <TextBlock Text="{Binding ScrapContent}" TextWrapping="Wrap" Width="520" />
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
Get solutions of the .NET problems with video explanations, .pdf and source code in .NET How to's.
As per above code-snippet, you can see that first I have written the ListBox control tag. Every ListBox control has property called ItemTemplate, under that we have DataTemplate. DataTemplate is the place where you can write code to give customize look and feel of the ListBox control items. To do that it is suggested to use StackPanel (I have used it, you can directly place your control also but to arrange them in desired order, StackPanel is used.) and its Orientation properties. Orientation properties of the StackPanel has two values, Horizontal and Vertical. As name suggests they render inside contents horizontally and vertically.
To show the data that is coming from the object (the csharp class, I have mentioned above) we can use TextBlock control that has Text property that is used to set the value of the TextBlock control. We can directly mention the text to appear into the TextBlock control if we want static text to appear. But as in this case we want dynamic data to appear so we can mention its Text value as "{Binding FieldName}", here Binding is he syntax we need to use and FieldName can be your database table field name or any property of the object. You can notice in the above code snippet that I have used {Binding UserName}, {Binding ThisDateTime} etc. to display username and datetime values of the record respectively.
If we want to do some record specific activity on click event of the button or hyperlink in the ListBox control, we can place them as well. In this case I have placed a HyperlinkButton control and specified Click event as HyperlinkButton_Click. On click event of this button, I am going to mark that record as spam and deactive that record.
Lets see the server side code now.
To bind the data into the ListBox control, you can use following code snippet, here I am assuming that you are using a web service and your web service has Load method to return the list of objects. To know how to use web service in Silverlight, please read http://www.dotnetfunda.com/articles/article218.aspx
	/// <summary>
        /// Bind the scraps now
        /// </summary>
        private void BindScraps()
        {

            ScrapbookReference.ScrapbookServiceSoapClient scrapService = new ScrapbookApplication.ScrapbookReference.ScrapbookServiceSoapClient();
            scrapService.LoadCompleted += new EventHandler<ScrapbookApplication.ScrapbookReference.LoadCompletedEventArgs>(scrapService_LoadCompleted);
            scrapService.LoadAsync(_ownerID, _count);
        }

        void scrapService_LoadCompleted(object sender, ScrapbookApplication.ScrapbookReference.LoadCompletedEventArgs e)
        {
            System.Collections.ObjectModel.Collection<ScrapbookReference.Scrap> list = e.Result;
            listScraps.ItemsSource = list;
        }

To do record specific activity on the click event of the button, we can use following code snippet. 

private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
        {
            bool confirm = System.Windows.Browser.HtmlPage.Window.Confirm("Are you sure this entry is spam?"); // to get the JavaScript confirmation
            if (confirm)
            {
                HyperlinkButton h = (HyperlinkButton)sender; // get the buton that has been clicked
                ScrapbookReference.Scrap scrap = h.DataContext as ScrapbookReference.Scrap; // get the object from the DataContext

                // call data web service
                ScrapbookReference.ScrapbookServiceSoapClient scrapService = new ScrapbookApplication.ScrapbookReference.ScrapbookServiceSoapClient();
                scrapService.UpdateCompleted += new EventHandler<ScrapbookApplication.ScrapbookReference.UpdateCompletedEventArgs>(scrapService_UpdateCompleted);
                scrapService.UpdateAsync(scrap.AutoID, 0);

            }
        }

In the above code snippet, first I am getting the javascript confirmation from the user if he really wants to mark this record as spam, if yes then I am getting the HyperlinkButton object by unboxing the sender object. (Either in ASP.NET or Silverlight, the sender parameter of the event gives us the object that has fired the event).

After getting the HyperlinkButton that has been clicked, I am getting the DataContext property as the object that has been bound to the ListBox control. Notice that DataContext property of any control inside the DataTemplate returns the whole object that has been bound to the ListBox control. Once we have the object for that item, I am getting its AutoID and calling update method to update the record as spam.

Conclusion

Using ListBox.ItemTemplate > DataTemplate, we can custmize the look and feel of the ListBox control in Silverlight.

Hope this article will be useful. Thank you for reading, happy coding !!!

Page copy protected against web site content infringement by Copyscape

About the Author

SheoNarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com
Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)