[CLOSED] Extending Components and Overriding properties

  1. #1

    [CLOSED] Extending Components and Overriding properties

    From what I have seen in the source, you never extend Components as is done by ExtJs, e.g. instead of extending Window from Panel, you create base classes PanelBase, and extend both Window and Panel from PanelBase.

    Same is true for form components e.g. DateField extending TriggerFieldBase etc.

    In my understanding, this is done to overcome issues with co-variance and contra-variance in overriding (which are not permissible in C# n overriding scenarios). e.g. this prevents issues in overriding the Listeners property where Panel would have PanelListeners but Window would have WindowListeners.

    Is this correct?

    Now, what would you suggest for extending components? e.g. I need to extend Window client-side with custom events, and need to do on the server-side the same. I have extended Window, extended WindowListeners and hide Listeners property on my new CustomWindow class. But I get a Parser Error: Ambiguous match found:

    Parser Error Message: Ambiguous match found.
    
    Source Error: 
    
    
    Line 44:                                     <portal:PortalWindow Title="Hello">
    Line 45:                                         <Listeners>
    Line 46:                                         </Listeners>
    Line 47:                                     </portal:PortalWindow>
    Last edited by Daniil; Oct 13, 2010 at 11:31 AM. Reason: [CLOSED]
  2. #2
    I wonder whether Ext.Net components have really been designed for extending and inheritance.

    I needed to have custom node types for TreePanel too. My first attempt at extending TreeNode was a failure because I cannot override or hide Listeners.

    I then approached to extend TreeNodeBase, but to my surprise, ParentNode setter is internal (it should have been protected atleast), AfterItemAdd event for StateManagedCollection is internal. I am having some heart-burn currently.
  3. #3
    Looks like the problems are not ending, this time client-side Ext.net.TreePanel's createNode method:

    createNode : function (config) {
            var type = config.nodeType || "node";
            if (this.loader.baseAttrs) {
                Ext.applyIf(config, this.loader.baseAttrs);
            }
            if (typeof config.uiProvider == "string") {
                config.uiProvider = this.loader.uiProviders[config.uiProvider] || eval(config.uiProvider);
            }
            if (type == "node") {
                return new Ext.tree.TreeNode(config);
            }
            return new Ext.tree.AsyncTreeNode(config);
        }
    The code assumes there would either be TreeNodes or AsyncTreeNodes, however ExtJs allows you to create and register custom node types. See the following for ExtJs Tree Loader's createNode method:

     if(attr.nodeType){
                return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
            }else{
                return attr.leaf ?
                            new Ext.tree.TreeNode(attr) :
                            new Ext.tree.AsyncTreeNode(attr);
            }
    Any chances of these issues getting addressed soon? I think they might require significant changes to the toolkit, which might not be desirable on your side at this time...
  4. #4
    Hi,

    From what I have seen in the source, you never extend Components as is done by ExtJs, e.g. instead of extending Window from Panel, you create base classes PanelBase, and extend both Window and Panel from PanelBase.

    Same is true for form components e.g. DateField extending TriggerFieldBase etc.

    In my understanding, this is done to overcome issues with co-variance and contra-variance in overriding (which are not permissible in C# n overriding scenarios). e.g. this prevents issues in overriding the Listeners property where Panel would have PanelListeners but Window would have WindowListeners.

    Is this correct?

    Now, what would you suggest for extending components? e.g. I need to extend Window client-side with custom events, and need to do on the server-side the same. I have extended Window, extended WindowListeners and hide Listeners property on my new CustomWindow class. But I get a Parser Error: Ambiguous match found
    Yes, therefore we created Base classes without listeners and direct events. Because each new widget can has own events but we C# doesn't allow to override return type (interesting, as I remember Java allows override return type of methods which have different arguments)

    My first attempt at extending TreeNode was a failure because I cannot override or hide Listeners.
    Well, I can suggest one workaround (just not sure if it is acceptable for you), you can add additional listeners property, like ExtnededListeners, and set serialization name as "listeners" (in this case, do not use standard listeners). As you see it is not very good solution but it can solve that problem

    I then approached to extend TreeNodeBase, but to my surprise, ParentNode setter is internal (it should have been protected atleast), AfterItemAdd event for StateManagedCollection is internal. I am having some heart-burn currently.
    Fixed. ParentNode setter is protected internal now, AfterItemAdd event is public

    client-side Ext.net.TreePanel's createNode
    fixed, it was very old code, i updated it to support another node types

    Thanks for your suggestion and feedback
    Vladimir Shcheglov
    Sr. Developer
  5. #5
    Quote Originally Posted by r_honey View Post
    In my understanding, this is done to overcome issues with co-variance and contra-variance in overriding (which are not permissible in C# n overriding scenarios). e.g. this prevents issues in overriding the Listeners property where Panel would have PanelListeners but Window would have WindowListeners.

    Is this correct?
    No I don't think that is correct. The reason we inherit Child Components from a common Base class is to work-around a defect in the ASP.NET runtime (and DesignTime?) parser.

    Parser Error Message: Ambiguous match found.
    Yep, thats the one.
    Geoffrey McGill
    Founder & CEO
  6. #6
    Quote Originally Posted by r_honey View Post
    I then approached to extend TreeNodeBase, but to my surprise, ParentNode setter is internal (it should have been protected atleast), AfterItemAdd event for StateManagedCollection is internal. I am having some heart-burn currently.
    In general, if you find a property that is "private" and you feel should be "public" or "protected", you're probably correct. As a general rule, everything should be override-able.

    In this case, I think setting as "private" was just an oversight/defect.
    Last edited by geoffrey.mcgill; Jan 02, 2012 at 10:57 AM.
    Geoffrey McGill
    Founder & CEO
  7. #7
    Quote Originally Posted by r_honey View Post
    I wonder whether Ext.Net components have really been designed for extending and inheritance.
    The whole structure of the library is based on deep inheritance. Some of the Components are seven levels down. Everything is inherited from something else.

    The problems with direct inheritance of some Components is noted above (ASP.NET parser).
    Geoffrey McGill
    Founder & CEO
  8. #8
    Thanks vlad and geoff for your replies.

    Quote Originally Posted by vladimir View Post
    Well, I can suggest one workaround (just not sure if it is acceptable for you), you can add additional listeners property, like ExtnededListeners, and set serialization name as "listeners" (in this case, do not use standard listeners). As you see it is not very good solution but it can solve that problem
    I was using almost similar thing. I extended TreeNodeListeners, and created an entirely new property with all the listeners. But now I think your approach is more suitable. Leave the existing Listeners as such and add custom events as ExtendedListeners. So, I have updated my code as following:

    	public class PortalTreeNodeListeners : ComponentListeners
    	{
    		private ComponentListener load;
    
    		/// <summary>
    		/// Fires when the child nodes need to be loaded
    		/// </summary>
    		[ListenerArgument(0, "node")]
    		[TypeConverter(typeof(ExpandableObjectConverter))]
    		[ConfigOption("beforechildrenrendered", typeof(ListenerJsonConverter))]
    		[PersistenceMode(PersistenceMode.InnerProperty)]
    		[NotifyParentProperty(true)]
    		[Description("Fires when the child nodes need to be loaded")]
    		public virtual ComponentListener Load
    		{
    			get
    			{
    				if (this.load == null)
    				{
    					this.load = new ComponentListener();
    				}
    
    				return this.load;
    			}
    		}
    	}
    
    	public class PortalTreeNode : TreeNode
    	{
    		private PortalTreeNodeListeners extendedListeners;
    
    		/// <summary>
    		/// Client-side JavaScript Event Handlers
    		/// </summary>
    		[ConfigOption("listeners", JsonMode.Object)]
    		[Category("2. Observable")]
    		[NotifyParentProperty(true)]
    		[PersistenceMode(PersistenceMode.InnerProperty)]
    		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    		[ViewStateMember]
    		[Description("Client-side JavaScript Event Handlers")]
    		public new PortalTreeNodeListeners ExtendedListeners
    		{
    			get
    			{
    				if (this.extendedListeners == null)
    				{
    					this.extendedListeners = new PortalTreeNodeListeners();
    				}
    
    				return this.extendedListeners;
    			}
    		}
    	}
    Can you please confirm if this seems suitable??
  9. #9
    Hi,

    Well, I guess that PortalTreeNodeListeners must be inherited from TreeNodeListeners because you cannot use ExtendedListeners and Listeners at one time (because Listeners and ExtendedListeners are serialized to the "listeners" and you cannot have two "listeners" object in the json object)
    Vladimir Shcheglov
    Sr. Developer
  10. #10
    Quote Originally Posted by Vladimir View Post
    Hi,

    Well, I guess that PortalTreeNodeListeners must be inherited from TreeNodeListeners because you cannot use ExtendedListeners and Listeners at one time (because Listeners and ExtendedListeners are serialized to the "listeners" and you cannot have two "listeners" object in the json object)
    Hmm... Okay I will see that way now... Thanks!!!

Similar Threads

  1. [CLOSED] Overriding the tab close icon click
    By RCM in forum 1.x Premium Help
    Replies: 1
    Last Post: Jun 26, 2012, 3:25 PM
  2. Replies: 3
    Last Post: Aug 06, 2009, 2:06 PM
  3. [CLOSED] Overriding Button Templates
    By UGRev in forum 1.x Premium Help
    Replies: 3
    Last Post: Dec 12, 2008, 12:36 PM
  4. [CLOSED] Overriding a ClientConfig default value
    By jchau in forum 1.x Premium Help
    Replies: 3
    Last Post: Nov 12, 2008, 10:21 AM
  5. Extending Ext Components and Coolite
    By jchau in forum Open Discussions
    Replies: 1
    Last Post: Aug 14, 2008, 11:35 AM

Tags for this Thread

Posting Permissions