×
Namespaces

Variants
Actions

Windows Phone 8 Scrollable List with Image from stream and Search functionality

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to create a searchable scrollable list, where the list items include images, which are also streamed from the list definition XML.

WP Metro Icon UI.png
SignpostIcon XAML 40.png
WP Metro Icon WP8.png
SignpostIcon WP7 70px.png
Article Metadata
Code ExampleCompatibilityArticle
Created: munjalrohit (13 Sep 2013)
Last edited: BuildNokia (13 Jun 2014)

Contents

Introduction

This article shows how to create a searchable and scrollable list (with item icons) based on a definition in an XML file. It demonstrates:

  • Creating a class object to import XML "contact list" file into XAML
  • Converting the image from XML by streaming it into a bitmap
  • Using LINQ for searching in List


Screenshots of the lists are shown below:

Implementation

How to converting XML to Class objects

The following code is used to convert XML data to class object. The matching sample XML is available in the attached project.

Class code:

namespace ScrollableListDemo
{
[XmlRoot("Contacts")]
public class ContactLists
{
[XmlElement("Contact")]
public Contact[] Contacts { get; set; }
}
 
 
[XmlRoot("Contact")]
public class Contact
{
 
[XmlAttribute("Mobile")]
public string Mobile { get; set; }
 
[XmlAttribute("FirstName")]
public string FirstName { get; set; }
 
[XmlAttribute("LastName")]
public string LastName { get; set; }
 
[XmlAttribute("NickName")]
public string NickName { get; set; }
 
[XmlAttribute("Address")]
public string Address { get; set; }
 
[XmlAttribute("Email")]
public string Email { get; set; }
 
[XmlElement("Image")]
public string Image { get; set; }
 
}
}

Converting Image from a Stream

The contact's image information is stored in the XML in the "image" node as a "string" of data. The code below is used to stream the images and convert them into BitmapImage.

public sealed class StreamToImageSourceConverter : IValueConverter
{
 
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
if (value != null)// && value is byte[])
{
 
byte[] data = System.Convert.FromBase64String(value.ToString());
Stream stream = new MemoryStream(data, 0, data.Length);
var image = new BitmapImage();
image.SetSource(stream);
stream.Close();
return image;
}
else
{
Uri uriR = new Uri("/Images/NoImage.png", UriKind.Relative);
BitmapImage imgSourceR = new BitmapImage(uriR);
return imgSourceR;
}
 
}
catch
{
Uri uriR = new Uri("/Images/NoImage.png", UriKind.Relative);
BitmapImage imgSourceR = new BitmapImage(uriR);
 
 
return imgSourceR;
//return null;
}
 
}
 
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}

The StreamToImageSourceConverter converter above is declared as a resource in the Layout of the main page:

xmlns:localnamespace="clr-namespace:ValueConverterSample"

and

<phone:PhoneApplicationPage.Resources>
<localnamespace:StreamToImageSourceConverter x:Key="StreamToImageSourceConverter"/>
</phone:PhoneApplicationPage.Resources>

It is then used in the List:

  <Image 
Source="{Binding Image, Converter={StaticResource StreamToImageSourceConverter}}"
Grid.Column="0"
Width="97"
Height="95"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5"/>

The complete layout XAML for the MainPage is given below.

<phone:PhoneApplicationPage
x:Class="ScrollableListDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:localnamespace="clr-namespace:ValueConverterSample"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
 
<phone:PhoneApplicationPage.Resources>
<localnamespace:StreamToImageSourceConverter x:Key="StreamToImageSourceConverter"/>
</phone:PhoneApplicationPage.Resources>
 
 
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot">
<Grid.Background>
<ImageBrush ImageSource="/Images/bg-grey.png" Stretch="Fill" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="10*"/>
<RowDefinition Height="90*"/>
</Grid.RowDefinitions>
 
<!-- LOCALIZATION NOTE:
To localize the displayed strings copy their values to appropriately named
keys in the app's neutral language resource file (AppResources.resx) then
replace the hard-coded text value between the attributes' quotation marks
with the binding clause whose path points to that string name.
 
For example:
 
Text="{Binding Path=LocalizedResources.ApplicationTitle, Source={StaticResource LocalizedStrings}}"
 
This binding points to the template's string resource named "ApplicationTitle".
 
Adding supported languages in the Project Properties tab will create a
new resx file per language that can carry the translated values of your
UI strings. The binding in these examples will cause the value of the
attributes to be drawn from the .resx file that matches the
CurrentUICulture of the app at run time.
-->
 
<!--TitlePanel contains the name of the application and page title-->
<Grid x:Name="grdTitle" Grid.Row="0">
 
<TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" Text="List Scroll" FontSize="26.667" Foreground="#FF121111" FontWeight="Bold" />
 
</Grid>
<!--ContentPanel - place additional content here-->
<StackPanel Orientation="Vertical" x:Name="ContentPanel1" Grid.Row="1" Grid.Column="0" Margin="0,0,0,5">
<StackPanel>
<StackPanel.Background>
<ImageBrush ImageSource="/Images/search-bar.png" />
</StackPanel.Background>
<TextBox x:Name="txtsearch" Text="Search" BorderThickness="0" FontSize="21.333" Width="430" Height="60" Opacity="0.6" Foreground="#FF060505" HorizontalAlignment="Right" LostFocus="txtsearch_LostFocus" GotFocus="txtsearch_GotFocus" TextChanged="txtsearch_TextChanged">
<TextBox.Background>
<ImageBrush Stretch="UniformToFill"/>
</TextBox.Background>
</TextBox>
</StackPanel>
 
 
 
<!--ContentPanel - place additional content here-->
<ListBox x:Name="VcontactList" Margin="0,0,0,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="110" Width="480" Grid.Row="1">
<Grid.Background>
<ImageBrush ImageSource="/Images/listing.png" />
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45*"/>
<ColumnDefinition Width="60*"/>
 
 
</Grid.ColumnDefinitions>
 
<StackPanel Grid.Column="0">
<Image
Source="{Binding Image, Converter={StaticResource StreamToImageSourceConverter}}"
Grid.Column="0"
Width="97"
Height="95"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5"/>
</StackPanel>
 
<StackPanel Margin="0"
Grid.Column="1"
Height="100"
Orientation="Vertical"
VerticalAlignment="Top"
HorizontalAlignment="Left">
 
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical" Grid.Column="1" Height="100" Width="250" >
<TextBlock Grid.Column="1" Text="{Binding NickName}" HorizontalAlignment="Left" x:Name="LblName" FontSize="21.333" Margin="0,5,0,0" Foreground="#FF787373" FontWeight="Bold" />
<TextBlock HorizontalAlignment="Left" x:Name="LblMobile" Text="{Binding Mobile}" Grid.Column="1" FontSize="16" Foreground="#FF787373" />
<TextBlock HorizontalAlignment="Left" x:Name="Lbladdress" Text="{Binding Address}" Grid.Column="1" Width="210" TextWrapping="Wrap" FontSize="16" Foreground="#FF787373" />
</StackPanel>
 
</StackPanel>
 
</StackPanel>
 
 
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
 
 
<!--Uncomment to see an alignment grid to help ensure your controls are
aligned on common boundaries. The image has a top margin of -32px to
account for the System Tray. Set this to 0 (or remove the margin altogether)
if the System Tray is hidden.
 
Before shipping remove this XAML and the image itself.-->
<!--<Image Source="/Assets/AlignmentGrid.png" VerticalAlignment="Top" Height="800" Width="480" Margin="0,-32,0,0" Grid.Row="0" Grid.RowSpan="2" IsHitTestVisible="False" />-->
</Grid>
 
</phone:PhoneApplicationPage>

Code for search functionality

The full code behind, including search functionality, is given below

namespace ScrollableListDemo
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
ContactLists ContactListData = new ContactLists();
public MainPage()
{
InitializeComponent();
 
XmlSerializer serializer = new XmlSerializer(typeof(ContactLists));
XDocument document = XDocument.Load("SampleXML.xml");//XDocument.Parse(e.Result);
ContactListData = (ContactLists)serializer.Deserialize(document.CreateReader());
VcontactList.ItemsSource = ContactListData.Contacts.AsEnumerable();
 
}
private void txtsearch_LostFocus(object sender, RoutedEventArgs e)
{
 
}
 
private void txtsearch_GotFocus(object sender, RoutedEventArgs e)
{
txtsearch.Text = "";
}
 
private void txtsearch_TextChanged(object sender, TextChangedEventArgs e)
{
 
if (!(txtsearch.Text.ToLower() == "search"))
{
 
var query = from c in ContactListData.Contacts
where c.NickName.ToLower().StartsWith(txtsearch.Text.ToLower())
select c;
 
VcontactList.ItemsSource = query.AsEnumerable();
}
 
}
 
 
// Sample code for building a localized ApplicationBar
//private void BuildLocalizedApplicationBar()
//{
// // Set the page's ApplicationBar to a new instance of ApplicationBar.
// ApplicationBar = new ApplicationBar();
 
// // Create a new button and set the text value to the localized string from AppResources.
// ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative));
// appBarButton.Text = AppResources.AppBarButtonText;
// ApplicationBar.Buttons.Add(appBarButton);
 
// // Create a new menu item with the localized string from AppResources.
// ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
// ApplicationBar.MenuItems.Add(appBarMenuItem);
//}
}
}

Summary

This code example shows how to create scrollable list with image where image data is as stream and additional search functionality.

You can download source code from here: File:ScrollableListDemo.zip

This page was last modified on 13 June 2014, at 02:57.
221 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×