Introduction
This article show how to create a Horoscope Application to Windows Phone 7. The tecnologies used are XAML, WCF, LINQ and C#.
Background
The scenario is based on Windows Phone to access a published WCF service with the chosen sign. This service will open a RSS, get the prevision, and return this prevision to Windows Phone.
Using the code
Start a Windows Phone Application project:
Create a Title Panel to show the title of the Application and a short explanation.
Insert the ContentPanel that has all the controls of this application (Sign Buttons and Prevision Panel).
Insert 12 images that represent the Zodiac Signs. Determine the position, image source and size of images to have good appearence. Mount the MouseLeftButtonDown as click event equals to all images and for each image determine a parameter Code and Name in property Tag.
Prevision Grid have controls to show the Sign name, Prevision text and the Back Button.
Here is the complete XAML:
<phone:PhoneApplicationPage
x:Class="ZodiacPhone.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"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="The future in your hand" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="Zodiac Phone" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image Name="iAries" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="10,24,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/aries.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="1|Aries" />
<Image Name="iTaurus" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="165,24,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/touro.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="2|Taurus"/>
<Image Name="iGemini" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="322,24,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/gemeos.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="3|Gemini"/>
<Image Name="iCancer" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="10,172,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/cancer.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="4|Cancer"/>
<Image Name="iLeo" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="165,172,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/leao.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="5|Leo"/>
<Image Name="iVirgo" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="322,172,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/virgem.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="6|Virgo"/>
<Image Name="iLibra" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="10,330,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/libra.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="7|Libra"/>
<Image Name="iScorpio" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="165,330,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/escorpiao.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="8|Scorpio"/>
<Image Name="iSagitarius" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="322,330,0,0" Stretch="Fill"VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/sagitario.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown"Tag="9|Sagittarius"/>
<Image Name="iCapricorn" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="10,481,0,0" Stretch="Fill"VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/capricornio.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown"Tag="10|Capricorn"/>
<Image Name="iAquarius" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="165,481,0,0" Stretch="Fill"VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/aquario.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown"Tag="11|Aquarius"/>
<Image Name="iPisces" Cursor="Hand" Height="128" Width="128"
HorizontalAlignment="Left" Margin="322,481,0,0" Stretch="Fill" VerticalAlignment="Top"
Source="/ZodiacPhone;component/img/peixes.png" MouseLeftButtonDown="callPrevision_MouseLeftButtonDown" Tag="12|Pisces"/>
<Grid x:Name="TextGrid" Visibility="Collapsed" Background="#FF144B0D" Opacity="0.97">
<TextBlock Name="txtPrevisionTitle" Width="452" FontSize="20" Opacity="1"></TextBlock>
<TextBlock Name="txtPrevision" Width="400" Height="500" TextWrapping="Wrap" FontSize="24" />
<Button Name="btnHome" VerticalAlignment="Bottom" Width="90" Height="90" Cursor="Hand" BorderBrush="#FF70A1E2" Click="btnHome_Click">
<Button.Background>
<ImageBrush ImageSource="/ZodiacPhone;component/img/back_button.png" Stretch="None" />
</Button.Background>
</Button>
</Grid>
</Grid>
</Grid>
<!--Sample code showing usage of ApplicationBar-->
<!--<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="MenuItem 1"/>
<shell:ApplicationBarMenuItem Text="MenuItem 2"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>-->
</phone:PhoneApplicationPage>
</phone:PhoneApplicationPage>
Now create the WCF Project. I used separate projects because I use the Express Version. If the Visual Studio is not Express, you can use the same solution for the WCF project.
Choose WCF Service Application. Type a name like WcfService, choose location and click Ok.
Clear all example code that open with template. Rename the interface from IService1 to IZodiacPhone.
Create the interface method GetPrevision to be used by the main class.
Open the main class Service1. Rename the class to ZodiacPhone, change the interface to IZodiacPhone, and clear the examples code.
See the Interface code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService
{
[ServiceContract]
public interface IZodiacPhone
{
// TODO: Add your service operations here
[OperationContract]
string GetPrevision(int value);
}
}
To continue, call in scope reference to System.XML.Linq, create the GetPrevision method that manage Sign call, opening the correct RSS address and capture the Sign Description.
See the WCF Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.Xml.Linq;
namespace WcfService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
public class ZodiacPhone : IZodiacPhone
{
public string GetPrevision(int p_nSign)
{
try
{
string sReturn = "";
switch (p_nSign)
{
case 1:
sReturn = "Aries";
break;
case 2:
sReturn = "Taurus";
break;
case 3:
sReturn = "Gemini";
break;
case 4:
sReturn = "Cancer";
break;
case 5:
sReturn = "Leo";
break;
case 6:
sReturn = "Virgo";
break;
case 7:
sReturn = "Libra";
break;
case 8:
sReturn = "Scorpio";
break;
case 9:
sReturn = "Sagittarius";
break;
case 10:
sReturn = "Capricorn";
break;
case 11:
sReturn = "Aquarius";
break;
case 12:
sReturn = "Pisces";
break;
default:
sReturn = "service off...";
break;
}
//XDocument xml = XDocument.Load(@"http://www.horoscopofree.com/pt/misc/partnership/Horoscopo.xml?
HFPTS=526bf73c3babbce8ed5371f7633e3a5e");
XDocument xml = XDocument.Load(@"http://www.findyourfate.com/rss/dailyhoroscope-feed.asp?sign=" + sReturn);
var Horoscope = from rss in xml.Descendants("item")
//where (rss.Element("title").Value.Contains("sReturn"))
select new
{
Description = (string)rss.Element("description").Value
};
foreach (var dados in Horoscope)
{
sReturn = dados.Description;
}
return sReturn;
}
catch (Exception ex)
{
throw ex;
}
}
}
}
Publish the WCF Service in a Webserver. In my example I only run the WCF Project and use the local address.
Back to the Windows Phone XAML project, in Solution Explorer, right-click in Service References, and choose Add Service Reference.
Type the published WCF Service address, click in Go.
Type a namespace, like ZodiacPhoneService, and click in Ok.
Open the C# code to XAML Windows Phone project.
Call the WCF Service by a proxy variable. Implement the methods to front-end side (call prevision, show, hide and update).
See the Front-end code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace ZodiacPhone
{
public partial class MainPage : PhoneApplicationPage
{
ZodiacPhoneService.ZodiacPhoneClient proxy = new ZodiacPhoneService.ZodiacPhoneClient();
// Constructor
public MainPage()
{
InitializeComponent();
}
private void callPrevision(int sign, string signName)
{
proxy.GetPrevisionCompleted += new EventHandler<ZodiacPhoneService.GetPrevisionCompletedEventArgs>(proxy_GetPrevisionCompleted);
proxy.GetPrevisionAsync(sign);
txtPrevisionTitle.Text = signName;
}
private void closePrevision()
{
TextGrid.Visibility = System.Windows.Visibility.Collapsed;
txtPrevisionTitle.Text = "";
txtPrevision.Text = "";
}
private void callPrevision_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
string[] response = ((Image)sender).Tag.ToString().Split('|');
int sign = Convert.ToInt16(response[0]);
string signName = response[1];
callPrevision(sign, signName);
}
void proxy_GetPrevisionCompleted(object sender, ZodiacPhoneService.GetPrevisionCompletedEventArgs e)
{
string resultado = e.Result;
TextGrid.Visibility = System.Windows.Visibility.Visible;
txtPrevision.Text = resultado;
}
private void btnHome_Click(object sender, RoutedEventArgs e)
{
closePrevision();
}
}
}
Points of Interest
Is very good to develop to Windows Phone. This plataform is strong, with many tools to create powerfull application. The possibilities to use XAML, WCF and work with framework 4.0, open to Windows Phone a big future.