[转载]Silverlight+WCF 实战-网络象棋最终篇之解决重复的消息提示(八)

mikel阅读(892)

[转载]Silverlight+WCF 实战-网络象棋最终篇之解决重复的消息提示(八) – 路过秋天 – 博客园.

前言:

最近有网友经常会问,在跟着做象棋对战的通讯中,在重复退出进入的时候,消息会重复出现,本节就这问题进行解说与优化。

一:分析问题产生的原因?

1:首先看App.xaml,里面定义了一个全局客户端回调:

public static GameService.ServiceClient client;//回调的客户端

并且这个回调我们全局只实例化一次,并且默认加载时定位到登陆页面:

private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = root;
root.Children.Add(
new Login());//默认定位到登录页面。
}

2:再看登录页面Login.xaml里,构造函数的初始化:

public Login()
{
InitializeComponent();
App.client.LoginCompleted
+= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LoginCompleted);
Load();
}

我们对App.client.LoginCompleted初始化了一次事件,这时一切是正常的,接着我们进入房间,之后,我们返回系统回到登陆。

3:接着看退出系统的按钮是怎么返回到登陆页面的:

//退出系统
private void btnLogout_Click(object sender, RoutedEventArgs e)
{
if (App.chess.IsGaming)
{
btnGameLose_Click(
null, null);//发送认输
App.chess.IsGaming = false;
}
App.client.OutRoomAsync(App.player, App.player.RoomID, App.player.AttachInfo);
((App)Application.Current).RedirectTo(
new Login());
}

看最后一行,我们又New Login了,这种情况,刚才第二步中的:App.client.LoginCompleted事件将被重复注册,因此,重复的事件注册引发了重复的消息提示。

问题总结说明:

对于消息的重复提示,基本都属于事件的重复注册造成的,我们之前的代码很多转向都使用new 控件()的方式在各个页面切换时,于是容易产生这种问题。

二:解决消息重复问题

从第一步中,我们分析到问题产生的根源,于是,我们可以想出很多方式,来解决这种问题,这里我介绍两种方式:

先来看一下错误任法:注册事件前加先减,再加,示例代码如下:

App.client.LoginCompleted -= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LoginCompleted);
App.client.LoginCompleted
+= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_LoginCompleted);

网上有人说:每次注册前先去掉一下,然后再增加,逻辑上看起来好像没问题,刚自己试了下,纯忽悠型。

现在介绍下我想到的两种方式:

1:定义全局变量List<事件名称>,保存注册过的事件名称

逻辑:在每次事件产生前,先判断一下事件是否存在,不存在则添加,存在则跳过,此方法实现简单,大伙一说就应该会了,所以直接跳过了。

2:定义全局变量保存所有房间,于是在RedirectTo切换房间的时候,避免使用New 控件() 来避免再次执行事件注册事件

下面进行代码整改:

A:App.xaml全局定义每个房间的变量,并改造成属性,所幸控件就几个,定义也费不了多少力,代码如下:

private static Login loginObj;
public static Login LoginObj
{
get
{
if (loginObj == null)
{
loginObj
= new Login();
}
//loginObj.Reset();
return loginObj;
}
}
private static Room roomObj;
public static Room RoomObj
{
get
{
if (roomObj == null)
{
roomObj
= new Room();
}
//roomObj.Reset();
return roomObj;
}
}
private static Index indexObj;
public static Index IndexObj
{
get
{
if (indexObj == null)
{
indexObj
= new Index();
}
//indexObj.Reset();
return indexObj;
}
}

说明:

这里有两点:1是改造属性方式,这样在调用时不用再写判断语句,2是注册的Reset()方法,后面会开启到。

B:查找调用RedirectTo切换界面的代码,替换为:App.xxxxObj

随便找个RedirectTo,右键查找所有引用,看看有几个要修改的地方,所幸也不多,如下图:

说明:

按上面的查找出来的代码,一个一个更改即可,如把new Index()换成App.IndexObj。

OK,消息提示重复的问题,至此,是解决了,但是,将产生一点副作用,就是切回去的时候,状态需要重置。

简单的示例说明就是:

点登陆时,把按钮设置为不可用,然后你进去,再退出,看到的是“不可用”的按钮就没法再进去了。

OK,状态重置的问题,就留到下节解决了。

本节没关联啥好看图片,就随便挂一张在下面让大伙欣赏了:

[转载]android开发我的新浪微博客户端-OAuth篇(2.1)

mikel阅读(922)

[转载]android开发我的新浪微博客户端-OAuth篇(2.1) – 遇见未知的自己 – 博客园.

本篇说说关于OAuth授权认证的事情,新浪开放api都必须在这个基础上才能调用,所以有必要专门来讲讲,前面的文章中已经提到过关于新浪微博提供了 OAuth和Base OAuth两种认证方式,并且本项目采用OAuth认证方式,至于为什么采用这个OAuth认证而不采用Base OAuth认证原因很简单,自从Twitter只支持OAuth认证方式以来,各大应用都纷纷转向OAuth认证方式,而新浪微博的开放平台也将在近日停 止Base OAuth的认证方式。

OAuth的基本概念,OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第 三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。同样新浪微 博提供OAuth认证也是为了保证用户账号和密码的安全,在这里通过OAuth建立普通新浪微博用户、客户端程序(我们正在开发的这个Android客户 端程序)、新浪微博三者之间的相互信任关系,让客户端程序(我们正在开发的这个Android客户端程序)不需要知道用户的账号和密码也能浏览、发布微 博,这样有效的保护了用户账号的安全性不需要把账号密码透露给客户端程序又达到了通过客户端程序写微博看微博目的。这个是OAuth的作用。

结合新浪微博的OAuth认证来说说具体的功能实现,首先罗列一下关键字组,下面四组关键字跟我们接下来OAuth认证有非常大的关系。

第一组:(App Key和App Secret),这组参数就是本系列文本第一篇提到的建一个新的应用获取App Key和App Secret。

第二组:(Request Token和Request Secret)

第三组:(oauth_verifier

第四组:(user_id、Access Token和Access Secret)

新浪微博的OAuth认证过程,当用户第一次使用本客户端软件时,客户端程序用第一组作为参数向新浪微博发起请求,然后新浪微博经过验证后返回第二组参数给客户端软件同时表示新浪微博信任本客户端软件,当客户端软件获取第二组参数时作为参数引导用户浏览器跳至新浪微博的授权页面, 然后用户在新浪的这个授权页面里输入自己的微博账号和密码进行授权,完成授权后根据客户端设定的回调地址把第三组参数返回给客户端软件并表示用户也信任本 客户端软件,接下客户端软件把第二组参数和第三组参数作为参数再次向新浪微博发起请求,然后新浪微博返回第四组参数给客户端软件,第四组参数需要好好的保 存起来这个就是用来代替用户的新浪账号和密码用的,在后面调用api时都需要。从这个过程来看用户只是在新浪微博的认证网页输入过账户和密码并没有在客户 端软件里输入过账户和密码,客户端软件只保存了第四组数据并没有保存用户的账户和密码,这样有效的避免了账户和密码透露给新浪微博之外的第三方应用程序, 保证 了安全性。

本项目用为了方便开发采用了oauth-signpost开源项目进行OAuth认证开发,新建OAuth.java 类文件对OA进行简单的封装,OAuth类主要有RequestAccessToken、GetAccessToken、SignRequest三个方 法,第一个方法RequestAccessToken就是上面过程中用来获取第三组参数用的,GetAccessToken方法是用来获取第四组参数 用,SignRequest方法是用来调用api用。由于采用了oauth-signpost开源项目简单了很多。具体代码如下:

代码

public class OAuth {
private CommonsHttpOAuthConsumer httpOauthConsumer;
private OAuthProvider httpOauthprovider;
public String consumerKey;
public String consumerSecret;

public OAuth()
{
// 第一组:(App Key和App Secret)
// 这组参数就是本系列文本第一篇提到的建一个新的应用获取App Key和App Secret。
this(3315495489,e2731e7grf592c0fd7fea32406f86e1b);
}
public OAuth(String consumerKey,String consumerSecret)
{
this.consumerKey=consumerKey;
this.consumerSecret=consumerSecret;
}

public Boolean RequestAccessToken(Activity activity,String callBackUrl){
Boolean ret
=false;
try{
httpOauthConsumer
= new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);
httpOauthprovider
= new DefaultOAuthProvider(http://api.t.sina.com.cn/oauth/request_token,http://api.t.sina.com.cn/oauth/access_token,http://api.t.sina.com.cn/oauth/authorize);
String authUrl
= httpOauthprovider.retrieveRequestToken(httpOauthConsumer, callBackUrl);
activity.startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
ret
=true;
}
catch(Exception e){
}
return ret;
}

public UserInfo GetAccessToken(Intent intent){
UserInfo user
=null;
Uri uri
= intent.getData();
String verifier
= uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
try {
httpOauthprovider.setOAuth10a(
true);
httpOauthprovider.retrieveAccessToken(httpOauthConsumer,verifier);
}
catch (OAuthMessageSignerException ex) {
ex.printStackTrace();
}
catch (OAuthNotAuthorizedException ex) {
ex.printStackTrace();
}
catch (OAuthExpectationFailedException ex) {
ex.printStackTrace();
}
catch (OAuthCommunicationException ex) {
ex.printStackTrace();
}
SortedSet
<String> user_id= httpOauthprovider.getResponseParameters().get(user_id);
String userId
=user_id.first();
String userKey
= httpOauthConsumer.getToken();
String userSecret
= httpOauthConsumer.getTokenSecret();
user
=new UserInfo();
user.setUserId(userId);
user.setToken(userKey);
user.setTokenSecret(userSecret);
return user;
}

public HttpResponse SignRequest(String token,String tokenSecret,String url,List params)
{
HttpPost post
= new HttpPost(url);
//HttpClient httpClient = null;
try{
post.setEntity(
new UrlEncodedFormEntity(params,HTTP.UTF_8));
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//关闭Expect:100-Continue握手
//100-Continue握手需谨慎使用,因为遇到不支持HTTP/1.1协议的服务器或者代理时会引起问题
post.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
return SignRequest(token,tokenSecret,post);
}

public HttpResponse SignRequest(String token,String tokenSecret,HttpPost post){
httpOauthConsumer
= new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);
httpOauthConsumer.setTokenWithSecret(token,tokenSecret);
HttpResponse response
= null;
try {
httpOauthConsumer.sign(post);
}
catch (OAuthMessageSignerException e) {
e.printStackTrace();
}
catch (OAuthExpectationFailedException e) {
e.printStackTrace();
}
catch (OAuthCommunicationException e) {
e.printStackTrace();
}
//取得HTTP response
try {
response
= new DefaultHttpClient().execute(post);
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return response;
}
}

这样就完成了OAuth功能类的开发,后面都会用到这个类相关的方法。本篇到这里就算是完结请继续关注后面的文章。

[转载]QQ协议辅助分析工具(QQAnalyzer)

mikel阅读(2213)

[转载]QQ协议辅助分析工具(QQAnalyzer) – shiqishe – 博客园.

最近研究了一把QQ的通讯协议,发现没有什么好的分析工具,特别是在抓包处理这一块上。所以自己写了个比较方便的工具。

软件写得比较粗糙,BUG还不少,欢迎试用。有什么问题可以发邮件给我修改。

下载地址:http://u.115.com/file/f77cbe0dbe

本软件用于辅助分析QQ协议。

软件能够自动识别并抓取QQ数据包,自动分析QQ登录过程数据包。支持QQ UDP、TCP、代理模式的数据包抓取与分析。

同时支持wireshark抓取的PCAP数据格式文件的读取。

使用方法:

1.启动QQAnalyzer,点击“抓包设置”按钮设置抓包使用的网卡及过滤器。

2.抓包设置确定后,任务栏的“开始抓包”按钮已激活。点击开始抓取数据包,打开QQ软件并登录,软件会自动识别QQ的数据包并过滤掉不需要的数据包,抓取的数据包会实时显示在软件界面上,包括协议,IP地址,端口等五元组信息。

3.停止抓包后,即可分析抓取的数据包了。QQ登录过程中有很多次密钥生成和传递,为方便分析,可以标记不同的密钥,并在需要的时刻使用这些密钥,最新版本的QQAnalyzer已经

完成了自动分析功能。可以在需要的分析的数据包点右键,直接选择自动分析。

4.需要使用已标记的密钥解密时可以直接使用。解密后的数据会突出已红色显示。当选择自动分析后,程序会自动分析当前QQ数据包的命令,并将其密文解密出来,

将相关信息直接批注在密文后面。

5.软件可将当前数据保存为RTF或TXT或者PCAP格式。方便下次接着处理。同时支持PCAP,TXT,RFT格式文件读取。

6.软件提供专门的TEA加解密模块,以及各种字符串编解码、MD5计算、QQ十六进制、IP十六进制、时间十六进制相互转换等功能。

7.QQAnalyzer最新版本为1.3.0.0,欢迎下载试用。

[转载]asp.net文本编辑器FCKeditor使用方法详解

mikel阅读(1047)

[转载]asp.net文本编辑器FCKeditor使用方法详解 – 记录.net – 博客园.

效果图:

那么为什么说是FCKeditor的冰冷之心呢?这不是哗众取宠,主要是说它使用起来有点麻烦,下文就详细说明如何搞定这玩意儿。

1.FCKeditor的官方网站是:http://www.fckeditor.net/download
目前最新的FCKeditor 2.4.2版本。
请在此页下载:http://sourceforge.net/project/showfiles.php?group_id=75348
如图所示:

要下载FCKeditor2.4.2.zip和   FCKeditor.NET版的2个zip包。

说明:
FCKeditor2.4.2.zip是其最新的JavaScript文件和图片什么的;
FCKeditor.NET.zip是ASP.NET调用的DLL在里面。

2.分别解压后把FCKeditor2.4.2.zip里的fckeditor目录整个复制到网站中。

3.解压FCKeditor.NET.zip包后在FCKeditor.Net_2.2\bin\Debug目录里找到FredCK.FCKeditorV2.dll。其他文件没用,把FredCK.FCKeditorV2.dll复制到我们的网站,建立一个Bin目录

4.引用FredCK.FCKeditorV2.dll。
第一步:

第二步:

5.导入工具箱。
在“工具箱”下右键

点击“选择项”。弹出如图窗口:

点击浏览,找到dll所在目录。

这时发现工具箱里多出FCKeditor控件。

6.拖拽FCKeditor到页面上

7.配置WebConfig
<?xml version=”1.0″?>
<!–
注意: 除了手动编辑此文件以外,您还可以使用
Web 管理工具来配置应用程序的设置。可以使用 Visual Studio 中的
“网站”->“ASP.NET 配置”选项。
设置和注释的完整列表在
machine.config.comments 中,该文件通常位于
\Windows\Microsoft.Net\Framework\v2.x\Config 中
–>
<configuration>
<appSettings>

<add key=”FCKeditor:BasePath” value=”~/fckeditor/”/>

<add key=”FCKeditor:UserFilesPath” value=”/Files/” />

</appSettings>

<connectionStrings/>
<system.web>

说明:BasePath是fckeditor所在路径,fckeditor由于我们直接放网站目录下这样写就可以,如果您的网站多放几层适当调整即可。
UserFilesPath所有上传的文件的所在目录。为什么要设置成/Files这样而不是~/Files因为FCKeditor使用这个值来返回你上传后的文件的相对路径到客户端。否则的话客户访问的时候就会取客户的机器目录而不是http形式的目录。

建议:Files要单独做wwwroot目录下的一个站点比较好,和我们的站点FCKEditor平行。不要把它放FCKEditor里,为什么呢?因为Files是要让客户有写的权限的,如果放FCKEditor下很危险。

8.Files目录要有的权限。你根据自己网站需求设置那个帐号,本文为方便设置User实际中你可能用ASP.NET帐号更合理。

9.修改fckeditor/fckconfig.js文件
在第182行的位置
var _FileBrowserLanguage = ‘asp’ ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = ‘asp’ ; // asp | aspx | cfm | lasso | php
改为
var _FileBrowserLanguage = ‘aspx’ ; // asp | aspx | cfm | lasso | perl | php | py
var _QuickUploadLanguage = ‘aspx’ ; // asp | aspx | cfm | lasso | php

10.FCKeditor给其瘦身。以_打头的的都是范例文件或源文件,不过建议小心。

11.下面以上传图片示例说明如何使用,

点击“浏览服务器”。

弹出窗口很容易报错

如果报错XML request error: Internal Server Error(500),很可能就是目录路径不对和写权限没有。

选择图像



最后效果

前台代码:

<%@ Page Language=”C#validateRequest=false AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>

<%@ Register Assembly=”FredCK.FCKeditorV2″ Namespace=”FredCK.FCKeditorV2″ TagPrefix=”FCKeditorV2″ %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“>

<html xmlns=”http://www.w3.org/1999/xhtml” >
<head runat=”server”>
<title>FCKeditor文本编辑器</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<fckeditorv2:fckeditor id=”FCKeditor1″ runat=”server” DefaultLanguage=”zh-cn” Height=”400px” Width=”660px”
></fckeditorv2:fckeditor>

</div>
</form>
</body>
</html>

怎么样获取结果呢?FCKeditor1.Value就是。

[转载]使用cookies实现浏览历史记录功能

mikel阅读(1110)

[转载]使用cookies实现浏览历史记录功能 – muzhiye – 博客园.

1.创建历史记录的实体类

public class LastProducts
{
private int _productid;
private int _categoryid;
private string _imgsrc;
private string _productname;

public LastProducts(int id,int typeid,string imgsrc,string restorename)
{
_productid = id;
_categoryid = typeid;
_imgsrc = imgsrc;
_productname = restorename;
}

public int ProductId
{
get { return _productid; }
}

public int CategoryId
{
get { return _categoryid; }
}

public string ImgSrc
{
get { return _imgsrc; }
}

public string ProductName
{
get { return _productname; }
}
}

2.定义存储cookies的方法

public void HistoryRestore(string cookieName,int objectID)
{
HttpRequest Request = HttpContext.Current.Request;
HttpResponse Response = HttpContext.Current.Response;

if (Request.Cookies[cookieName] != null)
{
HttpCookie tempCurBuyerList = Request.Cookies[cookieName];
string tempstr = tempCurBuyerList.Value;
if (tempstr.IndexOf(“,”) > 0)
{
string[] sArray = tempstr.Split(‘,’);
bool hasthis = false;

foreach (string s in sArray)
{
if (s == objectID.ToString())
{
hasthis = true;
break;
}
else
{
hasthis = false;
}
}

if (!hasthis)   //如果没有ID,则加入
{
if (sArray.Length > 3) //3为存储浏览记录数的数量,实际数量为7
{
// 超过数量,去掉最先入队的元素
tempstr = tempstr.Substring(0, tempstr.LastIndexOf(“,”));
}
// 队列
tempstr = objectID.ToString() + “,” + tempstr;
}
}
else
{
//tempstr += “,” + objectID.ToString();
if (tempstr != objectID.ToString())
{
tempstr = objectID.ToString() + “,” + tempstr;
}
}
tempCurBuyerList.Value = tempstr;
tempCurBuyerList.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(tempCurBuyerList);
//或者 Response.Cookies[cookieName].Value = tempstr;
}
else
{
HttpCookie addToCookies = new HttpCookie(cookieName);
addToCookies.Value = objectID.ToString();
addToCookies.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(addToCookies);
}
}

3.读取cookies存储数据

public List<LastProducts> GetLastProducts()
{
HttpRequest Request = HttpContext.Current.Request;

List<LastProducts> list = null;

if (Request.Cookies[“restoreid”] != null)
{
HttpCookie tempCurBuyerList = Request.Cookies[“restoreid”];

string[] strArr = tempCurBuyerList.Value.Split(‘,’);
list = new List<LastProducts>();

foreach (string s in strArr)
{
ShopProduct model = dal.GetProById(int.Parse(s)); //商品的实体类
if (model != null)
{
list.Add(new Model.Shop.LastProducts(model.ProductID, model.CategoryID, model.ImageHref, model.Name));
}
}
}

return list;
}

4.在用户浏览某产品时记录到cookies中:

HistoryRestore(“restoreid”,productId);

5.数据源的绑定

Repeater1.DataSource = GetLastProducts();
Repeater1.DataBind();

[转载]android开发我的新浪微博客户端-载入页面sqlite篇(1.2)

mikel阅读(865)

[转载]android开发我的新浪微博客户端-载入页面sqlite篇(1.2) – 遇见未知的自己 – 博客园.

通过上一篇文章(Android开发我的新浪微博客户端-载入页面UI篇(1.1))已经完成了载入页面的UI部分的实现,效果如上图,接下来在上面的基础上完成载入页面的功能代码。

首先说明一下新浪微博提供了OAuth和Base OAuth两种认证方式(如果不知道什么是OAuth和Base OAuth请自己google一下恶补,同时接下来的2篇随笔也会对这方面进行详细的说明以及具体实现),本项目是采用OAuth认证方式,采用这种方式 就需要有用户的新浪UserID、Access Token、Access Secret这3样东西才能自由便利的调用新浪的开放接口,本项目是这样做的当用户第一次使用软件时进行授权认证获取这3样东西的时候存储到SQLite 库中以便用户下次使用时不需要重新进行繁琐的授权认证操作直接从SQLite库中读取出来即可,由于这样的需求载入页面的功能设定是这样:当用户打开软件 显示载入页面时开始检查SQLite库中是否已经保存有用户的新浪微博的UserID号、Access Token、Access Secret的记录,如果一条记录都没有那就说明用户是第一次使用本软件那么跳到认证授权页面进行授权认证操作(认证授权功能在接下来的两篇中进行实现讲 解)获取这3个值保存到sqlite库中,如果已经包括了记录,那么读取这些记录的UserID号、Access Token、Access Secret值然后根据这3个值调用新浪的api接口获取这些记录对应的用户昵称和用户头像图标等信息。

上面功能设定中涉及到sqlite数据库的创建、数据表的创建、数据记录的添加、数据记录的读取等操作,这里新建名为SqliteHelper.java类文件提供sqlite数据表的创建、更新等,代码如下:

代码

public class SqliteHelper extends SQLiteOpenHelper{
//用来保存

UserID、Access Token、Access Secret

的表名
public static final String TB_NAME=users;
public SqliteHelper(Context context, String name, CursorFactory factory, int version) {
super(context, name, factory, version);
}
//创建表
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
CREATE TABLE IF NOT EXISTS +
TB_NAME
+(+
UserInfo.ID
+ integer primary key,+
UserInfo.USERID
+ varchar,+
UserInfo.TOKEN
+ varchar,+
UserInfo.TOKENSECRET
+ varchar,+
UserInfo.USERNAME
+ varchar,+
UserInfo.USERICON
+ blob+
)
);
Log.e(
Database,onCreate);
}
//更新表
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(
DROP TABLE IF EXISTS + TB_NAME);
onCreate(db);
Log.e(
Database,onUpgrade);
}
//更新列
public void updateColumn(SQLiteDatabase db, String oldColumn, String newColumn, String typeColumn){
try{
db.execSQL(
ALTER TABLE +
TB_NAME
+ CHANGE +
oldColumn
+ + newColumn +
+ typeColumn
);
}
catch(Exception e){
e.printStackTrace();
}
}
}

接下来新建名为DataHelper.java类文件实现用户记录的创建、更新、删除等,代码如下:

代码

public class DataHelper {
//数据库名称
private static String DB_NAME = mysinaweibo.db;
//数据库版本
private static int DB_VERSION = 2;
private SQLiteDatabase db;
private SqliteHelper dbHelper;

public DataHelper(Context context){
dbHelper
=new SqliteHelper(context,DB_NAME, null, DB_VERSION);
db
= dbHelper.getWritableDatabase();
}

public void Close()
{
db.close();
dbHelper.close();
}
//获取users表中的UserID、Access Token、Access Secret的记录
public List<UserInfo> GetUserList(Boolean isSimple)
{
List
<UserInfo> userList = new ArrayList<UserInfo>();
Cursor cursor
=db.query(SqliteHelper.TB_NAME, null, null, null, null, null, UserInfo.ID+ DESC);
cursor.moveToFirst();
while(!cursor.isAfterLast()&& (cursor.getString(1)!=null)){
UserInfo user
=new UserInfo();
user.setId(cursor.getString(
0));
user.setUserId(cursor.getString(
1));
user.setToken(cursor.getString(
2));
user.setTokenSecret(cursor.getString(
3));
if(!isSimple){
user.setUserName(cursor.getString(
4));
ByteArrayInputStream stream
= new ByteArrayInputStream(cursor.getBlob(5));
Drawable icon
= Drawable.createFromStream(stream, image);
user.setUserIcon(icon);
}
userList.add(user);
cursor.moveToNext();
}
cursor.close();
return userList;
}

//判断users表中的是否包含某个UserID的记录
public Boolean HaveUserInfo(String UserId)
{
Boolean b
=false;
Cursor cursor
=db.query(SqliteHelper.TB_NAME, null, UserInfo.USERID + = + UserId, null, null, null,null);
b
=cursor.moveToFirst();
Log.e(
HaveUserInfo,b.toString());
cursor.close();
return b;
}

//更新users表的记录,根据UserId更新用户昵称和用户图标
public int UpdateUserInfo(String userName,Bitmap userIcon,String UserId)
{
ContentValues values
= new ContentValues();
values.put(UserInfo.USERNAME, userName);
// BLOB类型
final ByteArrayOutputStream os = new ByteArrayOutputStream();
// 将Bitmap压缩成PNG编码,质量为100%存储
userIcon.compress(Bitmap.CompressFormat.PNG, 100, os);
// 构造SQLite的Content对象,这里也可以使用raw
values.put(UserInfo.USERICON, os.toByteArray());
int id= db.update(SqliteHelper.TB_NAME, values, UserInfo.USERID + = + UserId, null);
Log.e(
UpdateUserInfo2,id+“”);
return id;
}

//更新users表的记录
public int UpdateUserInfo(UserInfo user)
{
ContentValues values
= new ContentValues();
values.put(UserInfo.USERID, user.getUserId());
values.put(UserInfo.TOKEN, user.getToken());
values.put(UserInfo.TOKENSECRET, user.getTokenSecret());
int id= db.update(SqliteHelper.TB_NAME, values, UserInfo.USERID + = + user.getUserId(), null);
Log.e(
UpdateUserInfo,id+“”);
return id;
}

//添加users表的记录
public Long SaveUserInfo(UserInfo user)
{
ContentValues values
= new ContentValues();
values.put(UserInfo.USERID, user.getUserId());
values.put(UserInfo.TOKEN, user.getToken());
values.put(UserInfo.TOKENSECRET, user.getTokenSecret());
Long uid
= db.insert(SqliteHelper.TB_NAME, UserInfo.ID, values);
Log.e(
SaveUserInfo,uid+“”);
return uid;
}

//删除users表的记录
public int DelUserInfo(String UserId){
int id= db.delete(SqliteHelper.TB_NAME, UserInfo.USERID +=+UserId, null);
Log.e(
DelUserInfo,id+“”);
return id;
}
}

完成上面的代码后,我们需要在载入页面中调用上面的方法实现sqlite库中是否已经保存有用户的新浪微博的UserID号、Access Token、Access Secret的记录的功能在MainActivity的onCreate方法添加代码:

代码

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

……

//获取账号列表
dbHelper=new DataHelper(this);
List
<UserInfo> userList= dbHelper.GetUserList(true);
if(userList.isEmpty())//如果为空说明第一次使用跳到AuthorizeActivity页面进行OAuth认证
{
Intent intent
= new Intent();
intent.setClass(MainActivity.
this, AuthorizeActivity.class);
startActivity(intent);
}
else//如果不为空读取这些记录的UserID号、Access Token、Access Secret值
//然后根据这3个值调用新浪的api接口获取这些记录对应的用户昵称和用户头像图标等信息。
{
for(UserInfo user:userList){
……
}
}
}

关于载入页面的sqlite就说到这里了,下一篇说说OAuth认证实现。

[转载]用jquery让.hover(over,out)代替css中的:hover来实现悬停效果

mikel阅读(1039)

[转载]用jquery让.hover(over,out)代替css中的:hover来实现悬停效果 – 天堂电影 – 博客园.

话不多说,直接上菜。

.scpItem:hover{ background-color: #F4D0D0;}

<div class=”scpItem”>悬停看这</div>

在ie6-中没有反应。

可以将.scpItem:hover{ background-color: #F4D0D0;}从css文件中删除了,

而在js文件使用JQuery框架的hover()来模仿鼠标悬停事件。如:

$(“.scpItem”).hover(

function(){$(this).css(“background-color”,”#F4D0D0″);}

,function(){$(this).css(“background-color”,”white”);}

);

这样要的效果实现了。

[转载]android开发我的新浪微博客户端-载入页面UI篇(1.1)

mikel阅读(1028)

[转载]android开发我的新浪微博客户端-载入页面UI篇(1.1) – 遇见未知的自己 – 博客园.

本软件设定用户第一个接触到的功能就是页面载入等待功能,这个功能对使用者来说就是一个持续1、2秒钟的等待页面,在用户等待的同时程序做一些必要的检 查以及数据准备工作,载入页面分为UI篇和功能篇,从表及里首先是UI的实现,一个软件除功能之外还得有一个光鲜的外表也是非常重要的,尽管本人设计水平 一般但是还是亲自操刀用ps先做了一下设计效果图如下:

一、接下来的任务就是在Android中实现这样的效果显示,从这个效果的设计分别把图片分成背景版本号部分软件名称和图标作者名称和blog四 个部分,按照这样的思路把分别生成4张png的图片,背景部分考虑实现横屏和竖屏切换额外添加一张横屏背景图,然后新建Android工程,我这里的名称 为MySinaWeibo,Android版本勾选2.2,并且创建名为MainActivity的Activity作为整个软件的起始页面,然后把上面 的这些图片保存到项目的res/drawable-mdpi文件夹下,关于res目录下的drawable-mdpi、drawable-ldpi,、 drawable-hdpi三个文件夹的区别,mdpi 里面主要放中等分辨率的图片,如HVGA (320×480)。ldpi里面主要放低分辨率的图片,如QVGA (240×320)。hdpi里面主要放高分辨率的图片,如WVGA (480×800),FWVGA (480×854)。android系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片,在开发程序时为了兼容不同平台不同屏幕,建议各自文 件夹根据需求均存放不同版本图片,我这里就不进行这么多的考虑了。

二、完成图片资源的准备后接下就是layout文件的编写, 在res/layout文件夹下新建main.xml文件,这个layout采用LinearLayout控件作为顶层控件,然后用ImageView控件分别实现版本号图片顶部靠左对齐显示、软件名称和图标图片居中对齐、作者名称和blog图片底部靠右对齐。注意在版本号图片显示ImageView控件下面添加一个RelativeLayout控件作为软件名称和图标图片ImageVIew和作者名称和blog图片ImageView的父控件用来控制居中对齐已经底部对齐的实现具体代码如下:代码

<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:id
=”@+id/layout”
android:orientation
=”vertical”
android:layout_width
=”fill_parent”
android:layout_height
=”fill_parent”>
<ImageView
android:layout_width=”wrap_content”
android:layout_height
=”wrap_content”
android:src
=”@drawable/ver”
android:layout_marginTop
=”15dip”
android:layout_marginLeft
=”15dip”>
</ImageView>
<RelativeLayout
android:layout_width=”fill_parent”
android:layout_height
=”fill_parent”>
<ImageView
android:layout_width=”wrap_content”
android:layout_height
=”wrap_content”
android:src
=”@drawable/logo”
android:layout_centerInParent
=”true”>
</ImageView>

<ImageView
android:layout_width=”wrap_content”
android:layout_height
=”wrap_content”
android:src
=”@drawable/dev”
android:layout_alignParentBottom
=”true”
android:layout_alignParentRight
=”true”
android:layout_marginRight
=”5dip”
android:layout_marginBottom
=”35dip”>
</ImageView>
</RelativeLayout>
</LinearLayout>

三、在ec打开名为MainActivity的Activity源代码文件进行编辑,onCreate部分代码如下:

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

然后运行项目可以在模拟器中显示,上面的几个图片都按照设计的位置和效果进行显示只是整个页面的背景还是黑色的,接下来就是背景部分的显示实现,由于为了实现横竖屏切换显示,背景图的显示采用代码进行控制显示,首先用如下方法获取当前手机是横屏还是竖屏:

代码

//获取屏幕方向
public static int ScreenOrient(Activity activity)
{
int orient = activity.getRequestedOrientation();
if(orient != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && orient != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
//宽>高为横屏,反正为竖屏
WindowManager windowManager = activity.getWindowManager();
Display display
= windowManager.getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
orient
= screenWidth < screenHeight ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
return orient;
}

然后编写一个名为AutoBackground的公共方法用来实现屏幕背景的自动切换,后面的几乎每一个功能页面都需要用到这个方法:

代码

public static void AutoBackground(Activity activity,View view,int Background_v, int Background_h)
{
int orient=ScreenOrient(activity);
if (orient == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { //纵向
view.setBackgroundResource(Background_v);
}
else{ //横向
view.setBackgroundResource(Background_h);
}
}

完成上述两方法后在 MainActivity的onCreate方法中调用AutoBackground方法进行屏幕自动切换:

LinearLayout layout=(LinearLayout)findViewById(R.id.layout);
//背景自动适应
AndroidHelper.AutoBackground(this, layout, R.drawable.bg_v, R.drawable.bg_h);

到此完成了载入页面的UI部分的实现,测试运行模拟器中查看效果,基本上跟最上面的设计效果图相符,测试效果图如下:

[转载]ActionScript3框架集合

mikel阅读(1227)

Cairngorm (download)

Cairngorm是一个最早最为成熟的FLEX框架,现在已归为ADOBE门下.

PureMVC (download)

它其实是一个ActionScript 3框架,不像Cairngorm,它并不是针对FLASH,FLEX或者其它ADOBE AS3.0类。它是一个用于开发基于FLASH的AS 3.0的任何程序.

Model-Glue: Flex (download)

Model-Glue是一种简单的MVC的FLEX框架,Model-Glue拥有COLDFUSION接口.它相比以上两款更为轻巧.

Foundry (download)
ServeBox Foundry ( sbasfoundry )是一个ActionScript 3 / Java框架针对Flex 2应用开发者.

Spring Actionscript

比利时的Christophe HerremanSpring ActionScript框架(以前的pranaframework)的创始人和主要开发成员之一,Spring ActionScript的当前版本是0.81。

当前版本的Spring ActionScript已经实现了IOC,反射编程框架,集成了Cairngorm和PureMVC框架。接下来会开发一个MVCS( Model-View-Controller-Service)的架构,并且加入AOP(Aspect Oriented Programming)面向切面编程。

Guasax Flex Framework (download)

Guasax是一个易用的程序框架,为保证新老FLEX应用的扩展.

ARP (download)

ARP (Ariaware RIA Platform)是一个基于ActionScript的框架,它是一个Open Source Flash 项目.

Flest Framework (download)

Flest 是一个ActionScript3 / Flex框架.

以上的框架可以从EasyMVC, Adobe FASTJoeberkovitz’s framework签出.

其它的一些还有

FlexUnit (一个用于ActionScript 3单元测试框架)

AS3CoreLib (一个 ActionScript 3.0 库包含强大的JSON 的包)

Granite DS (一个免费开源的,可以替代Adobe Data Services J2EE应用服务器 EJB3/Spring/Pojo 服务支持)

Soma v2 AS3 MVC

Soma v2的已经用于许多项目,使用它是一种极大的乐趣。我首先为自己建立这个框架,作为一种工具。如果我不认为Soma 可帮助您用最少的时间学习和 “框架冲突” ,我不会发布它,我希望…使用它们有很多乐趣!

相比第2版这一概念是类似的,许多已得到改善和增加。
首先是SomaUI演示!

~W8UT 1EWVHZ7{I)SF@V@IN

Aswing 国人iiley写的纯AS的UI框架,结构类似于 Java Swing,体积小巧。

weemvc ,国人写的,继Aswing之后的又一开源框架,值得学习,适合小项目。

  • 超级微型,简洁、简单,上手快,适合新手学习和开发小型项目;
  • 整合 PureMVC 与 Cairngorm 的优点进行设计;
  • FLASH 友好设计,对于 FLASH 的相关小型项目开发效率较高;
  • 在解耦上做了优化处理,使得 model 和 view 复用更容易。neatframework ,国人写的
  • 面向Flash项目开发,目标明确,实现灵活
  • 轻量,编译体积更小,架构清晰,简洁易用,适合快速开发
  • 核心基于MVC模式构建,模块间采用事件模型进行通讯,低耦合
  • 事件追踪,自动宏命令jdhMVC(Version 1.0.0),国人的自我总结:
    此框架并不影响以前写代码的风格, 只是将相关的类用继承框架中指定的类来达到事件播等,也许算不上MVC框架,之所以还是叫他MVC也就是因为确实把显示对象和控制对象分开来处理,至于数 据层几乎和控制层相同,可以根据自己不同的习惯来定了. (参考pureMVC框架)
    优点:简单易用, 只需要建立几个关联和重写几个方法就能实现事件广播, 重复代码量少;
    缺点:个人摸索的框架不够成熟, 测试量较少, 还需要更好地优化, 各事件发送与接收如果不做记录在数量多的情况下很找到其间的关联;

    一些FLASH游戏的框架

    1.Citrus 介绍:

    Citrus 是一个由Actionscript 3.0 语言和 Box2D物理引擎实现的卷轴类游戏 引擎。
    设计师和开发者可以利用Citrus 快速的构建卷轴(平台)类游戏。

    O%O57$GI)I46QYJ8EE8E$ 8

    http://blueflamedev.com/

    2.Yogurt3D

    http://www.yogurt3d.com/en/

    感觉flash现在对3D方面还不能很好的支持,虽然已经有很多的3D 框架的支持,但是运行效率还是不好,仅仅限于展示阶段

    还不能很好的用于一些应用里面。

    3.Teris game Engine

    Teris的介绍不多,

    http://code.google.com/p/bigroom/

    4.FFlimation

    介绍:

    The FFilmation Engine is an AS3 isometric programing engine , focused mainly on game development. The aim of the project is providing a robust development platform , where game designers can work on the game’s details and forget about the render engine. It is intended to be really usable from a “real production scenario” point of view. This means:

    B9B09OCW4Z]A5GZ5FCA{RT7

    demo http://www.ffilmation.org/website/demos/example-1/

    5.openspace

    介绍:

    OpenSpace is a powerful Flash based isometric engine and framework for rapid development of multi-user virtual worlds and MMO communities.
    The engine leverages the power of ActionScript 3 and SmartFoxServer , offering an unprecedented level of features and customizations.

    4R$O)CWN ~WE@[]JZBK7U5H

    demo: http://showcase.smartfoxserver.com/openspace2/

    和FFlimation 一样也是 isometric类 游戏,但是不是开源的。

    6. pushbutton engine

    介绍:

    The PushButton Engine is an Open Source , Flash game engine and framework that’s designed for a new generation of games. PushButton Engine makes it easy to bring together great existing libraries and components for building Flash games. Spend less time on code, more time on building fun games .


    webbus flashweb 框架 第一版(国人的)

    1.webbus FLASH框架将 SWF类库与主程序分开,完美控制类库加载. 在调用时自动加载类库SWF.或初始化时一次性加载必需类库.
    2.完美的单线程列队加载.只需抛一个事件流,剩下的事件交给框架来完成.
    3.系统配置方便,只需修改config.xml.
    4.自行扩展类库方便,可同时使用多个类库.
    5.每次只需编译相关功能应用SWF,单次编译文件最小,提高工作效率.
    6.框架采用分步加载. APP功能 类库功能分离,节省大量带宽资源,速度快.
    7.自行修改各加载LOADING,可不用LOADING.
    DEMO:http://www.webbus.com.cn/demo/flashweb/main.swf

  • [转载]分享Silverlight/WPF/Windows Phone一周学习导读(12月27日-1月2日)

    mikel阅读(1075)

    [转载]分享Silverlight/WPF/Windows Phone一周学习导读(12月27日-1月2日) – 专注Silverlight – 博客园.

    上周看了“微软 2011 年重大会议概览”,作为微软开发人员,2011年还是有不少值得期待的东西,Silverlight 5是其中之一。如果想预先了解Silverlight 5的新功能,推荐阅读微软发布Silverlight 5 Beta新特性一文。

    圣诞节和新年,一周时间基本没怎么阅读文章,随后的一周要补上。^_^

    总结上周的Silverlight,WPF和Windows Phone的学习文章。

    本周Silverlight学习资源更新:
    Silverlight中如何实现虚线边框 银光中国
    Silverlight Grid 边界线处理 duicky
    SilverLight搭建WCF聊天室详细过程(四)好友上线 fugitiver
    SilverLight搭建WCF聊天室详细过程(六)打开聊天窗口 fugitiver
    SilverLight搭建WCF聊天室详细过程(八)发送文本消息 fugitiver
    SilverLight搭建WCF聊天室详细过程(十)接收离线消息 fugitiver
    SilverLight搭建WCF聊天室详细过程(十一)发送图片 fugitiver
    SilverLight的List<T>、ObservableCollection<T>和INot 天神一
    silverlight游戏设计(四)角色/精灵篇之 — 精灵的设计 姜萌
    SilverLight搭建WCF聊天室详细过程(十三)发送文件邀请 fugitiver
    SilverLight搭建WCF聊天室详细过程(十五)接收文件 fugitiver
    Silverlight客户端实现图片的截取和压缩—-之上传头像 无名菜鸟
    Silverlight杂记-自定义loading 撞破南墙
    [SilverLight] DataGrid实现批量输入(like Excel) Silent Void
    Silverlight开发-“慢”游美丽的分形世界(画分形2) 撞破南墙
    Silverlight+WCF 实战-网络象棋最终篇之非线程阻塞倒计时窗口-应用篇(七) 路过秋天
    SilverLight搭建WCF聊天室详细过程(十六)仿QQ消息提醒 fugitiver
    Silverlight WriteableBitmap版-流体力学的演示 撞破南墙
    SilverLight搭建WCF聊天室详细过程(十七)新用户注册并刷新所有在线好友列表 fugitiver
    SilverLight搭建WCF聊天室详细过程(十八)视频 fugitiver
    silverlight 清空所有文本框 汪立
    如何在一个跨域环境中用Silverlight客户端使用自托管的WCF服务 微软Internet开发者
    winform和silverlight交互 漫游者
    Silverlight 自定义控件模板管理 (silverlight 学习笔记) Lvachel`
    将 Silverlight 程序部署到 IIS (1) 炭炭
    SilverLight使用javascrip几种方法 fugitiver
    SilverLight中使用ASP.NET session fugitiver
    让DIV悬浮在SilverLight之上 fugitiver
    给SilverLight传值之–属性传值 fugitiver
    SilverLight中DataGrid显示值转换 fugitiver
    Silverlight C# 游戏开发:L7 HeightMap nowpaper
    SilverLight搭建WCF聊天室详细过程(十九)WCF服务端变量以及对象设计思路 fugitiver
    SilverLight搭建WCF聊天室详细过程(七)打开窗口后添加到任务栏 fugitiver
    SilverLight搭建WCF聊天室详细过程(十四)发送文件 fugitiver
    SilverLight搭建WCF聊天室详细过程(三)好友列表之 Accordion滑动分组动态绑定 fugitiver
    SilverLight搭建WCF聊天室详细过程(九)接收文本消息 fugitiver
    SilverLight搭建WCF聊天室详细过程(五)好友下线 fugitiver
    Siverlight支持断点续传的多文件上传解决方案 .自.在.
    SilverLight使用WCF RIA SERVICE实现对数据库的操作(查询) fugitiver
    SilverLight使用WCF RIA SERVICE实现对数据库的操作 (添加,删除,更新) fugitiver
    SilverLight使用WCF RIA SERVICE返回自定义类 fugitiver
    Button中MouseLeftButtonDown和MouseLeftButtonUp事件无法触发的解决方案 giser2007
    SilverLight搭建WCF聊天室详细过程(二十)WCF服务端用户列表字典的应用 fugitiver
    SilverLight用DataContext显示数据 JerryT
    SilverLight搭建WCF聊天室详细过程(二十一)关于聊天室项目错误排查 fugitiver
    Silverlight实现DataGrid的Select All功能 Jason Li
    silverlight DataBind 小Demo livewall
    silverlight 4中datagrid列标题和列内容居中问题 guoyuanwei
    Silverlight 自定义表格 duicky
    在Silverlight中打开网页的几种方法 Windie Chai
    Silverlight 之轻 佚名
    Silverlight 应用程序中未处理的错误 InitializeError 解决方法 自由骑士笃志
    Silverlight 3 + WCF 的例外處理 黄伟荣
    silverlight 与 ASP.NET 会员系统 m a r c h23
    Silverlight 4使用Domain Service做资料快速存取 黄伟荣
    Silverlight利用DispatcherTimer做出"图片轮播"的功能 puma
    Silverlight资料验证(Data Validation) eternaltung
    Silverlight使用CircularPanel让ListBox的Items环状排列 eternaltung

    本周WPF学习资源更新:

    WPF动画(应用VisualBrush画刷) 2sws
    WPF动画(监视动画进度) 2sws
    WPF动画(图片渐变效果) 2sws
    【WPF】自定义GridLineDecorator给ListView画网格 RMay
    WPF动画(应用VisualBrush画刷Test) 2sws
    使用elementhost将wpf内容移植到winform窗体 vpoint2009
    WPF动画(关键帧动画) 2sws
    WPF动画(离散关键帧动画) 2sws
    ZAM 3D入门教程(1):初识ZAM 3D Alexis
    ZAM 3D入门教程(2):场景编辑器 Alexis
    ZAM 3D入门教程(3):Viewport Alexis
    ZAM 3D入门教程(4):Extrusion编辑器 Alexis
    ZAM 3D入门教程(5):Lathe编辑器 Alexis
    ZAM 3D入门教程(6):导入AI和EPS格式的文件 Alexis
    WPF的消息机制(一)- 让应用程序动起来 葡萄城控件技术团队
    ListView 的三种数据绑定方式 xiaokang088
    WPF下可编辑Header的Tab控件实现 葡萄城控件技术团队
    WPF Image绑定中碰到的事 刘剑
    WPF与混淆器 徐明璐
    Microsoft Visual Studio 2010 编辑器增加背景图片插件[源码] 王文壮
    WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口 葡萄城控件技术团队
    WPF快速指导1:资源 luminji
    在WPF中內嵌WindowsForm控制項 Ouch
    Binding in WPF and Silverlight – (一)使用C# Ouch
    Binding in WPF and Silverlight – (二)使用Visual Studio和Blend Ouch
    WPF动画冰雪效果(可视化对象) 2sws
    WinForm应用程序中嵌入WPF控件 Retrying
    WPF检查滑鼠有没有点到物件 help

    本周Windows Phone 7学习资源更新:

    WP7 App性能优化(11):检测应用程序性能(Ⅳ) MagicBoy110
    Windows Phone– Passing arguments between pages and Input Sc 永恒的记忆
    Silverlight for Windows Phone 7–Popup 永恒的记忆
    Operation not permitted on IsolatedStorageFileStream. 永恒的记忆
    Windows Mobile设备常见任务开发(2)-个人信息管理 MagicBoy110
    Windows Phone 7 XNA触控操作之Gestures 永恒的记忆
    Windows Phone 7 For Silverlight 生命周期 永恒的记忆
    分享你的Windows Phone 7应用程序 永恒的记忆
    Windows Phone Marketplace注意事项 永恒的记忆
    在你的Windows Phone 7 应用程序中植入广告(广告控件的使用) 永恒的记忆
    Windows Phone 7 图表控件的使用 永恒的记忆
    Windows Mobile设备常见开发任务(3)–语音呼叫与短消息 MagicBoy110
    Windows Phone 7独立存储空间IsolatedStorage 永恒的记忆
    Windows Phone 7中使用PhoneApplicationService类保存应用程序状态 永恒的记忆
    Windows Mobile设备常见任务开发(4)–状态与通知 MagicBoy110
    windows mobile网络设备-DMProcessConfigXML snow wolf
    Windows Phone 7 不温不火学习之《独立存储空间》 Terry_龙
    Windows Phone 7项目实战之记事本(一) 永恒的记忆
    Windows Phone 7的多种使用技巧 gwalker
    WP7 App性能优化(13):检测应用程序性能(Ⅵ) MagicBoy110
    Windows Phone 7调用必应翻译服务 永恒的记忆
    WP7 XNA 使用Guide输入文字、显示讯息与试用版测试 help
    WP7 XNA ContentPipelen help
    WP7 XNA触控与手势 help
    Windows Phone 7 程式碼效能分析器 kylin
    本周开源实例代码和作品展示:
    本周推荐学习书籍:

    Pro WPF and Silverlight MVVM,详细介绍MVVM设计模型在WPF和Silverlight中的应用。

    该书是WPF和Silverlight专业设计书籍。

    书籍下载

    欢迎大家加入“专注Silverlight”QQ技术群,目前,1-8群都已经满员,新开200人九群,欢迎大家加入一起学习讨论Silverlight&WPF&Widnows Phone开发技术。
    22308706(一群) 超级群500人
    37891947(二群) 超级群500人
    100844510(三群) 高级群200人
    32679922(四群) 超级群500人
    23413513(五群) 高级群200人
    32679955(六群) 超级群500人

    61267622(七群) 超级群500人

    88585140(八群) 超级群500人

    128043302(九群 企业应用开发推荐群) 高级群200人