首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IExtenderProvider和WinForms设计器文件

IExtenderProvider和WinForms设计器文件
EN

Stack Overflow用户
提问于 2009-04-24 08:31:24
回答 3查看 1.3K关注 0票数 1

C# 3.5 WinForm...

因此,我最近发现了IExtenderProvider,以及如何使用它来扩展具有附加属性的控件。

在我设置的原型项目中,我在我的扩展属性的‘set’方法上设置了一个断点,当窗体加载时,我可以看到窗体上的每个控件都执行了‘set’方法;这正是我想要的。在成功的原型之后,我在我的主项目中实现了扩展器组件。我的项目中的所有窗体都继承自我添加了扩展器组件的基窗体。在基本窗体上,我将扩展器组件的修饰符设置为public,以便继承此基本窗体的窗体可以访问它。

在我为扩展属性的“set”方法添加断点之前,我做了同样的事情,但该方法不会对窗体中的控件执行(但只对基窗体中的控件执行)。帮助!

我可能应该在这一点上补充说,我已经对我的表单进行了源码控制,所以它们中的大多数都是签入的(即锁定修改)。对于我签出并修改了provider属性的窗体,我注意到在设计器文件中,所有控件都有一个额外的语句,它调用provider属性的“set”方法。

this.MyProvider1.SetMyProperty(this.txtTextBox1,false);

我的想法是否正确:为了让扩展器组件工作,它必须在物理上修改设计器文件,或者它是否应该能够处理锁定的文件,从而动态调用set方法?我猜如果它必须修改设计器文件,那么对于新的窗体或在将扩展程序组件添加到项目中后被修改的窗体来说,这不是问题--但是当您有101个窗体都被源代码安全锁定时,这将是一个问题……

如果你有任何想法,我将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-06-24 06:09:43

扩展程序提供程序(IExtenderProvider)在什么时候扩展扩展程序的“类型”(在我的例子中是winforms控件),是在设计时还是在运行时?

designer负责在属性编辑器中显示扩展程序的属性

IExtenderProvider接口中的bool CanExtend(object)方法

要让扩展程序组件正常工作,它必须在物理上修改设计器文件,还是应该能够处理锁定的文件,从而动态地调用set方法,这样的想法正确吗?

它必须在物理上修改设计器文件,并在其中写入扩展属性

我猜如果它必须修改设计器文件,那么对于新的窗体或在将扩展程序组件添加到项目中后被修改的窗体来说,这不是问题-但是当您有101个窗体都被源代码安全锁定时,这将是一个问题……

这对于新表单不是问题,而对于旧表单则不是问题。

如果要设置某些扩展属性,请打开旧表单并设置扩展属性(必须签出文件)

票数 1
EN

Stack Overflow用户

发布于 2009-06-26 08:00:20

这确实证实了我的怀疑,非常感谢。但这确实留下了一个问题,因为只有在对旧形式进行一些物理更改的情况下,组件才会被扩展。

我试图劫持Set property方法,以便向组件添加和删除事件处理程序(如果组件是控件)。图像属性是一个布尔值,当设置为false时,它会添加事件句柄,从而添加默认行为(设置为true不会添加事件处理程序)

长话短说,作为新添加窗体一部分的控件会自动添加一个事件处理程序,即使我没有显式地将该属性设置为false,但旧窗体的设计器文件从不修饰,所以没有添加事件处理程序。

作为一些背景知识,我尝试为所有控件Global event handler for all controls for User Help添加一个全局事件处理程序

这里的主题是向我的表单添加上下文帮助这里是扩展程序的示例(事件处理程序是作为end initialiser的一部分添加的)

公共分部类HelpProvider : Component、IExtenderProvider、ISupportInitialize

..。扩展程序的其他代码被省略...

代码语言:javascript
复制
    #region ISupportInitialize Members

    public void BeginInit()
    {
        // do nothing
    }

    public void EndInit()
    {
        if (DesignMode)
            return;

        foreach (Component item in _disableOnlineHelp)
        {
            if (item == null)
                continue;

            if (GetDisableOnlineHelp(item)) // developer has decide to set property to TRUE
                continue;

            Control control = item as Control;

            if (control != null)
                continue;

            control.HelpRequested += new HelpEventHandler(HelpProvider_HelpRequested);
            _toolTip.SetToolTip(control, GetHelpText(control));
        }
    }

    #endregion

    #region DisableOnlineHelp Provider Property

    public virtual bool GetDisableOnlineHelp(Component component)
    {
        object flag = _disableOnlineHelp[component];

        if (flag == null)
            return false;

        return (bool)flag;
    }

    public virtual void SetDisableOnlineHelp(Component component, bool value)
    {
        _disableOnlineHelp[component] = value;
    }

    #endregion
票数 0
EN

Stack Overflow用户

发布于 2011-05-26 00:12:44

一个问题可能是EndInit方法中的foreach循环:

代码语言:javascript
复制
Control control = item as Control;

if (control != null)
    continue;

如果该项目实际上是一个Control,则在执行以下代码之前退出循环:

代码语言:javascript
复制
control.HelpRequested += new HelpEventHandle(HelpProvider_HelpRequested);
_toolTip.SetToolTip(control, GetHelpText(control));

因此,您永远不会将事件处理程序或ToolTip添加到任何控件。Oops :)

谢谢,约翰

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/784985

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档