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

在线演示地址: 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运行,看看正常不正常:

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

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

 

深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
【6层】4837.9平米六层框架综合办公楼(含计算书、建筑、结构图纸) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博私信或留言,博看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博删除。 6、可私信博看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博私信或留言,博看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博删除。 6、可私信博看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博私信或留言,博看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博删除。 6、可私信博看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值