如何在组件(component中)模拟用户控件(UserControl)中FindForm()的功能
使用Component编程是一项值得推崇的技术,它既具有可视化的界面编程模式,又不向UserControl那样体积庞大。但是,熟悉UserControl的朋友们都知道,在UserControl类中有一个FindForm()函数,返回UserControl所在的窗体的引用,这将大大方便我们对窗体的控制----尽管这可能有些越俎代庖的味道,但有时我们就需要这种控制能力。
但是,在Component并没有提供这样的函数,你可以使用其它的一些技巧来取得Component所在的窗体的引用,比如在Component的构造函数中使用Application.AddMessageFilter(this),然后取出由窗体发来的消息的句柄,就可以得到窗体的引用,缺点是不能设计时刻就获得窗体引用;比如可以给Component加一个StyleForm的属性,然后你就可以在设计器中用鼠标选择一个,缺点是你必须手动来选择。
今天,花了半天的时间,终于设计出了克服了以上两个缺点的方案,代码如下:
但是,在Component并没有提供这样的函数,你可以使用其它的一些技巧来取得Component所在的窗体的引用,比如在Component的构造函数中使用Application.AddMessageFilter(this),然后取出由窗体发来的消息的句柄,就可以得到窗体的引用,缺点是不能设计时刻就获得窗体引用;比如可以给Component加一个StyleForm的属性,然后你就可以在设计器中用鼠标选择一个,缺点是你必须手动来选择。
今天,花了半天的时间,终于设计出了克服了以上两个缺点的方案,代码如下:
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.ComponentModel.Design;
using System.Windows.Forms;
namespace FindFormSimulation
{
public partial class BaseStyle : Component
{
public BaseStyle()
{
InitializeComponent();
}
public BaseStyle(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// 关键在这里,对基类的Site重载。
/// </summary>
public override ISite Site
{
get
{
return base.Site;
}
set
{
if (base.Site != value)
{
base.Site = value;
//使用反射机制,在设计时刻取得你要控制的窗体。
IReferenceService referenceService = (IReferenceService)this.GetService(typeof(IReferenceService));
if (referenceService != null)
{
///下面这句用于取得本组件所在的窗体对象。
object[] parent = referenceService.GetReferences(typeof(Form));
Form container = parent[0] as Form;
StyleForm = container;
///如下方法测试,可以知道parent.Length总是为1的。
//StyleForm.Text = parent.Length.ToString();
}
}
}
}
private Form styleForm = null;
[Description("本组件所要控制的窗体"), DefaultValue(null)]
public Form StyleForm
{
get { return styleForm; }
set
{
if (styleForm != value)
{
styleForm = value;
}
}
}
}
}
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.ComponentModel.Design;
using System.Windows.Forms;
namespace FindFormSimulation
{
public partial class BaseStyle : Component
{
public BaseStyle()
{
InitializeComponent();
}
public BaseStyle(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// 关键在这里,对基类的Site重载。
/// </summary>
public override ISite Site
{
get
{
return base.Site;
}
set
{
if (base.Site != value)
{
base.Site = value;
//使用反射机制,在设计时刻取得你要控制的窗体。
IReferenceService referenceService = (IReferenceService)this.GetService(typeof(IReferenceService));
if (referenceService != null)
{
///下面这句用于取得本组件所在的窗体对象。
object[] parent = referenceService.GetReferences(typeof(Form));
Form container = parent[0] as Form;
StyleForm = container;
///如下方法测试,可以知道parent.Length总是为1的。
//StyleForm.Text = parent.Length.ToString();
}
}
}
}
private Form styleForm = null;
[Description("本组件所要控制的窗体"), DefaultValue(null)]
public Form StyleForm
{
get { return styleForm; }
set
{
if (styleForm != value)
{
styleForm = value;
}
}
}
}
}