Introduction
In a few months, Microsoft will bring the new version of its mobile operating system, Windows Phone 7 with many new, controversial, supporters and retractors ...
But today, let's take a look from our point of view, the programmers. Microsoft has given a great advantage to those who use WPF / Silverlight. For now, we are also developers for Windows Phone 7, as all applications for this O.S. are developed in XNA or Silverlight.
This is a revolution compared to Windows Mobile 6.X or other competitors mobile platforms, because it will allow us to port applications that are already working on Silverlight in a fast and simple way, almost without rewriting code.
To get a bit to the development of an application made in Silverlight for Windows Phone 7 as an example, I bring you an RSS reader (very basic, no commercial aspirations or anything) in which we will use several interesting things about Silverlight and Windows Phone 7:
- Application Bar
- Access to local storage of our terminal
- Object serialization and deserialization
- Use of the
WebClient
class
- Use of the
webBrowser
control to load dynamic generated content
The final result of our application:
Starting
In order to develop applications for Windows 7 Phone, you need to download the CTP of the tools of development here.
This pack includes Visual Studio 2010 Express for Windows Phone, so if you do not have Visual Studio 2010, you will not have problems in developing for Windows Phone 7.
Once the Developers tools have been installed, just open Visual Studio 2010 and choose a new Silverlight for Windows Phone project as shown in the image:
The project is in Visual C#, do not look at Visual Basic, it is not found, yet. For now, there is only support for C#, but the Windows Phone has promised that the final version of the SDK will have support for Visual Basic. But in the end, really all of it is .NET and the two languages do not change so much.
ApplicationBar
The ApplicationBar
is a wonderful idea of design from the Windows Phone 7 team to help us create the interface of our applications, you can see it in detail in this capture:
The bottom bar violet with the 3 points is the application bar, clicking on the 3 points is displayed showing all available options:
It is very useful because it allows us to create a menu that can be included on each page of the application you want to just add a reference, since the definition of the menu is in the file App.xaml and the code associated with each option in the file app.xaml.cs. Consider the code required to define the application XAML bar.
First, our project should include a reference to the assembly Microsoft.Phone.Shell
.
Then, our App.xaml should include a reference to Microsoft.Phone.Shell
:
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;
assembly=Microsoft.Phone.Shell"
Finally in the Tag <Application.Resources>
, create our Application Bar:
<shell:ApplicationBar x:Name="MenuAppBar" Opacity="0.7"
IsVisible="True" IsMenuEnabled="True"
BackgroundColor="Purple" >
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="Edit Rss Sources"
x:Name="EditRss"
Click="EditRss_Click"/>
<shell:ApplicationBarMenuItem Text="Update Local Rss"
x:Name="UpdateRss"
Click="UpdateRss_Click"/>
<shell:ApplicationBarMenuItem Text="View Local Rss"
x:Name="ViewRss"
Click="ViewRss_Click"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
Now on each page where you want to display the ApplicationBar
, you must indicate the attribute ApplicationBar
of the object <navigation:PhoneApplicationPage>
:
<navigation:PhoneApplicationPage
...
...
ApplicationBar="{StaticResource MenuAppBar}">
With this, if we run our application, we will see that our Application Bar appears and is displayed showing all options.
To add code to each option, we use the Click event in XAML we defined earlier, for example, the Edit RSS Sources option calls the event EditRss_Click
, which is located in the file app.xaml.cs and has this signature:
private void EditRss_Click(object sender, EventArgs e)
{
}
As you can see, the method EditRss_Click
signature is the same as the Click
event of any button.
Access to Local Storage, Serialize and Deserialize Objects
One of the major changes in development between Windows Mobile 6.X and Windows Phone 7 is that our applications do not have permission to access the general storage terminal on which are stored and cannot use databases in the terminal.
To meet this guideline for Microsoft is clear: move your data to the cloud and your application can access them through your Internet connection. Although this is totally true, we can find times when we want to store some information on the terminal as a data cache or store user preferences on the application and its status. This we do by going to IsolatedStorage
assigned to our application. This storage space is isolated from the rest of the system and applications, and is exclusive to our application.
Let's say we want to save a file in this isolated storage that contains all the RSS feeds you have configured in our application. This is very simple using the XML serialization and deserialization and decorating our class with the necessary XML attribute.
For this, we need first to add to our project a reference to the assembly System.Xml.Serialization
.
To start, let's create a class that can store the information that we want to keep for each RSS:
public class RssSource
{
[System.Xml.Serialization.XmlElement]
public String Description { get; set; }
[System.Xml.Serialization.XmlElement]
public String Url { get; set; }
public RssSource()
{
}
public RssSource(String SourceDesc, String SourceUrl)
{
Description = SourceDesc;
Url = SourceUrl;
}
}
As you can see, it is a very simple class, has two public
properties to store the RSS URL and a description and two constructors.
If you look at the properties of this class, you will see that both are decorated with the attribute System.Xml.Serialization.XmlElement
, this serves for the XML serializer to become aware that each property represent an XML Element node.
Now, as we store more than one RSS feed in our file, we create another class, which will be serialized and also that it will have the functionality to add, delete, save and load our list of sources:
public class RssSources
{
[System.Xml.Serialization.XmlArray]
public List<RssSource> Sources = new List<RssSource>();
public RssSources()
{
}
public bool LoadFromIso()
{
XmlSerializer Serializator = new XmlSerializer(typeof(RssSources));
IsolatedStorageFile IsoFile = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream Stream = IsoFile.OpenFile("Sources.rss",
FileMode.OpenOrCreate);
try
{
RssSources DiskSources = (RssSources)Serializator.Deserialize(Stream);
this.Sources = DiskSources.Sources;
return true;
}
catch (Exception)
{
return false;
}
finally
{
Stream.Close();
IsoFile.Dispose();
}
}
public bool AddSource(String Description, String Url)
{
try
{
Sources.Add(new RssSource(Description, Url));
SaveToIso();
return true;
}
catch (Exception)
{
return false;
}
}
public bool DeleteSource(RssSource Item)
{
try
{
Sources.Remove(Item);
return true;
}
catch (Exception)
{
return false;
}
}
private bool SaveToIso()
{
XmlSerializer Serializator = new XmlSerializer(typeof(RssSources));
IsolatedStorageFile IsoFile = IsolatedStorageFile.GetUserStoreForApplication();
if (IsoFile.FileExists("Sources.rss"))
{
IsoFile.DeleteFile("Sources.rss");
}
IsolatedStorageFileStream Stream = IsoFile.CreateFile("Sources.rss");
try
{
Serializator.Serialize(Stream, this);
return true;
}
catch (Exception)
{
return false;
}
finally
{
Stream.Close();
IsoFile.Dispose();
}
}
}
Well, this class exposes a list of type RssSource
(the base class you created earlier), a parameterless constructor and four methods:
AddSource
: Just add a new RssSource
to the Sources list.
DeleteSource
: Removes an existing Item from the List of sources.
SaveToIso
: Using the XmlSerializer
class, create a serializer the same type as our class, we get the IsolatedStore
of our application and create a IsolatedSorageFileStream
, and last serialize the content of our class to this file.
LoadFromIso
: The reverse operation of SaveToIso
method, we open a file with our class serialized and deserialized to obtain the RssSource
list it contains.
If you examine the code, you see it is really simple and allows us to store information in a very simple and fast way, of course no substitute for a database, but for small pieces of data or physical persist the state of objects of our application is very useful.
Use of the WebClient Class
Well, we already have stored our RSS feed, but how do you get content from them? Well, very simple, using the WebClient
class in Silverlight
This class allows you to download content in text format from a URI asynchronously, so the first thing to do is declare a method that responds to the WebClient
class event DownloadStringCompleted
:
private void DownloadComplete(object sender, DownloadStringCompletedEventArgs e)
{
var client = sender as WebClient;
if (client != null)
{
client.DownloadStringCompleted -= DownloadComplete;
}
if (e.Error != null)
{
throw e.Error;
}
if (e.Result != null)
{
}
}
e.Result
contains the text downloaded, in our case containing the different XML RSS news we've downloaded. In the sample project, I use LINQ to XML to get all the news and save them to a generic list.
Once we have defined the DownloadStringCompleted
event handler, we only create the object and tell WebClient
to download the RSS:
WebClient client = new WebClient();
client.DownloadStringCompleted += DownloadComplete;
client.DownloadStringAsync(new Uri(RssUrl));
Use of the webBrowser Control to Load Dynamic Generated Content
The last step is to display the content of news, usually the content is in HTML format with images and other tags, so it is more appropriate to use the WebBrowser
control to display content in a web page, for it only needs to add the head and body to our news and use the method NavigateToString
of the WebBrowser
control to display our HTML:
webBrowser1.NavigateToString(
"<html><head><meta name='viewport' " +
"content='width=480, user-scalable=yes'/>" +
"</head><body>" +
(lstDetails.SelectedItem as RssFeed).Description +
"</body></html>");
With this simple code, any text string can be displayed in the webbrowser control as if it were a web page.
And that's all. You can download the attached project to see all in action.
I hope you liked it. Happy coding! A big welcome to all and thanks for reading!
History
- 02 July 2010 - First version
- 15 July 2010 - Updated to the new Developer Tools Beta released from Microsoft some days ago:
- Now using
Microsoft.Phone
assembly replacing Microsoft.Phone.Controls
, Microsoft.Phone.Navigation
, Microsoft.Phone.Shell
and more...
- The
PhoneApplicationPage
object now comes in the namespace Microsoft.Phone.Controls
and not in the Microsoft.Phone.Navigation
like in the CTP version
- Deleted all
UIElement.Effect
references, not allowed in Beta version
- The main page of our application now is defined in the file WMAppManifest.xml under Properties, in the section
<Tasks><DefaultTask></DefaultTask></Tasks>
- Posted new example code updated to Beta versiĆ³n with all changes made.