如何在组件(component中)模拟用户控件(UserControl)中FindForm()的功能

    使用Component编程是一项值得推崇的技术,它既具有可视化的界面编程模式,又不向UserControl那样体积庞大。但是,熟悉UserControl的朋友们都知道,在UserControl类中有一个FindForm()函数,返回UserControl所在的窗体的引用,这将大大方便我们对窗体的控制----尽管这可能有些越俎代庖的味道,但有时我们就需要这种控制能力。
    但是,在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[0as 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;
                }

            }

        }

    }

}

posted @ 2006-04-19 23:55  李现民  阅读(868)  评论(0编辑  收藏  举报