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

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

本节连着Silverlight+WCF 新手实例 象棋 主界面-在线用户区(二十四) 发,主界面就不截图了,这节我们实现“实时聊天区”:

这节内容几乎和上节一个样的逻辑

1:新建一个用户控件:就叫:Chat.xaml,用来在线聊天

2: 界面拖一个Border到Index.xaml,现在界面上有三个Border了,第三个chatBoard就是新添加进去的了。宽和高设置为230*280了。

<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>
        <Border BorderBrush="Silver" BorderThickness="1" Height="280" HorizontalAlignment="Left" Margin="756,276,0,0" Name="chatBoard" VerticalAlignment="Top" Width="230" />
    </Grid>

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

public Index()
        {
            InitializeComponent();
            Chess chessControl=new Chess();//实例化控件
            chessBoard.Child = chessControl;//加载控件
            OnlineUser onlineUserControl = new OnlineUser();//今天新加的在线用户
            onlineUserBoard.Child = onlineUserControl;
            Chat chatControl = new Chat();//也是今天新加的---看这里看这里两行
            chatBoard.Child = chatControl;
        }

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

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

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

</Grid>
</UserControl>

然后呢,往里放四个TextBlock和一个ListBox..-_-...不是啦,都照着上节复制了。。。

然后呢,往里放一个TextBox;一个Button和一个ListBox,这个对了。。

看清楚按钮哦,下面Button默认多了一个Click事件,不小心双击了下,反正早晚要双击的。

 <Grid x:Name="LayoutRoot" Background="White">
        <ListBox Height="226" HorizontalAlignment="Left" Name="lbMsg" VerticalAlignment="Top" Width="215" Margin="7,8,0,0" />
        <TextBox Height="29" HorizontalAlignment="Left"  Margin="7,238,0,0" Name="txtMsg" VerticalAlignment="Top" Width="143"  />
        <Button Content="提交" HorizontalAlignment="Left" Margin="159,240,0,13" Name="btnChat" Width="63" Click="btnChat_Click" />
    </Grid>

好吧,还是和上次一样截张图吧:

接着我们同样的,回WCF服务端写事件了[你点击提交,内容得提交到服务端吧,人家也提交,你这边得接收更新吧]。

打开IService.cs,加入接口:

[OperationContract(IsOneWay = true)]
void Chat(Player player);

看,我们把Player传递过去了,可是我们的聊天消息往哪放呢?Player可是没有属性来存这个消息的哦?没有?那就加呗。

打开Player.cs,加一个附加信息属性[以后这属性大有用处]:

 /// <summary>
    /// 游戏玩家 by 路过秋天
    /// </summary>
    [DataContract]
    public class Player
    {
        //...省略几百个属性...

/// <summary>
        /// 附加信息,杂七杂八的都可以
        /// </summary>
        [DataMember]
        public string AttachInfo
        {
            get;
            set;
        }
    }

好了,现在有了,接着增加一个回调,通知大伙接收我发的消息:

打开ICallBack.cs接口,增加:

 interface ICallBack
    {
       //..省略掉之前两个..两个也省,就是这么省
        [OperationContract(IsOneWay = true)]
        void NotifyChatUpdate(Player player);//通知聊天信息更新
    }

接着实现接口的Chat方法,其实服务端接到消息,直接就转发了,所以代码,一行:

public class Service : IService
    {
       
        //...省略几百行代码...

public void Chat(Player player)
        {
            Notify.Chat(playerList, player);
        }

}

一来消息就把消息通知给大伙,可是那个Notify.Chat方法我们还没实现呢。

切回到Notify类,我们来实现,相当的简单,遍历下房间用户,除了自己,每个人发一份:

代码

 /// <summary>
    /// 通知 by 路过秋天
    /// </summary>
    public class Notify
    {
        //...省略掉之前的两个通知方法...
        internal static void Chat(Dictionary<int, Dictionary<Guid, Player>> playerList, Player player)
        {
            foreach (KeyValuePair<Guid, Player> item in playerList[player.RoomID])
            {
                if (item.Value.ID != player.ID)
                {
                    item.Value.CallBack.NotifyChatUpdate(player);
                }
            }
            
        }
    }

好了,服务写完了,回客户端调用了:

记得编绎,更新服务引用。

OK,现在回到Chat.xmal.cs代码里,我们要动手了:

手痒,先写一个AddMsg(string msg)方法,用于添加消息

public void AddMsg(string msg)
        {
            if (lbMsg.Items.Count > 50)
            {
                for (int i = 0; i < 40; i++)
                {
                    lbMsg.Items.RemoveAt(0);
                }
            }
            lbMsg.Items.Add(string.Format("[{0}]{1}",DateTime.Now.ToLongTimeString(),msg));
            lbMsg.SelectedIndex = lbMsg.Items.Count - 1;
            lbMsg.UpdateLayout();
            lbMsg.ScrollIntoView(lbMsg.SelectedItem);
        }

说明:

1。如果消息内容大于50条,我们就清除前面40条

2。往ListBox里添加消息

3。设置索引定位到最后一条

4。更新下布局,为什么会有这个,详见:Silverlight4 ListBox bug

5。滚动到最后一条去。

OK,接着我们双击按钮,去Click事件里写代码:

两行代码,就三行[刚加了一行判断..-_-.]!

private void btnChat_Click(object sender, RoutedEventArgs e)
        {if (txtMsg.Text.Length > 0)
            {
            App.player.AttachInfo = txtMsg.Text;//设置消息
              App.client.ChatAsync(App.player);//传递消息
            }
        }

可是WCF是异步的,咋不见那个发送后的回调函数呢?这里,我把它放构造函数里去了,总不能每点击就来一次事件,会造成不良影响的。

看,来了,在回调里,我们添加一条消息,然后清空文本:

public Chat()
        {
            InitializeComponent();
            App.client.ChatCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_ChatCompleted);
        }

void client_ChatCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            AddMsg("我 说:" + txtMsg.Text);
            txtMsg.Text = "";
        }

发送写完了,那接收呢?也是相当的相当的简单,就一行:

public Chat()
        {
            
            //...省略掉刚才两行...

App.client.NotifyChatUpdateReceived += new EventHandler<GameService.NotifyChatUpdateReceivedEventArgs>(client_NotifyChatUpdateReceived);
        
        }
        void client_NotifyChatUpdateReceived(object sender, GameService.NotifyChatUpdateReceivedEventArgs e)
        {
            AddMsg(e.player.NickName + " 说:" + e.player.AttachInfo);
        }

一收到消息就直接AddMsg进去了,OK,到此小节就结束了。

不过有时候我们喜欢用回车就发送消息,不想点按钮,那就为TextBox添加一个KeyDown事件吧

上一张图,免的大伙不知在哪加:

好,双击进去后事件代码,直接调用按钮事件:

 private void txtMsg_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                if (txtMsg.Text.Length > 0)
                {
                    btnChat_Click(null, null);
                }
            }
        }

OK,至此,本节就真的结束了,现在F5运行,看看正常不正常:

如上图,一切正常,打完收工!

啊?上节那个纠结的进出房间的文本提示还没弄呢。。。-_-..下节写好了!

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

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

    在线演示地址: Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界面-棋谱-回放(三十九)中,我们实现了用户的棋谱回放,在文章的下面,我们 ...

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

    2019独角兽企业重金招聘Python工程师标准>>> 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 在Silverlight+WCF 新手实例 象棋 主界 ...

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

    在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 本节完后,同时会更新Silverlight+WCF 新手实例 象棋 专题索引,并顺路提供第八阶段源码 在Silverlight+ ...

  4. Silverlight+WCF 新手实例 象棋 主界面-事件区-求和认输(三十二)

    在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 事隔几篇,我们又回到事件区,继续其它两个按钮事件,来张图吧: 在Silverlight+WCF 新手实例 象棋 主界面-事件区- ...

  5. Silverlight+WCF 新手实例 象棋 主界面-事件区-返回退出(三十三)

    在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 还是那张图: 本节实现返回大厅和退出系统: 一:返回大厅,其实很简单的说,就是转向房间列表了. 可是,转向前也有很多事情要处理的 ...

  6. Silverlight+WCF 新手实例 象棋 该谁下棋-B下A停(三十)

    2019独角兽企业重金招聘Python工程师标准>>> 在线演示地址:Silverlight+WCF 新手实例 象棋 在线演示 上上一节,就是二十八节:Silverlight+WCF ...

  7. Silverlight+WCF 新手实例 象棋 棋子移动-规则[附加上半盘限制](十)

    上上一节,我们对棋子的下半盘棋子做了所有的规则限制,因为我们下棋的总是用下半盘的棋子来下,总没人用上半盘棋来下那么高境界的吧. 不过这节简单追加点代码,让那些企图高境界的人士可以临时性的自己和自己下. ...

  8. Silverlight+WCF 新手实例 象棋 棋盘(二)

    2019独角兽企业重金招聘Python工程师标准>>> 1.先新建一个和棋子相关的类库 打开VS2010后->新建->项目->Silverlight类库,名称就定为 ...

  9. Silverlight+WCF 新手实例 象棋 棋子(三)

    2019独角兽企业重金招聘Python工程师标准>>> 棋盘上有棋子,棋子应该还有一些属性,按原始冲动新建一个棋子类. 上google翻译下棋子E文叫什么,查到了叫Chessman, ...

最新文章

  1. 数据中心建设“优劣”在于这几个关键问题
  2. PostgreSQL命令行方式登陆数据库
  3. python用def编写calsum函数_Python函数
  4. Redis Sentinel机制与用法
  5. 关于会计科目表,科目组,字段状态组
  6. postgresql集群方案hot standby 安装和测试
  7. sql使用逻辑控制语句
  8. jstack Dump日志文件中的线程状态
  9. Scala初体验之:Map
  10. 云服务器里可以放多少网站,一台云服务器上可以放多少个网站
  11. Linux 命令 - touch
  12. FPGA实现“打字机”(VGA UART)
  13. 尚学堂·百战程序员--java300集视频笔记
  14. 数据库表同义词mysql修改_SQLServer中同义词Synonym的用法
  15. html css 扑克牌桌面,CSS Card:纯css制作扑克牌
  16. SEO内部优化与SEO外部优化
  17. 帝国采集发布-帝国免规则采集发布
  18. 一言不和就自己写了个编程语言
  19. @PageableDefault
  20. 信息化故事--温州的传奇(11)从“进城务工”看“温州新版自闭症”

热门文章

  1. 尹伊:Datawhale做的一件事
  2. 代码规范指南:怎样写才能干净整洁
  3. 这个Python库可以偷懒,和import说再见!
  4. 剑指offer_第18题_二叉树的镜像_Python
  5. 神经网络为何越大越好?这篇NeurIPS论文证明:鲁棒性是泛化的基础
  6. 模仿并超越人类围棋手,KL正则化搜索让AI下棋更像人类,MetaCMU出品
  7. 说话夹杂English的人:我不是要装X,只是Brain功能太强
  8. NeurIPS 2020放榜,接收率史上最低!AC:低接收率带不来有趣的论文
  9. 12.6%!IJCAI 2020接收率断崖式下跌,但还是有华人大佬中了三篇
  10. Git教程:最详细、最傻瓜、最浅显、真正手把手教!