using System;
using System.Security.Permissions;
using System.Runtime.InteropServices;
namespace System.ComponentModel {
/// <summary>
/// 组件类
/// </summary>
[DesignerCategory("Component"), ClassInterface(ClassInterfaceType.AutoDispatch), ComVisible(true)]
public class Component : MarshalByRefObject, IComponent, IDisposable {
static Component() {
//用于定位Disposed事件的关键字,不懂,为什么不用一个常量呢?
Component.EventDisposed = new object();
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose() {
//调用重载的释放方法
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 是否资源
/// </summary>
/// <param name="disposing">是否是主动释放资源</param>
protected virtual void Dispose(bool disposing) {
if (disposing) {
//防止并发还是重要的。
lock (this) {
//如果我还在别人的容器里,要从容器中移动走。
//在容器代码中,调用这个代码前,已经将Site属性设置为Null了。
if ((this.site != null) && (this.site.Container != null)) {
this.site.Container.Remove(this);
}
//检查是否包含Disposed事件的拦截
if (this.events != null) {
//注意,所有的事件都是放在这个Events中的,Disposed也是这样。
EventHandler disposedHandler = (EventHandler)this.events[Component.EventDisposed];
if (disposedHandler == null) {
return;
}
disposedHandler(this, EventArgs.Empty);
}
}
}
}
/// <summary>
/// 垃圾收集器调用
/// </summary>
~Component() {
this.Dispose(false);
}
/// <summary>
/// 获取服务
/// </summary>
/// <param name="service">要获取的服务类型</param>
/// <returns>服务的实例</returns>
protected virtual object GetService(Type service) {
ISite site = this.site;
if (site != null) {
//服务的获取顺序是:Component -> Site -> Container
return site.GetService(service);
}
return null;
}
/// <summary>
/// 重载了对象的文本显示
/// </summary>
/// <returns>新的文本</returns>
public override string ToString() {
//如果存在站点,名称像这样的: btnOk[System.Windows.Froms.Button]
ISite site = this.site;
if (site != null) {
return (site.Name + " [" + base.GetType().FullName + "]");
}
return base.GetType().FullName;
}
/// <summary>
/// 返回是否允许释放事件
/// </summary>
/// <remarks>
/// 如果继承类也将EventHandler添加到Events中的话(参见Disposed的实现)
/// 就可以通过重载此属性,来屏蔽所有事件的触发
/// </remarks>
protected virtual bool CanRaiseEvents {
get {
return true;
}
}
/// <summary>
/// 这个属性是被EventHandlerList访问的。实际上就是CanRaiseEvents属性
/// </summary>
internal bool CanRaiseEventsInternal {
get {
return this.CanRaiseEvents;
}
}
/// <summary>
/// 返回组件所在的容器
/// </summary>
/// <remarks>
/// IComponent接口并没有定义这个属性,这里只是为了使用方便而已
/// 容器是通过站点对象获取的。
/// </remarks>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
public IContainer Container {
get {
ISite site = this.site;
if (site != null) {
return site.Container;
}
return null;
}
}
/// <summary>
/// 返回是否是设计模式
/// </summary>
/// <remarks>
/// 和Container一样,为了方便使用添加的,实际数据的获取是通过站点获得的。
/// </remarks>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
protected bool DesignMode {
get {
ISite site = this.site;
if (site != null) {
return site.DesignMode;
}
return false;
}
}
/// <summary>
/// 所有事件的存储地
/// </summary>
/// <remarks>
/// 通过自定义的EventHandlerList对象,Component实现了事件的统一管理,
/// 可以屏蔽所有的事件触发(通过CanRaiseEventsInternal)
/// </remarks>
protected EventHandlerList Events {
get {
if (this.events == null) {
this.events = new EventHandlerList(this);
}
return this.events;
}
}
/// <summary>
/// 返回/设置组件的站点对象
/// </summary>
/// <remarks>
/// Component的核心思想就是这里了,可是他很简单,就是注射Site,
/// 就是注射了环境。
/// </remarks>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual ISite Site {
get {
return this.site;
}
set {
this.site = value;
}
}
/// <summary>
/// 对象的释放事件
/// </summary>
/// <remarks>
/// 通过拦截此事件,可以在拦截组件的释放。例如:
/// 当前选择了一些组件,但如果组件被释放,选择的组件将减少。
/// </remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
public event EventHandler Disposed {
add {
this.Events.AddHandler(Component.EventDisposed, value);
}
remove {
this.Events.RemoveHandler(Component.EventDisposed, value);
}
}
// Fields
private static readonly object EventDisposed;
private EventHandlerList events;
private ISite site;
}
/// <summary>
/// Component专用的事件链表
/// </summary>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public sealed class EventHandlerList : IDisposable {
/// <summary>
/// 初始化对象,允许不传递parent
/// </summary>
public EventHandlerList() {
}
/// <summary>
/// 传递Component的父对象初始化实例
/// </summary>
/// <param name="parent">所在的组件</param>
internal EventHandlerList(Component parent) {
this.parent = parent;
}
/// <summary>
/// 添加Handler
/// </summary>
/// <param name="key">事件的查询关键字</param>
/// <param name="value">新的Handler</param>
public void AddHandler(object key, Delegate value) {
//在链表中寻找这个事件
EventHandlerList.ListEntry entry = this.Find(key);
if (entry != null) {
//如果找到了,就合并成新的Handler,
entry.handler = Delegate.Combine(entry.handler, value);
}
else {
//如果没有找到,为链表添加新的头。
this.head = new EventHandlerList.ListEntry(key, value, this.head);
}
}
/// <summary>
/// 添加一批新的Handlers
/// </summary>
/// <param name="listToAddFrom">列表</param>
public void AddHandlers(EventHandlerList listToAddFrom) {
//循环链表,一个个加
for (EventHandlerList.ListEntry entry = listToAddFrom.head; entry != null; entry = entry.next) {
this.AddHandler(entry.key, entry.handler);
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose() {
this.head = null;
}
/// <summary>
/// 寻找某个关键字的事件
/// </summary>
/// <param name="key">要寻找的事件的关键字</param>
/// <returns>如果找到就返回他的结构,否则返回Null</returns>
private EventHandlerList.ListEntry Find(object key) {
//这里使用了while循环找,上面那个AddHandlers是用For。
EventHandlerList.ListEntry entry = this.head;
while (entry != null) {
if (entry.key == key) {
break;
}
entry = entry.next;
}
return entry;
}
/// <summary>
/// 在链表中移除某个Handler
/// </summary>
/// <param name="key">事件关键字</param>
/// <param name="value">要移除的Handler</param>
public void RemoveHandler(object key, Delegate value) {
//在链表中寻找,如果找到就Remove掉
EventHandlerList.ListEntry entry = this.Find(key);
if (entry != null) {
entry.handler = Delegate.Remove(entry.handler, value);
}
}
/// <summary>
/// 获取某个事件的Handler
/// </summary>
/// <param name="key">事件的关键字</param>
/// <returns>如果找到事件,且没有设置屏蔽,就返回他</returns>
public Delegate this[object key] {
get {
EventHandlerList.ListEntry entry = null;
//如果所在组件设置了不触发事件,将不会Find,返回Null
if ((this.parent == null) || this.parent.CanRaiseEventsInternal) {
entry = this.Find(key);
}
if (entry != null) {
return entry.handler;
}
return null;
}
set {
//相当与AddHandler
EventHandlerList.ListEntry entry = this.Find(key);
if (entry1 != null) {
entry1.handler = value;
}
else {
this.head = new EventHandlerList.ListEntry(key, value, this.head);
}
}
}
// Fields
private ListEntry head;
private Component parent;
//存储所有Handler的结构
private sealed class ListEntry {
/// <summary>
/// 构造新结构
/// </summary>
/// <param name="key">当前新事件类型的关键字</param>
/// <param name="handler">新委托</param>
/// <param name="next">下一个结构(链表)</param>
public ListEntry(object key, Delegate handler, EventHandlerList.ListEntry next) {
this.next = next;
this.key = key;
this.handler = handler;
}
// Fields
internal Delegate handler;
internal object key;
internal EventHandlerList.ListEntry next;
}
}
}
using System.Security.Permissions;
using System.Runtime.InteropServices;
namespace System.ComponentModel {
/// <summary>
/// 组件类
/// </summary>
[DesignerCategory("Component"), ClassInterface(ClassInterfaceType.AutoDispatch), ComVisible(true)]
public class Component : MarshalByRefObject, IComponent, IDisposable {
static Component() {
//用于定位Disposed事件的关键字,不懂,为什么不用一个常量呢?
Component.EventDisposed = new object();
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose() {
//调用重载的释放方法
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 是否资源
/// </summary>
/// <param name="disposing">是否是主动释放资源</param>
protected virtual void Dispose(bool disposing) {
if (disposing) {
//防止并发还是重要的。
lock (this) {
//如果我还在别人的容器里,要从容器中移动走。
//在容器代码中,调用这个代码前,已经将Site属性设置为Null了。
if ((this.site != null) && (this.site.Container != null)) {
this.site.Container.Remove(this);
}
//检查是否包含Disposed事件的拦截
if (this.events != null) {
//注意,所有的事件都是放在这个Events中的,Disposed也是这样。
EventHandler disposedHandler = (EventHandler)this.events[Component.EventDisposed];
if (disposedHandler == null) {
return;
}
disposedHandler(this, EventArgs.Empty);
}
}
}
}
/// <summary>
/// 垃圾收集器调用
/// </summary>
~Component() {
this.Dispose(false);
}
/// <summary>
/// 获取服务
/// </summary>
/// <param name="service">要获取的服务类型</param>
/// <returns>服务的实例</returns>
protected virtual object GetService(Type service) {
ISite site = this.site;
if (site != null) {
//服务的获取顺序是:Component -> Site -> Container
return site.GetService(service);
}
return null;
}
/// <summary>
/// 重载了对象的文本显示
/// </summary>
/// <returns>新的文本</returns>
public override string ToString() {
//如果存在站点,名称像这样的: btnOk[System.Windows.Froms.Button]
ISite site = this.site;
if (site != null) {
return (site.Name + " [" + base.GetType().FullName + "]");
}
return base.GetType().FullName;
}
/// <summary>
/// 返回是否允许释放事件
/// </summary>
/// <remarks>
/// 如果继承类也将EventHandler添加到Events中的话(参见Disposed的实现)
/// 就可以通过重载此属性,来屏蔽所有事件的触发
/// </remarks>
protected virtual bool CanRaiseEvents {
get {
return true;
}
}
/// <summary>
/// 这个属性是被EventHandlerList访问的。实际上就是CanRaiseEvents属性
/// </summary>
internal bool CanRaiseEventsInternal {
get {
return this.CanRaiseEvents;
}
}
/// <summary>
/// 返回组件所在的容器
/// </summary>
/// <remarks>
/// IComponent接口并没有定义这个属性,这里只是为了使用方便而已
/// 容器是通过站点对象获取的。
/// </remarks>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
public IContainer Container {
get {
ISite site = this.site;
if (site != null) {
return site.Container;
}
return null;
}
}
/// <summary>
/// 返回是否是设计模式
/// </summary>
/// <remarks>
/// 和Container一样,为了方便使用添加的,实际数据的获取是通过站点获得的。
/// </remarks>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
protected bool DesignMode {
get {
ISite site = this.site;
if (site != null) {
return site.DesignMode;
}
return false;
}
}
/// <summary>
/// 所有事件的存储地
/// </summary>
/// <remarks>
/// 通过自定义的EventHandlerList对象,Component实现了事件的统一管理,
/// 可以屏蔽所有的事件触发(通过CanRaiseEventsInternal)
/// </remarks>
protected EventHandlerList Events {
get {
if (this.events == null) {
this.events = new EventHandlerList(this);
}
return this.events;
}
}
/// <summary>
/// 返回/设置组件的站点对象
/// </summary>
/// <remarks>
/// Component的核心思想就是这里了,可是他很简单,就是注射Site,
/// 就是注射了环境。
/// </remarks>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual ISite Site {
get {
return this.site;
}
set {
this.site = value;
}
}
/// <summary>
/// 对象的释放事件
/// </summary>
/// <remarks>
/// 通过拦截此事件,可以在拦截组件的释放。例如:
/// 当前选择了一些组件,但如果组件被释放,选择的组件将减少。
/// </remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]
public event EventHandler Disposed {
add {
this.Events.AddHandler(Component.EventDisposed, value);
}
remove {
this.Events.RemoveHandler(Component.EventDisposed, value);
}
}
// Fields
private static readonly object EventDisposed;
private EventHandlerList events;
private ISite site;
}
/// <summary>
/// Component专用的事件链表
/// </summary>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public sealed class EventHandlerList : IDisposable {
/// <summary>
/// 初始化对象,允许不传递parent
/// </summary>
public EventHandlerList() {
}
/// <summary>
/// 传递Component的父对象初始化实例
/// </summary>
/// <param name="parent">所在的组件</param>
internal EventHandlerList(Component parent) {
this.parent = parent;
}
/// <summary>
/// 添加Handler
/// </summary>
/// <param name="key">事件的查询关键字</param>
/// <param name="value">新的Handler</param>
public void AddHandler(object key, Delegate value) {
//在链表中寻找这个事件
EventHandlerList.ListEntry entry = this.Find(key);
if (entry != null) {
//如果找到了,就合并成新的Handler,
entry.handler = Delegate.Combine(entry.handler, value);
}
else {
//如果没有找到,为链表添加新的头。
this.head = new EventHandlerList.ListEntry(key, value, this.head);
}
}
/// <summary>
/// 添加一批新的Handlers
/// </summary>
/// <param name="listToAddFrom">列表</param>
public void AddHandlers(EventHandlerList listToAddFrom) {
//循环链表,一个个加
for (EventHandlerList.ListEntry entry = listToAddFrom.head; entry != null; entry = entry.next) {
this.AddHandler(entry.key, entry.handler);
}
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose() {
this.head = null;
}
/// <summary>
/// 寻找某个关键字的事件
/// </summary>
/// <param name="key">要寻找的事件的关键字</param>
/// <returns>如果找到就返回他的结构,否则返回Null</returns>
private EventHandlerList.ListEntry Find(object key) {
//这里使用了while循环找,上面那个AddHandlers是用For。
EventHandlerList.ListEntry entry = this.head;
while (entry != null) {
if (entry.key == key) {
break;
}
entry = entry.next;
}
return entry;
}
/// <summary>
/// 在链表中移除某个Handler
/// </summary>
/// <param name="key">事件关键字</param>
/// <param name="value">要移除的Handler</param>
public void RemoveHandler(object key, Delegate value) {
//在链表中寻找,如果找到就Remove掉
EventHandlerList.ListEntry entry = this.Find(key);
if (entry != null) {
entry.handler = Delegate.Remove(entry.handler, value);
}
}
/// <summary>
/// 获取某个事件的Handler
/// </summary>
/// <param name="key">事件的关键字</param>
/// <returns>如果找到事件,且没有设置屏蔽,就返回他</returns>
public Delegate this[object key] {
get {
EventHandlerList.ListEntry entry = null;
//如果所在组件设置了不触发事件,将不会Find,返回Null
if ((this.parent == null) || this.parent.CanRaiseEventsInternal) {
entry = this.Find(key);
}
if (entry != null) {
return entry.handler;
}
return null;
}
set {
//相当与AddHandler
EventHandlerList.ListEntry entry = this.Find(key);
if (entry1 != null) {
entry1.handler = value;
}
else {
this.head = new EventHandlerList.ListEntry(key, value, this.head);
}
}
}
// Fields
private ListEntry head;
private Component parent;
//存储所有Handler的结构
private sealed class ListEntry {
/// <summary>
/// 构造新结构
/// </summary>
/// <param name="key">当前新事件类型的关键字</param>
/// <param name="handler">新委托</param>
/// <param name="next">下一个结构(链表)</param>
public ListEntry(object key, Delegate handler, EventHandlerList.ListEntry next) {
this.next = next;
this.key = key;
this.handler = handler;
}
// Fields
internal Delegate handler;
internal object key;
internal EventHandlerList.ListEntry next;
}
}
}