Introduction
I had to design the Help and About pages for a Windows Phone 7 (WP7) application. I wanted to use local HTML pages to show the Help pages. I also wanted to show the buttons and the screen responses as PNG and JPEG images in the Help file. This involves storing the HTML page and the associated images in Isolated Storage. I thought this application is so general in nature that it would be useful to others.
Background
The main method used in this project is to move items to Isolated Storage and retrieve them, because WP7 has only this mechanism available for the Browser control. The technique used in this article was inspired by a blog Moving Files from XAP to Isolated Storage for Local HTML Content on Windows Phone 7 « Simplifying Technology by David Cornelson.
Using the Code
The example application has three pages:
- List page
- Help page: This page describes the buttons and the actions in the application
- About page: This describes the application
List Page
This page presents the list of states in a ListPicker
control. The selected State is shown in the TextBox
. If you are using this application, make sure you have downloaded the Silverlight Release: Silverlight for Windows Phone Toolkit - Nov 2010 and reference it in your project. This page is straightforward.
void ListPage_Loaded(object sender, RoutedEventArgs e)
{
StatesListPicker.SelectionChanged +=
new System.Windows.Controls.SelectionChangedEventHandler(
StatesListPicker_SelectionChanged);
StatesListPicker.SelectedIndex = 4;
}
void StatesListPicker_SelectionChanged(object sender,
System.Windows.Controls.SelectionChangedEventArgs e)
{
StateNameTextBlock.Text = StatesListPicker.SelectedItem.ToString();
}
When the ListPicker
item is changed, the State name appears in the TextBlock
.
The image buttons were inspired by the ImageButton control for Windows Phone 7: Silverlight and Windows Phone 7 Geek Page by Przemyslaw Chruscicki. The following code sets up the buttons:
<StackPanel x:Name="ButtonPanel" Grid.Row="1" Orientation="Horizontal">
<local:ImageButton x:Name="Help_Button"
Image="../Assets/Images/ButtonKeys/Help48.png"
PressedImage="../Assets/Images/ButtonKeys/Helppressed48.png"
Width="70" Height="70"
Template="{StaticResource ImageButtonControlTemplate}"
Margin="300,10,10,10" Click="Button_Click"/>
<local:ImageButton x:Name="About_Button"
Image="../Assets/Images/ButtonKeys/About48.png"
PressedImage="../Assets/Images/ButtonKeys/Aboutpressed48.png"
Width="70" Height="70"
Template="{StaticResource ImageButtonControlTemplate}"
Margin="10 " Click="Button_Click"/>
</StackPanel>
The ImageButton
Control Template is in App.Xaml.Cs. When the button is pressed, the following button event executes, which navigates the user to the selected page:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button_selected = sender as Button;
string button_name = button_selected.Name;
string uri = "";
switch (button_name)
{
case "List_Button":
uri = "/ListPage.xaml";
break;
case "Help_Button":
uri = "/HelpPage.xaml";
break;
case "About_Button":
uri = "/AboutPage.xaml";
break;
default:
break;
}
try
{
NavigationService.Navigate(new Uri(uri, UriKind.RelativeOrAbsolute));
}
catch (Exception enav)
{
string serror = enav.Message;
}
}
Help and About pages
The Help and About pages are the main theme of this article. This is a simple Browser
control which displays the local HTML page. For example, the Help page is displayed by the following code:
void HelpPage_Loaded(object sender, RoutedEventArgs e)
{
webBrowser1.Base = "HTDocs";
webBrowser1.Navigate(new Uri("Help.htm", UriKind.Relative));
}
Look how simple the code is. We are setting the base directory as HTDocs and navigating to the HTML page.
Setting Up the HTML Pages in App.Xaml.cs
HTML pages in Isolated Storage are set up in App.Xaml.cs. When the application is launched, Initialize_Help_HTMLPage()
is called. This code snippet is given below:
private void Initialize_Help_HTMLPage()
{
storageFile.CreateDirectory("HTDocs\\images");
storageFile.CopyTextFile("HTDocs\\Help.htm", true);
storageFile.CopyTextFile("HTDocs\\About.htm", true);
storageFile.CopyBinaryFile("HTDocs\\images\\About48.png", true);
storageFile.CopyBinaryFile("HTDocs\\images\\Help48.png", true);
storageFile.CopyBinaryFile("HTDocs\\images\\list48.png", true);
storageFile.CopyBinaryFile("HTDocs\\images\\ListPicker.png", true);
storageFile.CopyBinaryFile("HTDocs\\images\\PickedState.png", true);
}
We create the HTDocs directory in Isolated Storage and copy the HTML files and the images to this directory. I used Visual Studio to create this directory, the HTML files, and the images directory where I copied the image files. Please make sure that the type of the image files is Content
and not Resource
.
We are using two Extension Methods, CopyBinaryFile
and CopyTextFile
. CopyTextFile
is used to copy the HTML files and CopyBinaryFile
is used to copy the images to Isolated Storage. These are from the article by David Cornelson (Reference 2).
public static class ISExtensions
{
public static void CopyTextFile(this IsolatedStorageFile isf,
string filename, bool replace = false)
{
if (!isf.FileExists(filename) || replace == true)
{
StreamReader stream =
new StreamReader(TitleContainer.OpenStream(filename));
IsolatedStorageFileStream outFile = isf.CreateFile(filename);
string fileAsString = stream.ReadToEnd();
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(fileAsString);
outFile.Write(fileBytes, 0, fileBytes.Length);
stream.Close();
outFile.Close();
}
}
public static void CopyBinaryFile(this IsolatedStorageFile isf,
string filename, bool replace = false)
{
if (!isf.FileExists(filename) || replace == true)
{
BinaryReader fileReader =
new BinaryReader(TitleContainer.OpenStream(filename));
IsolatedStorageFileStream outFile = isf.CreateFile(filename);
bool eof = false;
long fileLength = fileReader.BaseStream.Length;
int writeLength = 512;
while (!eof)
{
if (fileLength < 512)
{
writeLength = Convert.ToInt32(fileLength);
outFile.Write(fileReader.ReadBytes(writeLength), 0, writeLength);
}
else
{
outFile.Write(fileReader.ReadBytes(writeLength), 0, writeLength);
}
fileLength = fileLength - 512;
if (fileLength <= 0) eof = true;
}
fileReader.Close();
outFile.Close();
}
}
}
Points of Interest
This was an interesting project. Now I have a template for designing HTML files for Help and About pages in my WP7 applications, which has simplified my life. I hope it will be of some use to you also.
References
- Silverlight Release: Silverlight for Windows Phone Toolkit - Nov 2010
- Moving Files from XAP to Isolated Storage for Local HTML Content on Windows Phone 7 « Simplifying Technology by David Cornelson
- ImageButton control for Windows Phone 7: Silverlight and Windows Phone 7 Geek Page by Przemyslaw Chruscicki
History