ASP.NET中自定义组合中的子控件初始化

时间:2008-09-24 15:16:12

标签: asp.net controls custom-server-controls

我正在研究的一系列控件中的一部分显然涉及到将它们中的一些混合在一起进入复合材料。我很快就开始知道这需要考虑(这对我来说都是新的!):)

我基本上有一个StyledWindow控件,它本质上是一个荣耀的Panel能够做其他位(比如添加边框等)。

以下是实例化其中的子控件的代码。到目前为止,似乎已经正常使用普通的静态控件:

    protected override void CreateChildControls()
    {
        _panel = new Panel();

        if (_editable != null)
            _editable.InstantiateIn(_panel);

        _regions = new List<IAttributeAccessor>();
        _regions.Add(_panel);
    }

当我尝试在其中嵌套更复杂的控件时,问题就出现了。此控件使用对页面的引用,因为它注入了JavaScript以使其更加活泼和响应(RegisterClientScriptBlock是我需要页面引用的唯一原因)。

现在,这导致了“对象null”错误,但我将其本地化为render方法,当然这是尝试针对[null] Page对象调用该方法。

让我感到困惑的是,控件作为一个独立的工作正常,但当放在StyledWindow时,一切都非常错误!

因此,我的StyledWindowChildControl似乎遗漏了某些内容。有什么想法吗?

更新

正如Brad Wilson非常正确地指出的那样,您没有看到控件被添加到Controls集合中。这就是_panel的用途,这是为了处理这个问题,基本上覆盖Controls(我从某个指南得到了这个):

    Panel _panel;    // Sub-Control to store the "Content".
    public override ControlCollection Controls
    {
        get
        {
            EnsureChildControls();
            return _panel.Controls;
        }
    }

我希望这有助于澄清事情。道歉。

Longhorn213's Answer

之后更新

是的,我一直在玩控制,在复合材料中放置一个,在外面放一个。然后,我在控件生命周期中获得了事件主要事件的Page状态,并将其呈现给页面。

独立版正常工作,页面按预期显示。但是,嵌套在Composite中的那个是不同的。它的OnLoad事件根本没有被解雇!所以我猜Brad可能是正确的,因为我没有正确设置控件层次结构,有人可以提供一些关于我缺少的建议吗? Panel方法不够吗? (好吧,显然不是吗?!):D

感谢您的帮助,感谢:)

4 个答案:

答案 0 :(得分:2)

我没有看到你在任何地方将控件添加到Controls集合,这可以解释为什么他们无法访问页面(因为他们从未正式放在页面上)。

答案 1 :(得分:1)

我总是把JavaScript调用放在OnLoad函数上。如下。

protected override void OnLoad(EventArgs e)
{

    // Do something to get the script
    string script = GetScript();

    this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "SomeJavaScriptName", script);

    // Could also use this function to determine if the script has been register. i.e. more than 1 of the controls exists
    this.Page.ClientScript.IsClientScriptBlockRegistered("SomeJavaScriptName");

    base.OnLoad(e);
}

如果您仍想进行渲染,那么您只需在响应中编写脚本即可。这就是RegisterScriptBlock所做的,它只是将脚本内联在页面上。

答案 2 :(得分:1)

解决!

是的,我决心今天破解这个!以下是我的想法:

  • 我认为使用Panel有点像黑客,所以我应该删除它并找出它是如何完成的。
  • 我不想做MyCtl.Controls[0].Controls之类的事情来访问添加到合成中的控件。
  • 我想要该死的东西上班!

所以,我搜索并点击MSDNthis artcle 真的很有帮助(就像几乎复制'n'粘贴一样,并解释得很好 - 某些MSDN传统上是坏的在)。尼斯!

所以,我扯掉了Panel的使用,并且几乎跟着artcle并把它作为福音,在我去的时候记笔记。

这就是我现在所拥有的:

  • 我知道我使用了错误的术语。我应该称之为 模板控制 。虽然模板化控件在技术上是复合材料,但存在明显差异。模板化控件可以为添加到它们的项目定义接口。
  • 模板控件功能非常强大,一旦你绕过它们,它们的设置非常简单快捷!
  • 我将在设计师的支持下发挥更多作用,以确保我完全理解这一切,然后发布博客文章:)
  • “模板”控件用于指定模板化数据的界面。

例如,以下是模板化控件的ASPX标记:

<cc1:TemplatedControl ID="MyCtl" runat="server">
    <Template>
        <!-- Templated Content Goes Here -->
    </Template>
</cc1:TemplatedControl>   

继承我现在的代码

public class DummyWebControl : WebControl
{
    // Acts as the surrogate for the templated controls.
    // This is essentially the "interface" for the templated data.
}

在TemplateControl.cs中......

    ITemplate _template;
    // Surrogate to hold the controls instantiated from 
    // within the template.
    DummyWebControl _owner;

    protected override void CreateChildControls()
    {
        // Note we are calling base.Controls here
        // (you will see why in a min).
        base.Controls.Clear();
        _owner = new DummyWebControl();

        // Load the Template Content
        ITemplate template = _template;
        if (template == null)
            template = new StyledWindowDefaultTemplate();
        template.InstantiateIn(_owner);

        base.Controls.Add(_owner);
        ChildControlsCreated = true;
    }

然后,为了便于访问[Surrogate]对象的控件:

(这就是我们需要清除/添加base.Controls的原因)

    public override ControlCollection Controls
    {
        get
        {
            EnsureChildControls();
            return _owner.Controls;
        }
    }

这就是它,当你知道怎么做时很容易! :)

下一步:设计时区支持!

答案 3 :(得分:0)

是的,我玩了,我认为我的控件实例化有问题,因为Longhorn是对的,我应该能够在OnLoad创建脚本引用(我不能)和Brad是正确的,我需要通过添加到复合的Controls集合来确保我的Controls层次结构。

所以,我在这里有两件事:

  1. 我已经覆盖复合的Controls属性访问器以返回此Panel的控件集合,因为我不想让ctl.Controls[0].Controls[0]进入我想要的实际控件。 我删除了这个,但我需要对此进行排序。
  2. 我没有将Panel添加到Controls集合中,我现在已经这样做了。
  3. 所以,它现在有效,如何让复合的Controls属性返回Panel中的项目,而不是Panel本身?