1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Custom Module - 3.6 Upgrade Issue

Custom Module - 3.6 Upgrade Issue

11 posts, 0 answered
  1. Adam
    Adam avatar
    63 posts
    Registered:
    30 Jan 2008
    19 Mar 2009
    Link to this post
    I have a custom module in a project site that I just recently upgraded to 3.6.  The Built-in modules all appear to be working correctly, but the custom module has been giving the error that the Required Controls within the .ascx files are not found.  There are probably 20 .ascx files being used by this custom module. 

    Did I miss a web.config setting that is needed to let the custom module find its .ascx template files?   The .ascx file locations are the same as they were before the upgrade.

    Adam
  2. Adam
    Adam avatar
    63 posts
    Registered:
    30 Jan 2008
    19 Mar 2009
    Link to this post
    After further research....

    Some of the custom module controls are working.  I'm using base.FindRequiredControl<Repeater>("ControlName");   to load the controls... this appears to be unable to parse through nested controls to find the child as it did before the 3.6 upgrade.   That's just my best guess right now.

    Adam
  3. Adam
    Adam avatar
    63 posts
    Registered:
    30 Jan 2008
    19 Mar 2009
    Link to this post
    I found a fix but I don't understand why this is different from 3.5 SP1 to 3.6 w/ Hotfix.   In all my custom modules I had grouped together the ObjectDataSource with the controls that used it.  I had to move adding the object data source to just before adding the container to the Controls collection to fix this issue.  For some reason... adding the Object data source caused the template to lose its knowledge of any other controls already part of the template.  

  4. Ivan
    Ivan avatar
    478 posts
    Registered:
    16 Jun 2015
    20 Mar 2009
    Link to this post
    Hello Adam,

    first of all, we are glad you've managed to fix your problem.

    We'd also be interested to see the class which caused you problems, since the behavior is not expected and we'd like to investigate it further. We'd be very thankful if you could send us the code.

    Best wishes,
    Ivan
    the Telerik team


    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  5. Adam
    Adam avatar
    63 posts
    Registered:
    30 Jan 2008
    20 Mar 2009
    Link to this post
    Ivan,

    This error seemed to be fairly consistent.  The problem was in my CreateChildControls() method.  If I programmatically created an Object Data Source, added it to the container, and after adding it I referenced any existing control in the container's properties it would give me a control not found error, unless I had referenced that control before adding the Object Data Source to the container.

    Here's an example of code that would fail:

    protected override void CreateChildControls()  
    {  
      container = new PublicControlContainer(this);  
      LayoutTemplate.InstantiateIn(container);  
     
      ObjectDataSource TestODS = new ObjectDataSource();  
      testODS.ID = "TestODS";  
      testODS.TypeName = "CustomModule.Manager";  
      testODS.SelectMethod = "SelectItemsMethod";  
     
      container.Controls.Add(testODS);  
     
      // Error will be caused by this line that states the  
      // required contral testGridView could not be found.  
      container.testGridView.DataSourceID = testODS.ID;  
      container.testGridView.DataBound += new EventHandler(testGridView_DataBound);  
     
      Controls.Add(container);  
    }  
     
    private class PublicControlContainer : GenericContainer<CustomModule> 
    {  
      public PublicControlContainer(CustomModule owner) : base(owner) { }  
     
      private GridView _testGridView;  
      public GridView testGridView  
      {  
        get   
        {  
          if (_testGridView == null)  
          {  
            _testGridView = base.FindRequiredControl<GridView>("testGridView");  
          }  
          return _testGridView;  
        }  
      }  
    }  
     

    Moving one line of code would get rid of the error:

    protected override void CreateChildControls()  
    {  
      container = new PublicControlContainer(this);  
      LayoutTemplate.InstantiateIn(container);  
     
      ObjectDataSource TestODS = new ObjectDataSource();  
      testODS.ID = "TestODS";  
      testODS.TypeName = "CustomModule.Manager";  
      testODS.SelectMethod = "SelectItemsMethod";  
     
      container.testGridView.DataSourceID = testODS.ID;  
      container.testGridView.DataBound += new EventHandler(testGridView_DataBound);  
     
      // Moving this line below the reference above of the testGridView  
      // would prevent the required control missing error.  Instead of moving   
      // this line to the end I could have also just referenced the testGridView  
      // once before adding this ObjectDataSource, but I would have to reference  
      // all of the controls at least once before adding to the container to prevent  
      // the error from happening for any of the other container controls from the  
      // class definition.  
      container.Controls.Add(testODS);  
     
      Controls.Add(container);  
    }  
     
    private class PublicControlContainer : GenericContainer<CustomModule> 
    {  
      public PublicControlContainer(CustomModule owner) : base(owner) { }  
     
      private GridView _testGridView;  
      public GridView testGridView  
      {  
        get   
        {  
          if (_testGridView == null)  
          {  
            _testGridView = base.FindRequiredControl<GridView>("testGridView");  
          }  
          return _testGridView;  
        }  
      }  
    }  
     

    Let me know if you need any more info.

    Thanks,
    Adam

  6. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    24 Mar 2009
    Link to this post
    Hi Adam,

    The changes in the architecture are in fact causing you the issues.

    There is no more need to override the CreateChildControls on Initialize. There is no container class as well. If you want to get a reference to the controls, you should be getting it from the Views. The following articles would be helpful for you:
    Let me know if you need any further information.
    All the best,
    Georgi
    the Telerik team

    Check out Telerik Trainer , the state of the art learning tool for Telerik products.
  7. David Meyer
    David Meyer avatar
    13 posts
    Registered:
    29 Oct 2009
    08 Dec 2009
    Link to this post
    I'm using the Sitefinity pluggable module to add a public control and an admin module page. My public control is a Contact Us form. I set the template, set it in the container, but it doesnt  show the content of my form. In the sample you have this:

    /// <summary> 
    /// Container class with helper methods for working with controls inside of 
    /// a template 
    /// </summary> 
    private class PublicControlContainer : GenericContainer<ContactUsPublicControl> 
        public PublicControlContainer(ContactUsPublicControl owner) 
            : base(owner) 
        { 
     
        } 
     
        /// <summary> 
        /// Property which returns the reference to the DataRepeater Repeater 
        /// inside of SamplePublicControl template 
        /// </summary> 
        public Repeater DataRepeater 
        { 
            get 
            { 
                if (dataRepeater == null) 
                    dataRepeater = FindRequiredControl<Repeater>("dataRepeater"); 
                return dataRepeater; 
            } 
        } 
     
        private Repeater dataRepeater; 

    Do I need to do something like this to load in each form element and call that code in the CreateChildControls() override, just after Controls.Add(container)? Or is there a way to load the whole ascx at once?
    Thanks
    David

  8. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    08 Dec 2009
    Link to this post
    Hello David Meyer,

    You can give a try to the following code:

    private class PublicControlContainer : GenericContainer<ContactUsPublicControl>
    {
        public PublicControlContainer(ContactUsPublicControl owner)
            : base(owner)
        {
        }
     
     
     
        public Repeater DataRepeater
        {
            get
            {
                if (this.dataRepeater == null)
                    this.dataRepeater = (Repeater)base.FindRequiredControl<Repeater>("dataRepeater");
                return dataRepeater;
            }
        }
     
     
    }
    private PublicControlContainer container;
    private Repeater dataRepeater;

    Then you should be able to access the control from the container  - container.DataRepeater. Whether you are going to add the container depends on the implementation you have. Generally this is done inside CreateChildcontrols method

    sample:

    protected override void CreateChildControls()
    {
     // subcribe for some events and then add the container, not before that
     //
       this.Controls.Add(this.container);
    }

    Kind regards,

    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  9. David Meyer
    David Meyer avatar
    13 posts
    Registered:
    29 Oct 2009
    08 Dec 2009
    Link to this post
    Thanks for the response. I did see this code, but since I'm not repeating anything so I dont need a repeater. Is there one control that my ascx  markup can sit inside? should I just put my markup inside the repeater to use it as a container? I thought by setting LayoutTemplatePath to my ascx that holds the markup for my Contact Us page, that would be what is rendered in the public control.
  10. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    08 Dec 2009
    Link to this post
    Hi David Meyer,

    You use LayoutTemplatePath to create reference to the template. The container is used to create reference to the controls from your templates and remove the pain controls searching with recursion. As far as I see from your code you have even set the control as required. So, if you want to manipulate the control DataRepeater, you should better use the container. If you are not going to use this control, just remove it from the container.


    All the best,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  11. David Meyer
    David Meyer avatar
    13 posts
    Registered:
    29 Oct 2009
    08 Dec 2009
    Link to this post
    I was just using that code as an example, like I said Im not going to actually use a repeater. I see you load one, but do I also need to load each html element in my ascx? I wouldnt think so...I thought I'd be able to load my ascx control via the LayoutTemplatePath and be done.
Register for webinar
11 posts, 0 answered