ASP.NET Custom Controls - Composites

后端 未结 6 503
别跟我提以往
别跟我提以往 2020-12-13 20:13

Summary

Hi All,
OK, further into my adventures with custom controls...

In summary, here is that I have learned of three main "classes" of cus

相关标签:
6条回答
  • 2020-12-13 20:45

    You might be able to make use of this technique to make design-time easier:

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

    Basically you create an instance of a user control at runtime using the LoadControl method, then hand it a statebag of some kind, then attach it to the control tree. So your composite control would actually function like more of a controller, and the .ascx file would be like a view.

    This would save you the trouble of having to instantiate the entire control tree and style the control in C#!

    0 讨论(0)
  • 2020-12-13 20:47

    Using custom composite controls has a point in a situation where you have a large web application and want to reuse large chunks in many places. Then you would only add child controls of the ones you are developing instead of repeating yourself. On a large project I've worked recently what we did is the following:

    • Every composite control has a container. Used as a wrapped for everything inside the control.
    • Every composite control has a template. An ascx file (without the <%Control%> directive) which only contains the markup for the template.
    • The container (being a control in itself) is initialized from the template.
    • The container exposes properties for all other controls in the template.
    • You only use this.Controls.Add([the_container]) in your composite control.

    In fact you need a base class that would take care of initializing a container with the specified template and also throw exceptions when a control is not found in the template. Of course this is likely to be an overkill in a small application. If you don't have reused code and markup and only want to write simple controls, you're better off using User Controls.

    0 讨论(0)
  • 2020-12-13 20:51

    Here's another extension method that I use for custom rendering:

     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);
        }
    }
    

    Then, to render a custom composite in the RenderContents() method I write this:

    protected override void RenderContents(HtmlTextWriter o)
    { 
        o.WriteControls
             (@"<table>
                   <tr>
                        <td>{0}</td>
                        <td>{1}</td>
                   </tr>
                 </table>"
                ,Text
                ,control1);
     }
    
    0 讨论(0)
  • 2020-12-13 20:53

    Rob, you are right. The approach I mentioned is kind of a hybrid. The advantage of having ascx files around is that on every project I've seen, designers would feel most comfortable with editing actual markup and with the ascx you and a designer can work separately. If you don't plan on actual CSS/markup/design changes on the controls themselves later, you can go with a custom rendered control. As I said, my approach is only relevant for more complicated scenarios (and these are probably where you need a designer :))

    0 讨论(0)
  • 2020-12-13 21:03

    I say go ahead with the custom rendered control. I find that in most cases the composite can be easier done and used in a UserControl, but anything beyond that and you'd need to have a finer degree of control (pun unintended) to merit your own rendering strategy.

    There maybe controls that are simple enough to merit a composite (e.g., a textbox combined with a javascript/dhtml based datepicker, for example) but beyond that one example, it looks like custom rendered controls are the way to go.

    0 讨论(0)
  • 2020-12-13 21:04

    I often use composite controls. Instead of overriding Render or RenderContents, just assign each Control a CssClass and use stylesheets. For multiple Controls.Add, I use an extension method:

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

    For quick and dirty rendering, I use something like this:

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

    For initializing control properties, I use property initializer syntax:

    childControl = new Control {  ID="Foo"
                                , CssClass="class1"
                                , CausesValidation=true;
                               };
    
    0 讨论(0)
提交回复
热议问题