创建一个组件以自动对其拥有的Form/UserControl上的所有控件进行迭代 [英] Create a Component to automaticall iterate controls on its owning Form/UserControl

查看:65
本文介绍了创建一个组件以自动对其拥有的Form/UserControl上的所有控件进行迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我目前正在考虑创建一个应从工具箱拖到窗体/用户控件的组件.

放置后,它应该遍历放置组件的Form/Usercontrol上的所有控件,并应用一些格式.

它应该能够自动找出其所有者,然后对控件进行最佳处理(最好),然后再显示控件以应用格式逻辑(迭代已经起作用,因此在这里没有问题).

我已经有以下内容:

Hi all,
I am currently thinking about creating a Component that should be dragged from the ToolBox to a Form/UserControl.

Once it is placed it should iterate through all controls on the Form/Usercontrol where the component was placed on and apply some formatting.

It should be able to automatically figure out its owner and then iterate the controls (best) before they are shown to appy the formatting logic (the iteration already works, so no problem here).

I already had the following:

public Control OwningControl{get;set;}


以便至少能够在希望迭代开始的位置设置控件,但是我总是需要触发一个函数(在拥有表单的Load事件中),该函数调用组件的ApplyFormatting()函数以应用格式. .

最好将组件拖动到窗体/UserControl,然后就把它忘了...
也许可以在Designer中调整某些内容(以便我的同事轻松使用),而不是在代码中进行调整...
有可能吗?


更新:
我发现有一个Site(ISite)属性,可以与拥有的容器进行交互.
这至少在运行时为我提供了容器,但是我无法在容器中获取所有控件.


Update II
好吧,多亏了我在网上找到的帖子,我才迈出了一步.
我添加了以下内容以获取组件的所有权控件,在我的情况下,该控件是Form或UserControl:


to be at least able to set the control where I wanted the iteration to start but I always need to fire a function (in the Load event of the owning form) that calls the ApplyFormatting() function of the component to apply the formatting...

It would be great to drag the component to the form/UserControl and then just forget about it...
Maybe adjusting something in the Designer (for my colleagues to use it easily) and not in the code...
Is that possible?


UPDATE:
I figured out that there is a Site (ISite) property that allows interaction with the owning container.
This at least gives me the container at runtime, but I am not able to get all the controls in the container.


Update II
Ok, I made a step foreward thanks to a post I found on the net.
I added the following to get a hand on the owning control of a component, which is in my case a Form or a UserControl:

        private delegate void HostingControlChangedHandler(object sender);

        private event HostingControlChangedHandler HostingControlChanged;

        private void InvokeHostingControlChanged()
        {
            HostingControlChangedHandler handler = HostingControlChanged;
            if (handler != null) handler(this);
        }

        Control hostingControl = null;

        [BrowsableAttribute(false)]
        public Control HostingControl
        {
            // Used to populate InitializeComponent at design time
            get
            {
                if ((hostingControl == null) && this.DesignMode)
                {
                    // Access designer host and obtain reference to root component
                    IDesignerHost designer =
                      this.GetService(typeof(IDesignerHost)) as IDesignerHost;
                    if (designer != null)
                    {
                        hostingControl = designer.RootComponent as Control;
                    }
                }
                return hostingControl;
            }
            set
            {
                if (!this.DesignMode)
                {
                    // Don't change hosting form at run time
                    if ((hostingControl != null) && (hostingControl != value))
                    {
                        throw new
                          InvalidOperationException
                          ("Can't set HostingForm at run time.");
                    }
                }
                hostingControl = value;
                InvokeHostingControlChanged();
            }


        }

// this is set in the constructor
void DefaultGridFormatter_HostingControlChanged(object sender)
        {
            _ultraGridDefaultFormatter.HostingControl = this.HostingControl;

            
            Form frm = this.HostingControl as Form;

            if (frm != null)
            {
                ((Form)this.HostingControl).Load += new EventHandler(DefaultGridFormatter_Load);
                return;
            }

            UserControl ctr = this.HostingControl as UserControl;
            if(ctr != null)
            {
                if(ctr.ParentForm != null)
                {
                    ctr.ParentForm.Load += new EventHandler(DefaultGridFormatter_Load);
                }
            }
        }



现在,我可以获取拥有的控件并遍历其子控件以应用所需的任何内容.
当我从工具箱中将组件拉到窗体时,在InitializeComponent中正确设置了HostingControl.
不幸的是,它仅在运行时无法在设计模式下工作....

我想念什么吗?

通常这是一种好方法还是违反了软件工程中的一切;)



任何想法/评论都表示赞赏,

欢呼
Andy



I am now able to grab the owning control and iterate through its child-controls to apply whatever is needed.
When I pull the component from the toolbox to my form the HostingControl is correctly set in InitializeComponent.
Unfortunately it does not work in the design-mode, only at runtime....

Am I missing something?

Is this in general a good approach or does it violates everything that is good in software engineering ;)



Any ideas/comments are kindly appreciated,

cheers
Andy

推荐答案

检查控件的Parent属性.它不应该为null,因为在将控件添加到表单时会设置oit.

可能最麻烦的是在表单本身中创建一个公共方法,并让控件从其Load事件中调用该方法.但是,让cont5ol知道并在父级中调用方法通常被认为是不好的做法.

您也许还可以更改父级Controls集合的可访问性,并在控件内部处理该集合.
Check the Control''s Parent property. It shouldn''t be null because oit''s set when the control is added to the form.

Probably the least hassle would be to create a public method in the form itself, and have the control call that method from its Load event. It''s generally considered bad practice to have the cont5ol know about and call a method in the parent, though.

You might also be able to change the accessibility of the parent''s Controls collection and process that colleciton inside your control.


这篇关于创建一个组件以自动对其拥有的Form/UserControl上的所有控件进行迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆