在前一篇文章中,大家和我一起已经为组件添加了其必要属性,那么,在有了属性之后,我们就接着为组件添加事件响应的功能吧,毕竟每个组件都应该有个简单的事件,要不组件就成属性容器了,在此篇文章中,大家将和我一起学习如何为组件添加事件,以及处理事件的响应方法等。
在前一篇文章中,大家和我一起已经为组件添加了其必要属性,那么,在有了属性之后,我们就接着为组件添加事件响应的功能吧,毕竟每个组件都应该有个简单的事件,要不组件就成属性容器了,呵呵。
好的,还是接上文『参考』.net CF组件编程(1)——基础之后,我们在TcpHelper.cs组件类中,添加一个基本的Tcp连接代码如下:
基础TCP方法
/// <summary>
/// 链接远程主机,用于测试网络的连通性
/// </summary>
private void Connect()
{
try
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(this.HostName), this.Port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(iep);
ConnectHandler("连接成功!");//使用定义好的私有方法,向事件的订阅者发送“连接成功”消息
}
catch (Exception e)
{
DisconnectHandler(e.Message);//使用定义好的私有方法,向事件的订阅者发送异常消息
}
finally
{
DisconnectHandler("断开连接!");//使用定义好的私有方法,向事件的订阅者发送“断开连接”消息
client.Close();
}
}
相信使用过Tcp编程的朋友们是非常熟悉这段代码的,当然,可能会对ConnectHandler以及DisconnectHandler函数陌生,他俩是我们即将定义的一个消息处理函数,用于向事件的订阅者传递事件信息的(这里的信息有点像Catch捕获异常时,那个Exception e中的e.Message),下面我们来真的为组件添加事件吧:
组件事件
/// <summary>
/// 线程委托,用于返回连接状态等信息
/// </summary>
/// <param name="msg">传出的参数,在实际调用中类似于事件的Args参数</param>
public delegate void ConnectStatuDelegate(string msg);
/// <summary>
/// 返回连接状态事件,ConnectedStatu就是在属性设计器中能看到的事件了
/// </summary>
public event ConnectStatuDelegate ConnectedStatu;
定义好事件后,可以参照前一篇文章中,提及的为组件添加属性描述的方法,为事件同样添加好描述。如图:
方法类似于属性,大家应该自己去看吧,因为实在简单,在此就不赘述了。好了,下面,组件有事件了,接下来,我们要告诉这个事件,应该如何响应,接下来,为事件添加响应代码:
事件响应代码
/// <summary>
/// 消息事件的委托方法,如果用户订阅了事件,那么其实是由此委托进行消息参数的传递的
/// </summary>
/// <param name="msg"></param>
private void MessageHandler(string msg)
{
ConnectStatuDelegate messageEvent = ConnectedStatu;
if (messageEvent != null)
{
messageEvent(msg);
}
}
/// <summary>
/// 私有方法,向事件发送消息
/// </summary>
/// <param name="msg">欲发送的消息</param>
private void ConnectHandler(string msg)
{
MessageHandler(msg);
}
/// <summary>
/// 私有方法,向事件发送消息
/// </summary>
/// <param name="msg">欲发送的消息</param>
private void DisconnectHandler(string msg)
{
MessageHandler(msg);
}
这里,我们看到了ConnectHandler以及DisconnectHandler函数,是不是明了很多呢?其实就是调用同一个委托方法,供TCP基础函数来针对不同的状态返回给事件订阅者不同的消息。而MessageHandler方法是一个经典的事件处理的描述。
到此为止,我们的组件已经拥有了方法、属性,而我们的组件代码也就到此结束,在下一篇的文章,我们将学会如何使用此组件,以及如何处理组件的默认属性。
TcpHelper组件的全部代码如下:
TcpHelper全部代码
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Net;
using System.Net.Sockets;
namespace TCPComponent
{
public class TCPHelper : Component
{
private Boolean isclient;
private Socket client;
private String host;
private Int32 port;
#region 主机地址
/// <summary>
/// 远程主机地址
/// </summary>
public string HostName
{
get
{
return host;
}
set
{
if (value == null || value.Trim().Length == 0)
{
throw new ArgumentException("Invalid Host name.");
}
host = value;
}
}
#endregion
#region 端口号
/// <summary>
/// 通讯使用的端口号
/// </summary>
public int Port
{
get
{
return port;
}
set
{
if (value == 0 || value > 65535)
{
throw new ArgumentException("Invalid port Number.");
}
port = value;
}
}
#endregion
#region 是否为客户端
/// <summary>
/// 指示是否为客户端
/// </summary>
public bool IsClient
{
get
{
return isclient;
}
set
{
isclient = value;
}
}
#endregion
#region 方法体
/// <summary>
/// 链接远程主机,用于测试网络的连通性
/// </summary>
private void Connect()
{
try
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(this.HostName), this.Port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(iep);
ConnectHandler("连接成功!");//使用定义好的私有方法,向事件的订阅者发送“连接成功”消息
}
catch (Exception e)
{
DisconnectHandler(e.Message);//使用定义好的私有方法,向事件的订阅者发送异常消息
}
finally
{
DisconnectHandler("断开连接!");//使用定义好的私有方法,向事件的订阅者发送“断开连接”消息
client.Close();
}
}
#endregion
#region
/// <summary>
/// 线程委托,用于返回连接状态等信息
/// </summary>
/// <param name="msg">传出的参数,在实际调用中类似于事件的Args参数</param>
public delegate void ConnectStatuDelegate(string msg);
/// <summary>
/// 返回连接状态事件,ConnectedStatu就是在属性设计器中能看到的事件了
/// </summary>
public event ConnectStatuDelegate ConnectedStatu;
/// <summary>
/// 消息事件的委托方法,如果用户订阅了事件,那么其实是由此委托进行消息参数的传递的
/// </summary>
/// <param name="msg"></param>
private void MessageHandler(string msg)
{
ConnectStatuDelegate messageEvent = ConnectedStatu;
if (messageEvent != null)
{
messageEvent(msg);
}
}
/// <summary>
/// 私有方法,向事件发送消息
/// </summary>
/// <param name="msg">欲发送的消息</param>
private void ConnectHandler(string msg)
{
MessageHandler(msg);
}
/// <summary>
/// 私有方法,向事件发送消息
/// </summary>
/// <param name="msg">欲发送的消息</param>
private void DisconnectHandler(string msg)
{
MessageHandler(msg);
}
#endregion
/// <summary>
/// 多线程版本的连接远程主机,实际中,我们是调用此方法,所以其修饰为Public
/// </summary>
public void ConnectAsync()
{
new Thread(new ThreadStart(Connect)).Start();
}
}
}
参考文档:
http://www.cnblogs.com/mapserver/category/65343.html 感谢Mapserver朋友
http://www.cnblogs.com/OSCAR_NJU/archive/2008/04/02/1134231.html 感谢死刑犯朋友(汗)