[CLOSED] Dynamic composition assistance needed

Page 1 of 2 12 LastLast
  1. #1

    [CLOSED] Dynamic composition assistance needed

    Hey Guys,
    I've been trying to figure out a way to create controls without knowing their type until runtime.

    To trim down the idea, let's assume a List<string> which contains strings that represent types of controls. e.g.
    var listOfItems=new List<string> {"textfield","panel","formpanel","combobox","radiobutton"}
    I've been trying to figure out a way to iterate over this list and GENERICALLY create the controls needed. To complicate this a bit further, in my real world data, I would have a list of parents and children that might like like the list above. So basically a multi-dimensional array.

    So I would need to iterate over the parents, add them to a Container/panel/formpanel etc, then loop through that set of children and essentially build the control tree that way. I am having a hard time finding a good, elegant way to do this. Maybe I'm just over thinking the problem.. I don't know. I've been scratching my head on this for a bit and wouldn't mind some outside input.

    Thanks.
    Last edited by Daniil; Feb 14, 2014 at 1:44 PM. Reason: [CLOSED]
  2. #2
    Hi @jlosi,

    Maybe, something like this.

    Example
    <%@ Page Language="C#" %>
     
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                XControl c = (Activator.CreateInstance(Type.GetType("Ext.Net.TextField"))) as XControl;
                this.Form.Controls.Add(c);
            }
        }
    </script>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Ext.NET Example</title>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
        </form>
    </body>
    </html>
    Though, it is going to work if you need to create the controls only, not to configure it. For example, I am not sure there is a possibility to apply some Text to that TextField without explicit casting to the TextField class.

    Also are you confined to use "textfield", "combobox". etc.? They should be changed to the type names.

    Though if you need to configure the controls as well (probably, you will need) and/or you are confined to use "textfield", "combobox", etc., the only solution looks a switch statement which, I guess, you already considered.
    switch (type)
    {
        case "textfield": new TextField(); ...
    }
  3. #3
    Quote Originally Posted by Daniil View Post
    Though, it is going to work if you need to create the controls only, not to configure it. For example, I am not sure there is a possibility to apply some Text to that TextField without explicit casting to the TextField class.
    Daniil, I was just looking at this today in 2.0 and was going to ask if you could expose this. I don't know if it's the same in 1.0, but...

    ... if you make ControlState State property public in ViewState.cs, then he could call the XControl's State.Set("Text", value) or any other of the many properties you use reflection to get the javascript names back from.
  4. #4
    Quote Originally Posted by Daniil View Post
    Hi @jlosi,

    Maybe, something like this.

    Example
    <%@ Page Language="C#" %>
     
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!X.IsAjaxRequest)
            {
                XControl c = (Activator.CreateInstance(Type.GetType("Ext.Net.TextField"))) as XControl;
                this.Form.Controls.Add(c);
            }
        }
    </script>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Ext.NET Example</title>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
        </form>
    </body>
    </html>
    Though, it is going to work if you need to create the controls only, not to configure it. For example, I am not sure there is a possibility to apply some Text to that TextField without explicit casting to the TextField class.

    Also are you confined to use "textfield", "combobox". etc.? They should be changed to the type names.

    Though if you need to configure the controls as well (probably, you will need) and/or you are confined to use "textfield", "combobox", etc., the only solution looks a switch statement which, I guess, you already considered.
    switch (type)
    {
        case "textfield": new TextField(); ...
    }
    I have enough room to play with the type names, but I'm not sure what benefit that would be as I cannot see a way to instantiate a control based on the xtype. Is there a way?

    To answer some other things:
    Yes. I do need to configure the controls. This is a completely dynamic tree. I will need to attach listeners add controls to other controls (fields to containers etc).

    I am currently using a switch statement to return a Component type after construction: e.g.
    new TextField.Builder()
              .FieldLabel(this.Text)
              .AllowBlank(!this.Required);
    I was trying to make this very universal where I could have the items in the list "know" how to build themselves.

    public class SurveyItem{
         public List<SurveyItem> SurveyItems{get;set;} //yes I create an instance here.. just being brief;
         public string Xtype{get;set;}
         public string FieldLabel{get;set;}
         public Guid ID {get;set;}
         [NonSerialzed]
         public Container UIComponent;
         public Component Build(){
                 
            //i have a switch statement here, but I'd rather have a more generic approach. 
           //Though I'm not sure that's possible if I have
            // to work with configurations. 
            //this is sort of how I'm doing it now and it works, but it's awfully long with the switch
             switch(ctrlType){         
                    case ControlTypes.TextBox:
                    default:
                        localComp = new TextField.Builder()
                                .FieldLabel(this.Text)
                                .AllowBlank(!this.Required);
                        break;
                    }
    
    
                this.UIComponent = new Container.Builder()
                        .CtCls("child-container")
                        .StyleSpec(this.SurveyItems.Any() ? "" : "padding-left:10px")
                        .HideBorders(true).Add(localComp);
    
                 //loop through child survey items and call build on those to add them 
                 //to this.UIComponent control collection  ... removed for brevity
                 //........loop............
               return this;
          }
    }
    So basically what I do is iterate over the collection, check the type during the Build() call and add the resulting Component to the parent.
    Last edited by jlosi; Feb 04, 2014 at 12:22 PM.
  5. #5
    Are you using asp.net 4.0 or higher? I think you should be able to use dynamic instead of XControl after the object has been CreateInstance? Then you can call the properties without knowing what they are until runtime.

    Someone has an example here (look for the item with a vote of 1):
    http://social.msdn.microsoft.com/For...csharplanguage
  6. #6
    Quote Originally Posted by michaeld View Post
    Are you using asp.net 4.0 or higher? I think you should be able to use dynamic instead of XControl after the object has been CreateInstance? Then you can call the properties without knowing what they are until runtime.

    Someone has an example here (look for the item with a vote of 1):
    http://social.msdn.microsoft.com/For...csharplanguage
    Yes 4.0.
    I had a version of this that used dynamic dispatching but I wanted to be very careful about being able to debug this. It's not that I can't use it so much as I want to leave dynamic as a last possible option but it is an option.

    one other odd thing I noticed was that with a Container item, it seemed that if the last item in a control tree was Container, the CtlCls didn't render.
    new Container.Builder()                    .CtCls("child-container")
                        .StyleSpec(this.SurveyItems.Any() ? "" : "padding-left:10px")
                        .HideBorders(true).Add(localComp);
    ...so I had to do the style spec..
    Last edited by jlosi; Feb 04, 2014 at 12:33 PM.
  7. #7
    Quote Originally Posted by michaeld View Post
    ... if you make ControlState State property public in ViewState.cs, then he could call the XControl's State.Set("Text", value) or any other of the many properties you use reflection to get the javascript names back from.
    A good idea, but not all the properties deal with State. So, it is not enough for a complete solution. As far as I can understand the OP needs a complete solution:
    Yes. I do need to configure the controls. This is a completely dynamic tree. I will need to attach listeners add controls to other controls (fields to containers etc).
    So, the only way for a complete solution is to use reflection manually.

    I have enough room to play with the type names, but I'm not sure what benefit that would be as I cannot see a way to instantiate a control based on the xtype. Is there a way?
    Well, I am not sure I understand you. Well, I also don't see a way to instantiate a control based on the xtype, but you can do it basing on the class name.
    XControl c = (Activator.CreateInstance(Type.GetType("Ext.Net.TextField"))) as XControl;
    Though, I might misunderstand something.

    I had a version of this that used dynamic dispatching but I wanted to be very careful about being able to debug this. It's not that I can't use it so much as I want to leave dynamic as a last possible option but it is an option.
    //this is sort of how I'm doing it now and it works, but it's awfully long with the
    Well, you don't want Reflection, the switch statement approach appears to be the only solution.

    Btw, one more disadvantage of Reflection - it is heavyweight.

    Quote Originally Posted by jlosi View Post
    one other odd thing I noticed was that with a Container item, it seemed that if the last item in a control tree was Container, the CtlCls didn't render.
    new Container.Builder()                    .CtCls("child-container")
                        .StyleSpec(this.SurveyItems.Any() ? "" : "padding-left:10px")
                        .HideBorders(true).Add(localComp);
    ...so I had to do the style spec..
    Hard to say what is going wrong. Please provide a full test case.
  8. #8
    Although the switch is not my favorite thing, perhaps I can try some generic class that returns a Component and cache the instance of each factory in a dictionary.

    Speaking of Component.. I noticed you guys are using XControl quite a bit. How does that differ from Component and the ability to add controls server side. I don't see an exposed method that allows .Add(..some control..). What are the pro's and con's to using XControl over Component?

    For the css thing on the container, I will start a new thread.
  9. #9
    The XControl class is a base class for all Ext.NET components which are supposed to be rendered to client (i.e. can appear in the output JavaScript).

    For example, there is the XControl class in the inheritance tree of the Store class, but there is no the Component class .

    The Component class inherits the XControl class (not directly) and is supposed to be used in the Items collections (or, certainly, individually). It is supposed that the Components have some visual representation in the browser. For example, you can see a Panel (a Component), but you cannot see a Store directly (which is not a Component, but XControl).

    What are the pro's and con's to using XControl over Component?
    Well, I would not say there are any pros and cons. It rather depends on a requirement. Hope my explanation of the difference helps to pick some.
  10. #10
    Thanks for the clarification. Moving back to dynamic composition... what would be the best way to go about cloning items. Let's say I have a structure like this:

    Panel
    --Container
    ---CompositeControl
    ------TextField | DropDown (in the composite)

    Now, i want to "copy" the Container and its children and add a duplicate to the Panel.. I don't care at which point, server or client side.
    I've made some progress here, but the controls seem to get added in a weird order.
Page 1 of 2 12 LastLast

Similar Threads

  1. [CLOSED] Need assistance with line chart
    By jpadgett in forum 2.x Legacy Premium Help
    Replies: 5
    Last Post: Feb 23, 2013, 4:03 AM
  2. urgent help needed :(
    By waqasaslammeo in forum 1.x Help
    Replies: 1
    Last Post: Feb 22, 2012, 7:42 AM
  3. Help Needed with PagingToolbar
    By pooja in forum 1.x Help
    Replies: 1
    Last Post: Jan 12, 2011, 10:57 AM
  4. Help Needed
    By pooja in forum 1.x Help
    Replies: 0
    Last Post: Jan 07, 2011, 6:07 AM
  5. Which license needed
    By ryzam in forum Licensing
    Replies: 1
    Last Post: Oct 05, 2010, 4:05 AM

Tags for this Thread

Posting Permissions