代码之家  ›  专栏  ›  技术社区  ›  Rob Cooper

ASP。NET自定义控件-复合

  •  19
  • Rob Cooper  · 技术社区  · 17 年前

    总结

    大家好,
    好的,进一步探讨我使用自定义控件的冒险。..

    总之,我学到了自定义控件的三个主要“类”。如果有任何错误,请随时纠正我!

    1. 用户控件 -哪些继承自 对象 并且包含在 ASCX 文件。这些功能非常有限,但它们是一种快速轻便的方式,可以在设计师的支持下获得一些UI共性。
    2. 自定义复合控件 -这些控件继承自 基类 在那里,您可以将预先存在的控件添加到控件中 CreateChildControls 方法。这提供了极大的灵活性,但如果不进行额外的编码,则缺乏设计者的支持。它们具有高度的可移植性,因为它们可以编译成DLL。
    3. 自定义渲染控件 -与自定义组合控件类似,这些控件被添加到Web控件库项目中。控件的呈现完全由程序员通过重写控件来控制 提供 方法。

    我的想法。。

    好的,在玩自定义复合材料时,我发现了以下内容:

    • 您对HTML输出几乎没有控制权,这使得“调试”变得困难。
    • 这个 CreateChildControls (以及后续的方法)可能会变得非常繁忙 控制。添加(myControl) 到处都是。
    • 我发现呈现表格(无论是布局还是内容)都相当尴尬。

    问题。。

    所以,我承认,我是新手,所以我可能会偏离我上面提到的一些观点。。

    • 你使用复合材料吗?
    • 你有什么巧妙的技巧来控制HTML输出吗?
    • 你只是说“见鬼去吧”,然后继续创建一个自定义渲染控件吗?

    这是我渴望在脑海中真正坚定的东西,因为我知道有多少 好的 控制开发可以缩短整体开发时间。

    我期待着你的回答^_^

    6 回复  |  直到 6 年前
        1
  •  5
  •   Jon Limjap    17 年前

    我建议继续使用自定义渲染控件。我发现在大多数情况下,复合可以更容易地在UserControl中完成和使用,但除此之外,你还需要更精细的控制(双关语无意中)才能获得你自己的渲染策略。

    可能有一些控件足够简单,值得进行组合(例如,文本框与基于javascript/dhtml的日期选择器相结合),但除此之外,自定义呈现的控件似乎是可行的。

        2
  •  3
  •   Mark Cidade    9 年前

    这是我用于自定义渲染的另一种扩展方法:

     public static void WriteControls
            (this HtmlTextWriter o, string format, params object[] args)
     { 
        const string delimiter = "<2E01A260-BD39-47d0-8C5E-0DF814FDF9DC>";
        var controls  = new Dictionary<string,Control>();
    
        for(int i =0; i < args.Length; ++i)
        { 
           var c = args[i] as Control; 
           if (c==null) continue;
           var guid = Guid.NewGuid().ToString();
           controls[guid] = c;
           args[i] = delimiter+guid+delimiter;
        }
    
        var _strings = string.Format(format, args)
                             .Split(new string[]{delimiter},
                                    StringSplitOptions.None);
        foreach(var s in _strings)
        { 
           if (controls.ContainsKey(s)) 
               controls[s].RenderControl(o);
           else 
               o.Write(s);
        }
    }
    

    然后,为了在RenderContents()方法中渲染自定义复合,我编写了以下代码:

    protected override void RenderContents(HtmlTextWriter o)
    { 
        o.WriteControls
             (@"<table>
                   <tr>
                        <td>{0}</td>
                        <td>{1}</td>
                   </tr>
                 </table>"
                ,Text
                ,control1);
     }
    
        3
  •  2
  •   Slavo    17 年前

    罗布,你说得对。我提到的方法是一种混合方法。使用ascx文件的优点是,在我见过的每个项目中,设计师都会对编辑实际标记感到最舒服,而且你和设计师可以单独使用ascx。如果你不打算以后对控件本身进行实际的CSS/标记/设计更改,你可以使用自定义渲染控件。正如我所说的,我的方法只适用于更复杂的场景(这些场景可能是你需要设计师的地方:)

        4
  •  1
  •   Mark Cidade    17 年前

    我经常使用复合控件。不要覆盖Render或RenderContents,只需为每个控件分配一个CssClass并使用样式表。用于多个控件。添加,我使用扩展方法:

    //Controls.Add(c1, c2, c3)
    static void Add(this ControlCollection coll, params Control[] controls)
     { foreach(Control control in controls) coll.Add(control);
     }
    

    对于快速和脏的渲染,我使用这样的东西:

    writer.Render(@"<table>
                       <tr><td>{0}</td></tr>
                       <tr>
                           <td>", Text);
    control1.RenderControl(writer);
    writer.Render("</td></tr></table>");
    

    对于初始化控件属性,我使用属性初始化器语法:

    childControl = new Control {  ID="Foo"
                                , CssClass="class1"
                                , CausesValidation=true;
                               };
    
        5
  •  1
  •   Slavo    17 年前

    在您有一个大型web应用程序并希望在许多地方重用大块的情况下,使用自定义复合控件是有道理的。然后,你只会添加你正在开发的子控件,而不是重复自己。 在我最近参与的一个大型项目中,我们做了以下工作:

    • 每个复合控件都有一个容器。用作控件内所有内容的包装。
    • 每个复合控件都有一个模板。仅包含模板标记的ascx文件(不含<%Control%>指令)。
    • 容器(本身就是一个控件)是从模板初始化的。
    • 容器公开模板中所有其他控件的属性。
    • 你只使用这个。控制。在复合控件中添加([the_container])。

    事实上,您需要一个基类,它将负责使用指定的模板初始化容器,并在模板中找不到控件时抛出异常。当然,在小型应用程序中,这可能是一种矫枉过正的做法。如果你没有重用的代码和标记,只想编写简单的控件,你最好使用用户控件。

        6
  •  0
  •   Andrew Myhre    17 年前

    您可以使用此技术使设计时间更容易:

    http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx

    基本上,您可以在运行时使用LoadControl方法创建用户控件的实例,然后给它一个某种状态包,然后将其附加到控件树上。因此,您的复合控件实际上更像是一个控制器,而.ascx文件则更像一个视图。

    这将为您省去在C#中实例化整个控件树和设置控件样式的麻烦!