4

我正在处理的一系列控件的一部分显然涉及我将其中的一些组合在一起。我很快开始了解到这需要考虑(这对我来说是全新的!):)

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

这是在其中实例化子控件的代码。到目前为止,它似乎一直在使用普通的静态控件正常工作:

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

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

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

今天当我尝试在其中嵌套一个更复杂的控件时,问题就来了。该控件使用对页面的引用,因为它注入了 JavaScript 以使其更加灵活和响应迅速(这RegisterClientScriptBlock是我需要页面引用的唯一原因)。

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

令我困惑的是,该控件作为独立的控件可以正常工作,但是当放置在其中时StyledWindow,一切都变得非常错误!

所以,看起来我在 myStyledWindowChildControl. 有任何想法吗?

更新

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

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

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

按照Longhorn213 的回答更新

是的,我一直在玩控件,将一个放在复合材料中,一个放在外面。然后我在控件生命周期中的 event major event 中获取 Page 的状态并将其呈现到页面。

独立运行正常,页面按预期启动。但是,嵌套在 Composite 中的那个是不同的。它的OnLoad事件根本没有被解雇!所以我猜布拉德可能是对的,因为我没有正确设置控制层次结构,任何人都可以就我所缺少的内容提供一些建议吗?Panel方法还不够吗?(好吧,显然不是吗?!):D

谢谢你们的帮助,不胜感激:)

4

4 回答 4

2

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

于 2008-09-24T15:19:25.867 回答
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 所做的,它只是将脚本内嵌在页面上。

于 2008-09-24T16:46:41.677 回答
1

解决了!

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

  • 我认为使用Panel是一种 hack,所以我应该删除它并找出它是如何完成的。
  • 我不想做类似MyCtl.Controls[0].Controls访问添加到组合中的控件之类的事情。
  • 我想让这该死的东西工作!

所以,我搜索并点击了MSDN这篇文章真的很有帮助(即几乎复制“n”粘贴,并且解释得很好——MSDN 传统上不擅长的东西)。好的!

所以,我去掉了使用,Panel几乎遵循了文章,把它当作福音,边做边做笔记。

这是我现在拥有的:

  • 我了解到我使用了错误的术语。我应该称它为Templated Control。虽然模板化控件在技术上是复合的,但有明显的区别。模板化控件可以定义添加到它们的项目的界面。
  • 模板化控件非常强大,而且一旦你开始了解它们,实际上设置起来非常快速和容易!
  • 我会在设计师的支持下多玩一些,以确保我完全理解这一切,然后写一篇博文:)
  • “模板”控件用于指定模板数据的接口。

例如,下面是模板化控件的 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;
        }
    }

差不多就是这样,当你知道怎么做时很容易!:)

Next:设计时区域支持!

于 2008-09-25T13:41:47.590 回答
0

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

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

  1. 我已经重写了Controls组合的属性访问器以返回 thisPanel的 Controls 集合,因为我不想去ctl.Controls[0].Controls[0]获得我想要的实际控件。我已将其删除,但我需要对其进行排序。
  2. 我没有添加PanelControls集合中,我现在已经这样做了。

所以,它现在可以工作了,但是,我如何获得Controls复合材料的属性以返回 中的项目Panel,而不是Panel本身?

于 2008-09-25T09:48:54.060 回答