IExtenderProvider和WinForms设计器文件

时间:2009-04-24 08:31:24

标签: c# .net winforms

C#3.5 Winforms ...

所以我最近发现了IExtenderProvider以及它如何用于扩展具有附加属性的控件。

在我设置的原型项目中,我为extendee属性的'set'方法设置了一个断点,并且当表单加载时,我可以看到为表单上的每个控件执行'set'方法;这正是我想要的。在成功的原型之后,我将扩展器组件实现到我的主项目中。我项目中的所有表单都从一个基本表单继承而来,我已经添加了我的扩展程序组件。在基础表单上,我将扩展程序组件的修饰符设置为public,以便通过继承此基本表单的表单来访问它。

在我为extendee属性的'set'方法添加断点之前做同样的事情,但该方法不对表单中的控件执行(但仅针对基本表单中的控件)。帮助!

我应该在这一点上添加我来源控制我的表单,因此大多数都是签到的(即锁定修改)。对于我签出并修改了提供者属性的表单;我在设计器文件中注意到所有控件都有一个额外的语句,它调用了provider属性的'set'方法。

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

我是否正确地认为,为了扩展器组件的工作,它必须在物理上修改设计器文件,还是应该能够处理锁定的文件,从而动态调用set方法?我想如果它确实需要修改设计器文件,那么对于在扩展程序组件添加到项目后得到修改的新表单或表单这不是问题 - 但是如果有101个表单全部被源代码锁定则会出现问题-safe ...

我很感激任何想法......

3 个答案:

答案 0 :(得分:1)

  
    

扩展程序提供程序(IExtenderProvider)在什么时候扩展了扩展程序所针对的“类型”(在我的情况下是一个winforms控件);在设计时或运行时?

  

设计师负责在属性编辑器中向您展示扩展程序的属性 来自IExtenderProvider接口的方法bool CanExtend(object)

  
    

我是否正确地认为,为了扩展器组件的工作,它必须在物理上修改设计器文件,还是应该能够处理锁定的文件,从而动态调用set方法?

  

它必须在物理上修改设计器文件,并在那里编写扩展属性

  
    

我想如果它确实需要修改设计器文件,那么对于在扩展程序组件添加到项目后被修改的新表单或表单这不是问题 - 但是当你有101个表单时会出现问题被源安全锁定......

  

这对新表单不是问题,不适用于旧表单 如果要设置某些扩展属性,请打开旧表单并设置扩展属性(必须签出文件)

答案 1 :(得分:0)

这确实证实了我的怀疑,非常感谢。但这确实留下了一个问题,即只有在对旧表单进行一些物理更改时才会扩展组件。

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

简而言之,作为新添加表单一部分的控件会自动添加一个事件处理程序,即使没有我明确地将属性设置为false,但旧表单的设计器文件永远不会修改,因此事件处理程序不是添加。

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

这里的主题是在我的表单中添加上下文帮助这里的扩展器示例(事件处理程序作为结束初始化程序的一部分添加)

public partial class HelpProvider:Component,IExtenderProvider,ISupportInitialize

...省略了扩展器的其他代码......

    #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

答案 2 :(得分:0)

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

Control control = item as Control;

if (control != null)
    continue;

如果该项实际上是一个Control,那么在执行此代码之前就会离开循环:

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

因此您永远不会将事件处理程序或工具提示添加到任何控件。糟糕:)

谢谢, 约翰