着是我的第一篇教学blog,各位看官手下留情...近期在网上接了一个任务,在windowphone平台下开发一个Rss的阅读器,平时一直在做winform开发,windowphone还没接触过,于是上网查了一下相关的资料,接下来容我来解释一下windowphone的几个特性;
case 1: 本地存储,Isolated Storage又叫做隔离存储空间,Windows Phone 7手机上用来本地存储数据。Isolated Storage用来创建与维护本地存储。WP7上的架构和Windows下的Silverlight类似,所有的读写操作都只限于隔离存储空间并且无法直接访问磁层操作系统的文件系统。这样能够防止非法的访问以及其他应用的破坏,增强安全性。
case 2:页面传值,这一点又跟winform有些差别,倒有点像web的页面传值qure传值的方式。
case 3:页面跳转的方式又跟web一样采用的是navigate导航的方式跳转,然后可以用goback()返回.
介绍完了着几个特性之后,再来分析一下需求文档,首先要先做一个登陆的界面,能勾选保存账号,这就需要用到本地存储了
勾选记住密码之后,用,IsolatedStorageFile类来存储账号,密码还有勾选状态,然后下次打开页面之后再读取之前保存好的文件判断勾选状态,是就把账号密码分别赋给账号框和密码框然后再选中radiobutton
图2是跳转的页面,用来显示rss源信息,RSS(简易信息聚合,也叫聚合内容)是一种描述和同步网站内容的格式 ,你可以在各大网站订阅rss源信息,然后加载到阅读器,然后用web协议解析,你会发现解析后的Rss其实都是XML格式,这里我使用了一条Lnq语句,查询出rss的title和url然后循环加载到listbox上面,item保存title,tag保存url;为了让添加rss源更方便,我让鼠标点击到添加源的textbox上面的时候自动获取系统剪切板的内容,然后用正则表达式判断是否是url的格式是就添加进去;点击加载好的节点,跳转到图3;
最后一步,获取选中的listboxitem的tag值,然后传递给下个page,窗体3里面我放了一个webbrowser,接受到url之后直接导航到那个地址,这样就完了吗?哈哈,让客户等待是最不好的体验,所以我又加了一个滚动条在页面上,给webbrowser注册两个事件,导航中和导航结束后,不得不说这个滚动条比winform的好看多了- -!
最后附上源码,还有很多地方需要完善,比如界面...硬伤,没多少美术细胞
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 System.IO;
using System.IO.IsolatedStorage;
using System.Xml.Linq;
namespace RssReader
{
public partial class MainPage : PhoneApplicationPage
{
// 构造函数
public MainPage()
{
InitializeComponent();
}
public string LoginID { get; set; }
public string LoginPwd { get; set; }
public int RadioIsCheck { get; set; }
private void button1_Click(object sender, RoutedEventArgs e)
{
if (textBox1.Text == LoginID && passwordBox1.Password == LoginPwd)
{
//MessageBox.Show("登陆成功");
NavigationService.Navigate(new Uri("/StartPage.xaml",UriKind.Relative));
}
else
{
MessageBox.Show("账号/密码错误");
}
}
/// <summary>
/// 加载本地文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
LoadLoginInfo();
}
/// <summary>
/// 读取本地信息
/// </summary>
private void LoadLoginInfo()
{
#region 读取本地存储,是否有登陆信息
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isf.FileExists("UserInfo.xml"))
{
using (IsolatedStorageFileStream isoStream = isf.OpenFile("UserInfo.xml", FileMode.Open, FileAccess.Read))
{
XElement xel = XElement.Load(isoStream);
IEnumerable<XElement> das = from el in xel.DescendantsAndSelf() select el;
foreach (var item in das)
{
LoginID = item.Element("ID").Value;
LoginPwd = item.Element("PWD").Value;
RadioIsCheck = int.Parse(item.Element("check").Value);
if (RadioIsCheck == 1)
{
textBox1.Text = LoginID;
passwordBox1.Password = LoginPwd;
radioButton1.IsChecked = true;
}
else { }
return;
}
}
}
else
{
radioButton1.Visibility = Visibility.Collapsed;
button1.Visibility = Visibility.Collapsed;
button2.Visibility = Visibility.Visible;
}
}
#endregion
}
/// <summary>
/// 注册
/// </summary>
private void button2_Click(object sender, RoutedEventArgs e)
{
LoginID = textBox1.Text;
LoginPwd = passwordBox1.Password;
#region 注册
if (string.IsNullOrEmpty(textBox1.Text) || string.IsNullOrEmpty(passwordBox1.Password)) return;
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isf.FileExists("UserInfo.xml"))
{
isf.DeleteFile("UserInfo.xml");
}
using (IsolatedStorageFileStream isoStream = isf.OpenFile("UserInfo.xml", FileMode.OpenOrCreate, FileAccess.Write))
{
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XElement("NewbieDiary"));
doc.Element("NewbieDiary").Add(new XElement("UserInfo"),
new XElement(("ID"), LoginID),
new XElement(("PWD"), LoginPwd),
new XElement(("check"), 0));
doc.Save(isoStream);
}
}
//MessageBox.Show("注册成功");
#endregion
button1.Visibility = Visibility.Visible;
radioButton1.Visibility = Visibility.Visible;
button2.Visibility = Visibility.Collapsed;
textBox1.Text = "输入账号";
passwordBox1.Password = "";
}
private void textBox1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (textBox1.Text == "输入账号") { textBox1.Text = ""; }
return;
}
bool rbischeck = false;
private void radioButton1_Click(object sender, RoutedEventArgs e)
{
if (rbischeck == false)
{
rbischeck = true;
radioButton1.IsChecked = rbischeck;
radioButton1.IsChecked = rbischeck;
RadioButtonIsCheck(rbischeck);
textBox1.Text = LoginID;
passwordBox1.Password = LoginPwd;
}
else
{
rbischeck = false;
radioButton1.IsChecked = rbischeck;
textBox1.Text = "输入账号";
passwordBox1.Password = "";
RadioButtonIsCheck(rbischeck);
}
}
/// <summary>
/// 选择框是否选中
/// </summary>
/// <param name="rbischeck">是/否</param>
private void RadioButtonIsCheck(bool rbischeck)
{
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
if (isf.FileExists("UserInfo.xml"))
{
isf.DeleteFile("UserInfo.xml");
using (IsolatedStorageFileStream isoStream = isf.OpenFile("UserInfo.xml", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XElement("NewbieDiary"));
int i = 0;
if (rbischeck)
{
i = 1;
}
doc.Element("NewbieDiary").Add(new XElement("UserInfo"),
new XElement(("ID"), LoginID),
new XElement(("PWD"), LoginPwd),
new XElement(("check"), i));
doc.Save(isoStream);
}
}
}
}
}
}
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 System.IO;
using System.Xml.Linq;
using System.Text.RegularExpressions;
namespace RssReader
{
public partial class StartPage : PhoneApplicationPage
{
public StartPage()
{
InitializeComponent();
}
//添加源
private void button1_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(textBox1.Text)) return;
ReadRss(new Uri(textBox1.Text, UriKind.Absolute));
}
//跳转
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
HyperlinkButton hlb = (HyperlinkButton)sender;
MessageBox.Show(hlb.NavigateUri.ToString());
}
//设置
private void button2_Click(object sender, RoutedEventArgs e)
{
}
/// <summary>
/// 获取Rss列表
/// </summary>
/// <param name="rssUri">Rss地址</param>
public void ReadRss(Uri rssUri)
{
WebClient wclient = new WebClient();
wclient.OpenReadCompleted += (sender, e) =>
{
if (e.Error != null)
return;
Stream str = e.Result;
XDocument xdoc = XDocument.Load(str);
//取前20个读取到的Rss
List<RSSFeedItem> rssFeedItems = (from item in xdoc.Descendants("item")
select new RSSFeedItem()
{
Title = item.Element("title").Value,
URL = new Uri(item.Element("link").Value, UriKind.Absolute),
}).Take(20).ToList();
//关闭流
str.Close();
//加载到显示控件
listBox1.Items.Clear();
//rssFeedItems.ForEach(item => listboxRSSFeedItems.Items.Add(item));
for (int i = 0; i < rssFeedItems.Count; i++)
{
ListBoxItem item = new ListBoxItem();
TextBlock textBlock = new TextBlock();
textBlock.Text = rssFeedItems[i].Title;
item.Content = textBlock;
listBox1.Items.Add(item);
item.Tag = rssFeedItems[i].URL;
}
};
wclient.OpenReadAsync(rssUri);
}
private void textBox1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
textBox1.Text = "http://rss.sina.com.cn/blog/index/cul.xml";
if (Clipboard.ContainsText())
{
try
{
string url = Clipboard.GetText();
string regexString = @"([\w\d]+\.)+\w{2,}(\/[\d\w\.\?=&]+)*";
if (Regex.IsMatch(url, regexString))
{
textBox1.Text = "http://rss.sina.com.cn/blog/index/cul.xml";
}
}
catch { return; }
}
}
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox lb = (ListBox)sender;
string url = ((ListBoxItem)lb.SelectedItem).Tag.ToString();
NavigationService.Navigate(new Uri("/PageRssRead.xaml",UriKind.Relative));
PageRssRead.url = url;
}
}
}