您的位置:首页 > 其它

Windows Phone 7 简单的饭否客户端

2011-02-15 21:19 225 查看
  前一个月折腾了一个超简单的饭否客户端,显示饭否随便看看的一段代码。先看一下效果图。

竖屏:



横屏……,好吧,我基本没做横屏方面的代码,只是展示了一下如何实现横屏适应。



  下面是整个项目的一个文件截图


Fanfou:

FanfouData.cs:下载解析返回的数据,数据格式为xml

FanfouStatus.cs:返回"随便看看"数据的模型

FnafouUser.cs:饭否用户的数据模型

WP7Fanfou:

AppManifest.xml: 生成应用程序安装包(XAP)所需的一个简单的应用程序清单文件

WMAppManifest.xml:另一个包含了应用程序特定数据的元数据文件,包括标题,图标位置,功能等等

App.xaml:这个文件和ASP.NET中的web.config文件很相似。你可以将供整个应用程序使用的数据和设置保存在此处

ApplicationIcon.png:程序的图标

Background.png:这个图片在你的程序被显示到开始界面中就会显示

SplashScreenImage.jpg:这个就是启动界面图片

MainPage.xaml:程序首页面,相当于android中的第一个Activity

主要的代码实现:

-----------------FanFou项目------------------------

FanfouStatus.cs

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Serialization;

namespace Fanfou.Model
{

public class FanfouStatus
{
[XmlElement("created_at")]
public string CreatedAt
{
set;
get;
}
[XmlElement("id")]
public string Id
{
set;
get;
}
[XmlElement("text")]
public string Text
{
set;
get;
}
[XmlElement("source")]
public string Source
{
set;
get;
}
[XmlElement("truncated")]
public bool Truncated
{
set;
get;
}
[XmlElement("in_reply_to_status_id")]
public string InReplyToStatusId
{
set;
get;
}
[XmlElement("in_reply_to_user_id")]
public string InReplyToUserId
{
set;
get;
}
[XmlElement("favorited")]
public bool Favorited
{
set;
get;
}
[XmlElement("in_reply_to_screen_name")]
public string InReplyToScreenName
{
set;
get;
}

[XmlElement("user")]
public FanfouUser User
{
set;
get;
}

}
}


FanfouUser.cs

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Serialization;

namespace Fanfou.Model
{
public class FanfouUser
{
[XmlElement("id")]
public string Id
{
set;
get;
}
[XmlElement("name")]
public string Name
{
set;
get;
}
[XmlElement("screen_name")]
public string ScreenName
{
set;
get;
}
[XmlElement("location")]
public string Location
{
set;
get;
}
[XmlElement("gender")]
public string Gender
{
set;
get;
}
[XmlElement("birthday")]
public string Birthday
{
set;
get;
}
[XmlElement("description")]
public string Description
{
set;
get;
}
[XmlElement("profile_image_url")]
public string ProfileImageUrl
{
set;
get;
}
[XmlElement("url")]
public string Url
{
set;
get;
}
[XmlElement("protected")]
public bool Protected
{
set;
get;
}
[XmlElement("followers_count")]
public int FollowersCount
{
set;
get;
}
[XmlElement("friends_count")]
public int FriendsCount
{
set;
get;
}
[XmlElement("favourites_count")]
public int FavouritesCount
{
set;
get;
}
[XmlElement("statuses_count")]
public int StatusesCount
{
set;
get;
}
[XmlElement("created_at")]
public string CreatedAt
{
set;
get;
}
[XmlElement("utc_offset")]
public int UtcOffset
{
set;
get;
}
[XmlElement("notifications")]
public bool Notifications
{
set;
get;
}
[XmlElement("following")]
public bool Following
{
set;
get;
}
[XmlElement("profile_background_color")]
public string ProfileBackgroundColor
{
set;
get;
}
[XmlElement("profile_text_color")]
public string ProfileTextColor
{
set;
get;
}
[XmlElement("profile_link_color")]
public string ProfileLinkColor
{
set;
get;
}
[XmlElement("profile_sidebar_fill_color")]
public string ProfileSidebarFillColor
{
set;
get;
}
[XmlElement("profile_sidebar_border_color")]
public string ProfileSidebarBorderColor
{
set;
get;
}
[XmlElement("profile_background_image_url")]
public string ProfileBackgroundImageUrl
{
set;
get;
}
[XmlElement("profile_background_tile")]
public bool ProfileBackgroundTile
{
set;
get;
}

}
}


FanFouData.cs

using System;
using System.Net;
using System.IO;
using System.Windows;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
using Fanfou.Model;

namespace Fanfou.Data
{
public class FanfouData
{
public delegate void AnalysisEventHandler(object sender);//事件的代理
public event AnalysisEventHandler Analysis;

private string username;//用户名
private string userpass;//密码

public string UserName
{
set { this.username = value; }
get { return this.userpass; }
}
public string UserPass
{
set { this.userpass = value; }
get { return this.userpass; }
}
private List<FanfouStatus> statuses;//存储从xml解析出来的对象
public List<FanfouStatus> GetStatusData()
{
string url = "http://api.fanfou.com/statuses/public_timeline.xml";//饭否“随便看看”的Api地址
WebClient client = new WebClient();//WebClient类,用于接收和发送信息
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);//当下载完毕后触发事件
client.Credentials = new NetworkCredential(this.username, this.userpass);//http验证
client.DownloadStringAsync(new Uri(url));//将指定的字符串下载到指定的资源

return statuses;
}
public FanfouData()
{
statuses = new List<FanfouStatus>();
}

/// <summary>
/// 解析数据完成后触发
/// </summary>
protected virtual void OnAnalysisComplete()
{
AnalysisEventHandler handler = Analysis;
if (handler != null)
{
// Invokes the delegates.
handler(this);
}

}

/// <summary>
/// 下载完成后处理字符串
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
string xml = e.Result;//异步下载完成后获得xml数据
AnalysisXml(xml);
}
/// <summary>
/// 解析下载下来的xml流
/// </summary>
/// <param name="xml"></param>
private void AnalysisXml(string xml)
{

XDocument document = XDocument.Parse(xml);
XElement element = document.Element("statuses");
IEnumerable<XElement> statusesElements = element.Elements("status");

foreach (var elx in statusesElements)
{
FanfouStatus status = new FanfouStatus();

foreach (var statusElement in elx.Elements())
{
switch (statusElement.Name.LocalName)
{
case "created_at":
status.CreatedAt = statusElement.Value;
break;
case "id":
status.Id = statusElement.Value;
break;
case "text":
status.Text = statusElement.Value;
break;
case "source":
status.Source = statusElement.Value;
break;
case "truncated":
status.Truncated = bool.Parse(statusElement.Value);
break;
case "in_reply_to_status_id":
status.InReplyToStatusId = statusElement.Value;
break;
case "in_reply_to_user_id":
status.InReplyToUserId = statusElement.Value;
break;
case "favorited":
status.Favorited = bool.Parse(statusElement.Value);
break;
case "in_reply_to_screen_name":
status.InReplyToScreenName = statusElement.Value;
break;
case "user":
FanfouUser user = new FanfouUser();
IEnumerable<XElement> userElements = statusElement.Elements();
foreach (var userElement in userElements)
{
switch (userElement.Name.LocalName)
{
case "id":
user.Id = userElement.Value;
break;
case "name":
user.Name = userElement.Value;
break;
case "screen_name":
user.ScreenName = userElement.Value;
break;
case "location":
user.Location = userElement.Value;
break;
case "gender":
user.Gender = userElement.Value;
break;
case "birthday":
user.Birthday = userElement.Value;
break;
case "description":
user.Description = userElement.Value;
break;
case "profile_image_url":
user.ProfileImageUrl = userElement.Value;
break;
case "url":
user.Url = userElement.Value;
break;
case "protected":
user.Protected = bool.Parse(userElement.Value);
break;
case "followers_count":
user.FollowersCount = int.Parse(userElement.Value);
break;
case "friends_count":
user.FriendsCount = int.Parse(userElement.Value);
break;
case "favourites_count":
user.FavouritesCount = int.Parse(userElement.Value);
break;
case "statuses_count":
user.StatusesCount = int.Parse(userElement.Value);
break;
case "created_at":
user.CreatedAt = userElement.Value;
break;
case "utc_offset":
user.UtcOffset = int.Parse(userElement.Value);
break;
case "notifications":
user.Notifications = bool.Parse(userElement.Value);
break;
case "following":
user.Following = bool.Parse(userElement.Value);
break;
case "profile_background_color":
user.ProfileBackgroundColor = userElement.Value;
break;
case "profile_text_color":
user.ProfileTextColor = userElement.Value;
break;
case "profile_link_color":
user.ProfileLinkColor = userElement.Value;
break;
case "profile_sidebar_fill_color":
user.ProfileSidebarFillColor = userElement.Value;
break;
case "profile_sidebar_border_color":
user.ProfileSidebarBorderColor = userElement.Value;
break;
case "profile_background_image_url":
user.ProfileBackgroundImageUrl = userElement.Value;
break;
case "profile_background_tile":
user.ProfileBackgroundTile = bool.Parse(userElement.Value);
break;
default:
break;
}
}
status.User = user;
break;
}

}
statuses.Add(status);
}
OnAnalysisComplete();//解析完成后触发
}
}
}


-----------------WP7FanFou项目-----------------------------

App.xaml

<Application
x:Class="WP7Fanfou.App"
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">

<!--Application Resources-->
<Application.Resources>

</Application.Resources>

<Application.ApplicationLifetimeObjects>
<!--Required object that handles lifetime events for the application-->
<shell:PhoneApplicationService
Launching="Application_Launching" Closing="Application_Closing"
Activated="Application_Activated" Deactivated="Application_Deactivated"/>
</Application.ApplicationLifetimeObjects>

</Application>


App.xaml.cs

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.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace WP7Fanfou
{
public partial class App : Application
{
/// <summary>
/// Provides easy access to the root frame of the Phone Application.
/// </summary>
/// <returns>The root frame of the Phone Application.</returns>
public PhoneApplicationFrame RootFrame { get; private set; }

/// <summary>
/// Constructor for the Application object.
/// </summary>
public App()
{
// Global handler for uncaught exceptions.
UnhandledException += Application_UnhandledException;

//下面的代码调试的时候才会用到
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
// Display the current frame rate counters. 显示当前页面的画面更新率,就是右边那一堆数字
//Application.Current.Host.Settings.EnableFrameRateCounter = true;

// Show the areas of the app that are being redrawn in each frame.被重画的区域
//Application.Current.Host.Settings.EnableRedrawRegions = true;

//注[1]!
// Enable non-production analysis visualization mode,
// which shows areas of a page that are being GPU accelerated with a colored overlay.
//Application.Current.Host.Settings.EnableCacheVisualization = true;
}

// Standard Silverlight initialization
InitializeComponent();

// Phone-specific initialization
InitializePhoneApplication();
}

// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}

// Code to execute when the application is activated (brought to foreground)
// This code will not execute when the application is first launched
private void Application_Activated(object sender, ActivatedEventArgs e)
{
}

// Code to execute when the application is deactivated (sent to background)
// This code will not execute when the application is closing
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}

// Code to execute when the application is closing (eg, user hit Back)
// This code will not execute when the application is deactivated
private void Application_Closing(object sender, ClosingEventArgs e)
{
}

// Code to execute if a navigation fails
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// A navigation has failed; break into the debugger
System.Diagnostics.Debugger.Break();
}
}

// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}

#region Phone application initialization

// Avoid double-initialization
private bool phoneApplicationInitialized = false;

// Do not add any additional code to this method
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;

// Create the frame but don't set it as RootVisual yet; this allows the splash
// screen to remain active until the application is ready to render.
RootFrame = new PhoneApplicationFrame();
RootFrame.Navigated += CompleteInitializePhoneApplication;

// Handle navigation failures
RootFrame.NavigationFailed += RootFrame_NavigationFailed;

// Ensure we don't initialize again
phoneApplicationInitialized = true;
}

// Do not add any additional code to this method
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
// Set the root visual to allow the application to render
if (RootVisual != RootFrame)
RootVisual = RootFrame;

// Remove this handler since it is no longer needed
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}

#endregion
}
}


MainPage.xaml

说明一下几个属性:

d:DesignWidth,d:DesignHeigh :在使用blend设计页面的时候比较有用。如果页面中的Height 和Width设置为Auto那么用Blend打开页面的时候,页面的显示区域会变成0,如果设置这两个属性,用Blend打开的时候会以你设置的大小显示。

SupportedOrientations:属性有三个枚举值,分别是:Landscape(支持水平方向)、Portrait(支持垂直方向)、PortraitOrLandscape(支持水平和垂直方向)

SystemTray.IsVisible:系统托盘信息,资料上说设置为true可以看到系统托盘的信息。

OrientationChanged:手机翻转时调用的事件

<phone:PhoneApplicationPage
x:Class="WP7Fanfou.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="PortraitOrLandscape"
Orientation="Portrait"
shell:SystemTray.IsVisible="True"
Loaded="PhoneApplicationPage_Loaded"
OrientationChanged="PhoneApplicationPage_OrientationChanged">

<!--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="随便看看" Style="{StaticResource PhoneTextNormalStyle}" mce_Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="饭否" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" mce_Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>

<!--内容列表,跟Android布局很相似-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,12,0">
<ListBox  HorizontalAlignment="Left" Name="listBox1" Width="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132" >
<Image Source="{Binding User.ProfileImageUrl}" Height="100" Width="100" VerticalAlignment="Top" Margin="0,10,8,0" ></Image>
<StackPanel>
<TextBlock Text="{Binding User.Name}" FontSize="36" TextWrapping="Wrap" Foreground="#FF4BCBB7" />
<TextBlock Text="{Binding Text}" FontSize="20" TextWrapping="Wrap"  Width="300" />
</StackPanel>
</StackPanel>

</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>

<!--这段被注释的是下边的按钮条-->
<!--<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>


MainPage.xaml.cs

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;
using Fanfou.Model;

namespace WP7Fanfou
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();

}
List<FanfouStatus> statuses = new List<FanfouStatus>();
/// <summary>
/// PageLoad事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
Fanfou.Data.FanfouData data = new Fanfou.Data.FanfouData();
data.UserName = "xxxxx";//用户名
data.UserPass = "xxxxx";//密码
statuses = data.GetStatusData();//获取数据
data.Analysis += new Fanfou.Data.FanfouData.AnalysisEventHandler(data_Analysis);//数据下载并处理完毕后

}

/// <summary>
/// 数据处理完毕后绑定到Listbox上
/// </summary>
/// <param name="sender"></param>
void data_Analysis(object sender)
{
listBox1.ItemsSource = statuses;

}

/// <summary>
/// 手机翻转事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
//向左翻转,头部在左
if (PageOrientation.LandscapeLeft == e.Orientation)
{
//TODO:处理
}
//向右翻转,头部在右
if (PageOrientation.LandscapeRight == e.Orientation)
{
//TODO:处理
}
//竖直放置,头部在上
if (PageOrientation.PortraitDown == e.Orientation)
{
//TODO:处理
}
//倒置放置,头部在下
if (PageOrientation.PortraitUp == e.Orientation)
{
//TODO:处理
}

}
}
}


我是一边查资料一边做的,参考的资料比较多,没有记下来。很多细节的地方都不懂,在这里将这些作为笔记吧。学习WP7 第一步!希望能和大家一起交流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: