一:分析问题产生的原因?
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 控件()的方式在各个页面切换时,于是容易产生这种问题。
二:解决消息重复问题
从第一步中,我们分析到问题产生的根源,于是,我们可以想出很多方式,来解决这种问题,这里我介绍两种方式:
先来看一下错误任法:注册事件前加先减,再加,示例代码如下:
@H_150_301@ 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,状态重置的问题,就留到下节解决了。
本节没关联啥好看图片,就随便挂一张在下面让大伙欣赏了:
最后:谢谢大家对本系列的喜欢,谢谢支持~
同时欢迎大家多到 秋色园 走走~~~
PS:传说点一下推荐会有10个园豆的规则已经取消了,不过,喜欢的还是可以点一下“推荐”,thank you very much!!
总结以上是内存溢出为你收集整理的Silverlight+WCF 实战-网络象棋最终篇之解决重复的消息提示(八)全部内容,希望文章能够帮你解决Silverlight+WCF 实战-网络象棋最终篇之解决重复的消息提示(八)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)