Horoscope Program for Windows Phone 7

Introduction

This article show how to create a Horoscope Application to Windows Phone 7. The tecnologies used are XAML, WCF, LINQ and C#.

1.gif

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.

2.gif
 
Using the code
 
Start a Windows Phone Application project:

3.gif
 
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.

4.gif
 
Prevision Grid have controls to show the Sign name, Prevision text and the Back Button.

5.gif
 
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.

6.gif
 
Clear all example code that open with template. Rename the interface from IService1 to IZodiacPhone.

7.gif
 
Create the interface method GetPrevision to be used by the main class.

8.gif
 
Open the main class Service1. Rename the class to ZodiacPhone, change the interface to IZodiacPhone, and clear the examples code.

9.gif
 
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.

10.gif
 
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.

11.gif
 
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).

12.gif
 
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.