Silverlight+WCF 新手实例 象棋 主界面-在线用户区(二十四)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示

演示已更新到此节介绍:Silverlight+WCF 新手实例 象棋 介绍III(二十三)

 

这节我们来实现在线用户区的显示,把上两节介绍那张图再弄来,看在线用户区是哪块:

 

一眼扫过看到了,是第四区,现在开始了,还是上次下棋区域一样的逻辑,往Index.xaml里拉一个Board控件,然后后台写两行代码代码一下。

当然了,得新建一个用户控件:就叫:OnlineUser.xaml,好,空白的在线用户建完了,下面还是两步实现加载:

1:界面拖一个Board到Index.xaml,现在界面上就有两行Board了:

第二个onlineUserBoard就是新添加进去的了。宽和高设置为230*260了。


<Grid x:Name="LayoutRoot" Background="White">
        <Border BorderBrush="Silver" BorderThickness="1" Height="544" HorizontalAlignment="Left" Margin="10,10,0,0" Name="chessBoard" VerticalAlignment="Top" Width="522"></Border>
        <Border BorderBrush="Silver" BorderThickness="1" Height="260" HorizontalAlignment="Left" Margin="756,10,0,0" Name="onlineUserBoard" VerticalAlignment="Top" Width="230"></Border>
    </Grid>

 

2:后台动态加载控件了,后台代码就两行,看今天新加的那。


public Index()
        {
            InitializeComponent();
            Chess chessControl=new Chess();//实例化控件
            chessBoard.Child = chessControl;//加载控件
            OnlineUser onlineUserControl = new OnlineUser();//今天新加的在线用户
            onlineUserBoard.Child = onlineUserControl;
        }

 

OK,控件就相当于加载完了。接下来的任务就是要实现OnlineUser控件里的内容显示了:

 

接下来我们回到OnlineUser.xaml里,改一下总体宽和高为230*260:

<UserControl ..省略一堆.. d:DesignHeight="260" d:DesignWidth="230">
    
    <Grid x:Name="LayoutRoot" Background="White">

    </Grid>
</UserControl>

 

然后呢,往里放四个TextBlock和一个ListBox


<Grid x:Name="LayoutRoot" Background="White">
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="9,10,0,0" Name="textBlock1" Text="我的昵称:" VerticalAlignment="Top" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="71,10,0,0" Name="txtNickName" Text="txtNickName" VerticalAlignment="Top" Width="164" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="9,39,0,0" Name="textBlock3" Text="在线人数:" VerticalAlignment="Top" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="71,39,0,0" Name="txtOnlineCount" Text="1" VerticalAlignment="Top" Width="71" />
        <ListBox Height="190" HorizontalAlignment="Left" Margin="8,61,0,0" Name="lbUserList" VerticalAlignment="Top" Width="215" />
    </Grid>

 

看这个不太直观,还是来张图:



现在看到布局情况了吧,界面布局就差不多了,接下来我们要获取服务端的用户列表,同时接收服务端的更新通知。

 

于是,转入WCF服务端了,加两个东东,一个获取用户列表,一个回调通知用户更新。[和房间列表几乎一个样]

打开IService.cs,加入接口,我们只要房间内的用户列表就行了:

[OperationContract]
Dictionary<Guid, Player> GetPlayerList(int roomID);//获取用户列表

 

然后增加回调接口,有新用户进入时,要通知我们的:

打开ICallBack.cs接口,由于只有两行,就顺便复制出来了[回调不熟悉的,回去再看通讯基础[十四--十七]那几节]:

通知用户那,由于用户有进入和退出,所以增加参数传递。


interface ICallBack
    {
        [OperationContract(IsOneWay = true)]
        void NotifyRoomUpdate(Room room);
        [OperationContract(IsOneWay = true)]
        void NotifyUserUpdate(Player player, bool isEnter);//通知用户
    }

 

说了N次了,回调的是方法是给客户端实现的,所以我们在服务端不实现。

 

但我们那个GetPlayerList还是得实现的,我们回到Service.svc.cs,实现接口

看,代码相当的简洁简单吧,没办法,我们的存档结构Dictionary存的好。


 #region IService 成员

        //获取房间用户列表
        public Dictionary<Guid, Player> GetPlayerList(int roomID)
        {
            if (playerList.ContainsKey(roomID))
            {
                return playerList[roomID];
            }
            return null;
        }

        #endregion

 

用户列表获取完事了,但是用户通知更新还没完事呢,这里一并处理了:

 

在用户进入房间和退出房间的时候,我们要调用一下那个回调通知房间内用户更新:

我们回到Notify类,上节有了一个通知房间更新的方法,这里我们添加一个用户更新的方法:

还是一样的很简洁,用户不是自己,就通知更新。


 internal static void User(Dictionary<int, Dictionary<Guid, Player>> playerList, Player player,bool isEnter)
        {
            //这里是今天新加的,通知房间内用户更新用户
            foreach (KeyValuePair<Guid, Player> item in playerList[0])
            {
                if (item.Value.ID != player.ID)
                {
                    item.Value.CallBack.NotifyUserUpdate(player,isEnter);
                }
            }
        }

 

现在回到进入房间和退出房间的方法里,调用下这个方法吧:

方法太长,就不全复制,这里复制两行好了:


public bool EnterRoom(Player player, int roomID)
        {
          //...省略一堆...

            //这里是以前用的,通知0房间的人[未进入房间的人]都更新此房间状态
            Notify.Room(playerList, room);
            //这里是今天新增加的,通知用户更新
            Notify.User(playerList, player, true);
          return true;
        }

 

同样的,退出房间方法里也有,也复制两行代码好了:


public void OutRoom(Player player, int roomID)
        {
            if (roomID > 0)
            {
               //...省略一堆...

              //这里是以前加的,通知0房间的人[未进入房间的人]都更新此房间状态
                Notify.Room(playerList, room);
             //这里是今天新增加的,通知用户退出房间更新
                Notify.User(playerList, player, false);

            }
        }

 

至此,WCF服务端代码就完成了,剩下的就是客户端获取显示了。

 

再次提醒,编绎WCF服务端项目,客户端更新引用引用

 

好了,我们回到OnlineUser.xaml.cs后台代码里,要开始获取数据了:


public partial class OnlineUser : UserControl
    {
        public OnlineUser()
        {
            InitializeComponent();
            App.client.GetPlayerListCompleted += new EventHandler<GameService.GetPlayerListCompletedEventArgs>(client_GetPlayerListCompleted);
            App.client.GetPlayerListAsync(App.player.RoomID);
        }

        void client_GetPlayerListCompleted(object sender, GameService.GetPlayerListCompletedEventArgs e)
        {
            //这里是获取用户列表显示区
        }
    }

 

构造函数里我们调用了一下:GetPlayerListAsync,由于WCF都是异步的,所以都有一个事件来处理获取之后的执行方法:

在“e”的参数里,总是有我们要的数据:

接下来看看实现代码:

 


void client_GetPlayerListCompleted(object sender, GameService.GetPlayerListCompletedEventArgs e)
        {
            //这里是获取用户列表显示区
            txtNickName.Text = App.player.NickName;
            if (e.Result != null)
            {
                txtOnlineCount.Text = e.Result.Count.ToString();
                lbUserList.Items.Clear();
                foreach (KeyValuePair<Guid, GameService.Player> item in e.Result)
                {
                    lbUserList.Items.Add(item.Value.NickName + "[" + item.Value.ID.ToString().Substring(1, 4) + "]");
                }
            }
        }

 

1。先把自己的昵称打进去,

2。判断如果获取到数据,

3。显示下在线用户数,

4。然后清除下用户列表,

5。循环添加了,由于昵称可以重复,所以加个ID的前四位在后面用于区别一下。

在线用户列表就显示完了,接下来实现新用户进入和退出的更新:

构造函数里添加一行通知事件代码:


public OnlineUser()
        {
            //...这里省略刚才几行...
            App.client.NotifyUserUpdateReceived += new EventHandler<GameService.NotifyUserUpdateReceivedEventArgs>(client_NotifyUserUpdateReceived);
        }

        void client_NotifyUserUpdateReceived(object sender, GameService.NotifyUserUpdateReceivedEventArgs e)
        {
            //这里是实现用户通知更新
        }

 

接下来同样实现用户通知更新:

代码也很简洁了,如果是进入就添加,退出就删除,然后更新下在线用户数:


   void client_NotifyUserUpdateReceived(object sender, GameService.NotifyUserUpdateReceivedEventArgs e)
        {
            //这里是实现用户通知更新
            if (e.isEnter)//进入
            {
                lbUserList.Items.Add(e.player.NickName + "[" + e.player.ID.ToString().Substring(1, 4) + "]");
            }
            else
            {
                lbUserList.Items.Remove(e.player.NickName + "[" + e.player.ID.ToString().Substring(1, 4) + "]");

            }
            txtOnlineCount.Text = lbUserList.Items.Count.ToString();
        }

 

至此,我们就折腾完了,只是没有文字提示用户进入和退出,这个纠结了点。。。

就纠结了先吧,等下节我们实现在线聊天的时候,我们把文字往那边显示去。

OK,一切就绪,还是F5运行:



用了三个浏览器看了下效果,太阳,只有列表出来,没有被用户通知更新,查一下代码先

查出来了,原来在Notify类里的用户通知的房间号写错了,默认从房间通知那里Copy来的,房间号写了0。

修正一下代码:


//把playerList[0]改成playerList[player.RoomID]
 internal static void User(Dictionary<int, Dictionary<Guid, Player>> playerList, Player player,bool isEnter)
        {
            //这里是新加的,通知0房间的人[未进入房间的人]都更新此房间状态
            foreach (KeyValuePair<Guid, Player> item in playerList[player.RoomID])
            {
                if (item.Value.ID != player.ID)
                {
                    item.Value.CallBack.NotifyUserUpdate(player,isEnter);
                }
            }
        }

 

 

OK,再次就绪,F5运行。



还是三个浏览器,这次正常了,OK,这节就到此结束了,下节再实现在线聊天,顺便把纠结的文字提示放那边去显示。

版权声明:本文原创发表于博客园,作者为路过秋天,原文链接:

http://www.cnblogs.com/cyq1162/archive/2010/07/24/1784222.html

时间: 2024-12-06 12:20:44

Silverlight+WCF 新手实例 象棋 主界面-在线用户区(二十四)的相关文章

Silverlight+WCF 新手实例 象棋 主界面-状态重置(三十四)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   正如我们在:Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)里面提到的一样: "游戏结束了,要干点什么呢?当然就是棋盘复位了,按钮重置了,如果还有棋谱之类的,全都得重置.这些,我们留下到另一节优化处理吧."   所以,本节就做这些手尾工作了. 由于游戏结束,我们复位的工作很多,至少有N个控件需要复位,因此,Silverlight+WCF 新手实例 象棋 主界面-控件消息传递(二

Silverlight+WCF 新手实例 象棋 主界面-棋盘区(二十二)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   这节我们要布局Index.xaml界面. 首先,我们定义一下全局的宽和高:1000*620[数字差不多就行了] 一堆代码,都是自动生成的,只是改了两个数字,不说大伙也知道改啥数字了. <UserControl x:Class="NewChessProject.Index"     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presen

Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   本节完后,同时会更新Silverlight+WCF 新手实例 象棋 专题索引,并顺路提供第八阶段源码   在Silverlight+WCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)节中,我们完成了下棋双方的棋谱传递 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)节中,我们完成了观棋者获取棋谱列表 在本节中,我们要进行最一步了,棋谱回放: 首先,当用户进入列表后,获取完棋谱信息之

Silverlight+WCF 新手实例 象棋 主界面-事件区-游戏开始(二十七)

本专题出产简单原由: 一开始的初衷,只是想写个简单的单机BS人机对战版的,开始还下了点AI算法看看的: 但是写到最后,都写成了通讯版本的对战了,只因中间不小心看到了WCF的相关内容,顺便加了进来; 最后就定局了,反正新手实例,能加多点内容就加多点了. 关于原始初衷,后期再补上了.       好了,先上几个附加索引: 1:Silverlight+WCF 新手实例 象棋 在线演示 2:Silverlight+WCF 简单部署问题集 3:Silverlight4 ListBox bug 4:Silv

Silverlight+WCF 新手实例 象棋 主界面-实时聊天区(二十五)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 演示已更新到此节介绍:Silverlight+WCF 新手实例 象棋 介绍III(二十三)   本节连着Silverlight+WCF 新手实例 象棋 主界面-在线用户区(二十四) 发,主界面就不截图了,这节我们实现"实时聊天区": 这节内容几乎和上节一个样的逻辑 1:新建一个用户控件:就叫:Chat.xaml,用来在线聊天 2: 界面拖一个Border到Index.xaml,现在界面上有三个Border了,第三个

Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十)

查看本系列其他相关文章请点击:Silverlight+WCF 新手实例象棋专题索引 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们曾留下了两个问题: 下棋者在下棋过程,要不要开放"回放"功能,如果开放,需要注意什么? 观众在回放过程中,突然又传来一个棋步,需要注意什么? 在解答这两个问题之前,我们先来解答上一篇的截图中发现的问题: 不知

一起谈.NET技术,Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放-结局(四十)

查看本系列其他相关文章请点击:Silverlight+WCF 新手实例象棋专题索引 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们曾留下了两个问题: 下棋者在下棋过程,要不要开放"回放"功能,如果开放,需要注意什么? 观众在回放过程中,突然又传来一个棋步,需要注意什么? 在解答这两个问题之前,我们先来解答上一篇的截图中发现的问题: 不知

赶紧接着上一节:Silverlight+WCF 新手实例 象棋 主界面-实时聊天区(二十五) 这节我们实现上节没实现的纠结的进出房间的消息提示 我们清楚的知道,我们每个区都是一个用户控件,我们的在线用户进出时,得到聊天区域显示信息,这就涉及到用户控件之间的消息传递了。 在线用户区说:反正我是

赶紧接着上一节:Silverlight+WCF 新手实例 象棋 主界面-实时聊天区(二十五)  这节我们实现上节没实现的纠结的进出房间的消息提示 我们清楚的知道,我们每个区都是一个用户控件,我们的在线用户进出时,得到聊天区域显示信息,这就涉及到用户控件之间的消息传递了. 在线用户区说:反正我是没权直接去实时聊天区写东西,没办法,找中介委托设置一下了. 那谁是中介呢?委托谁呢?当然是衣食父母Index.xaml了,是它撑着整个家庭的. 好了,知道中介了,那我就签个委托书了: 回到OnlineUse

Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)

在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示   在Silverlight+WCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)中,我们完成下棋双方的棋谱显示,这节,我们为观众增加棋子列表: 观众进入房间后,第一时间当然也要获取棋步列表了,不然进来干麻呢?你当这是聊天室啊,光聊天不看棋.   首先,当然是要在服务端添加一个获取棋步列表的接口方法了: WCF服务端,IService.cs:  /// <summary>     /// 服务端方法接口 by 路过秋天