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

Forums / Developing with Sitefinity / communication between custom controls

communication between custom controls

13 posts, 0 answered
  1. Christopher
    Christopher avatar
    22 posts
    Registered:
    09 Jun 2008
    19 Aug 2008
    Link to this post
    Hello,

    Is there is a recommended way to allow user controls on a page to interact. As far as I can tell, since pages are created dynamically, controls on the same page can't communicate. There are couple ways that I know how to make this happen: raising an event, using findcontrol or using web parts, but from what I know these methods won't work since there is no access to the page or it's code behind. Please let me know if there is a way to accomplish this.

    Example:

    LoginControl (Custom Control)
    StatusControl (Custom Control)

    When the user logs in using the LoginControl, the StatusControl should immediately update to say something like you are logged in...

    Thanks
    Chris
  2. Ivan
    Ivan avatar
    478 posts
    Registered:
    16 Jun 2015
    20 Aug 2008
    Link to this post
    Hi Christopher,

    For the example you have gave, the much simpler way is to use standard ASP.NET LoginStatus and Login control which will do the job without having to hook them up.

    For more general scenarios, you can use events. While you don't have a page code behind, you can look for one control from another control. For your given example, you could find LoginControl from the StatusControl (you would be using a recursive version of Page.FindControl method) and then subscribe to an event of LoginControl in case it is found.

    Also, when creating templates from masterpages - you can upload code behind for master pages.

    I hope you'll find this information helpful. Let us know if there is anything else we can do for you.

    Kind regards,
    Ivan
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  3. Christopher
    Christopher avatar
    22 posts
    Registered:
    09 Jun 2008
    20 Aug 2008
    Link to this post
    Hi Ivan,

    Thanks for replying to my post.

    The only problem I'm having with your suggestion of using Page.FindControl("id") and then subscribing to  the event is that I believe you need access to the control's type.. i.e.

    dim uc1 as UserControl1

    UserControl1 type is not in scope of another independent usercontrol (UserControl2)

    * The only thing I can think to do would be to actually put another UserControl1 into UserControl2 and just make in not visible. Then you would be able to declare a reference of type UserControl1. That doesn't seem like good practice though so let me know I'm overlooking something.

    Thanks again,
    Chris

  4. Adam @Habanero
    Adam @Habanero avatar
    45 posts
    Registered:
    22 Jun 2012
    20 Aug 2008
    Link to this post
    Instead of using a User Control, you may want to use a Custom Control.  They are strongly typed and easier to reference.
  5. Christopher
    Christopher avatar
    22 posts
    Registered:
    09 Jun 2008
    22 Aug 2008
    Link to this post
    This is more of a programming issue rather than a Sitefinity specific issue, but I thought I would post another suggestion that was offered to me in case anyone is interested. You can use a combination of the page's context object to store some known key value pairs inside the provider control.

    On ControlOne event occuring:
    Context.Items("ControlOneStatus") =  "Updated"

    And then in the subscribing control's  prerender method you can access the context value and have the control visually update.

    ControlTwo PreRender method:

        Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender 
            If Context.Items("ControlOneStatus") IsNot Nothing Then 
                Label1.Text = Context.Items("ControlOneStatus").ToString 
            End If 
        End Sub 
  6. Philip Senechal
    Philip Senechal avatar
    69 posts
    Registered:
    07 Apr 2008
    29 Jul 2010
    Link to this post
    Sorry to dig up such an old post, but I posted a question over on the Telerik forums and though that this might be a better place to ask the question since it relates directly to this post.

    Can you explain how the reference would work in the code behind to do a recursive version of Page.FindControl method?

    My scenario is that I have a Sitefinity page that has 2 user controls on it. I have a RadGrid in one of the user controls that I need to be able to access from the other user control. The RadGrid is in edit mode, so I need to be able to fire off the Update Command from the other user control. I figured out how to fire off the Update Command, I just can't figure out how to gain reference to the RadGrid. Can you help me out? Thanks.
  7. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    29 Jul 2010
    Link to this post
    Hi Philip Senechal,

    Get reference to the page and from the staged controls collection you can find the RadGrid

    IList<Telerik.Cms.ICmsWebControl> pageControls = currentPage.Staged.Controls;
    foreach (Telerik.Cms.ICmsWebControl webCtrl in pageControls)
    {
     if (webCtrl.ContainerID == "SideBarContent" && webCtrl.ControlType == typeof(RadGrid))
     {
         
         RadGrid grid = webCtrl.LoadControl() as RadGrid;
          
          
     }
    }


    If you use nested controls you can use Recursion

    private Control FindControlRecursive(Control root, string id)
       {
           if (root.ID == id)
           {
               return root;
           }
     
           foreach (Control c in root.Controls)
           {
               Control t = FindControlRecursive(c, id);
               if (t != null)
               {
                   return t;
               }
           }
     
           return null;
       }

    You can also create a custom container


    public class MyContainer : GenericContainer
           {
     
               public RadGrid Grid
               {
                   get
                   {
                       if (rg== null)
                           rg= base.GetControl<RadGrid >("RadGrid1", true, TraverseMethod.DepthFirst );
                       return rg;
                   }
               }
     
               private RadGrid rg;
           }


    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  8. Philip Senechal
    Philip Senechal avatar
    69 posts
    Registered:
    07 Apr 2008
    29 Jul 2010
    Link to this post
    Hi Ivan,

    Thanks for the quick response. I think I'm just about there, but had a couple small questions...

    I used your first suggestion and interpreted your use of currentPage to be an extension of something I found elsewhere...

    CmsManager manager = new CmsManager();
    IList allPages = manager.GetPages();
    foreach (ICmsPage page in allPages)
    {
        ICmsPage currentPage = (ICmsPage)manager.GetPage(page.ID, true);
    }

    Let me know if this is correct to get the currentPage object you referenced in your code.

    I then added the rest of what you sent and ended up with this block of code...

    CmsManager manager = new CmsManager();
    IList allPages = manager.GetPages();
    foreach (ICmsPage page in allPages)
    {
        ICmsPage currentPage = (ICmsPage)manager.GetPage(page.ID, true);
     
        IList<Telerik.Cms.ICmsWebControl> pageControls = currentPage.Staged.Controls;
        foreach (Telerik.Cms.ICmsWebControl webCtrl in pageControls)
        {
            if (webCtrl.ContainerID == "RadGrid1" && webCtrl.ControlType == typeof(RadGrid))
            {
                RadGrid grid = webCtrl.LoadControl() as RadGrid;
                (grid.SelectedItems[0] as GridDataItem).FireCommandEvent(RadGrid.UpdateCommandName, string.Empty);
            }
        }
    }

    While I don't get any errors, nothing happens which I'm assuming is because of the ContainerID. I'm not sure what this ContainerID is referring to. It doesn't seem like it's the RadGrid ID or the user control namespace.

    Can you let me know what this is supposed to be the ID of? Thanks again for the assistance!
  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    29 Jul 2010
    Link to this post
    Hi Philip Senechal,

    ContainerID  refers to the ContentPlaceHolder where you have added your RadGrid control. You could attach the VS debugger on the if bracket where you check the ControlType to see whether your control has been found. currentPage.Staged.Controls should return you all controls on the page. You can call .Count and check each index to see whether actually is your control.

    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  10. Philip Senechal
    Philip Senechal avatar
    69 posts
    Registered:
    07 Apr 2008
    29 Jul 2010
    Link to this post
    That makes a lot more sense, but I'm still trying to figure out how to get to the RadGrid. When I use "LeftContent" for the container ID, it gets me the contentplaceholder where the RadGrid is contained. If I bring back the type for webCtrl when I specify a container ID of "LeftContent", I get Telerik.Cms.Data.CmsWebControl, not RadGrid, which makes sense since that's what it is.

    So right now I have webCtrl which is the contentplaceholder where the RadGrid is contained, but I can't figure out how to get down one more step to the RadGrid which is in that contentplaceholder. FindControl isn't an available method for webCtrl at this point. Do I maybe need to do another foreach loop through webCtrl to look at the controls within it and try to find the RadGrid id?

    I'm getting so close and I know there's something really simple I'm just not understanding. Thanks for bearing with me on this.
  11. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    29 Jul 2010
    Link to this post
    Hello Philip Senechal,

    You should get the RadGrid, because you cast the ICmsWebControl to RadGrid

     RadGrid grid = webCtrl.LoadControl() as RadGrid;

    another option is to load the control first as Control and then cast it, but it is the same

    if (webCtrl.ContainerID == "LeftContent" && webCtrl.ControlType == typeof(RadGrid))
    {
        Control v = webCtrl.LoadControl(this.Page);
        RadGrid mycontrol = v as RadGrid;
    }


    Regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  12. Philip Senechal
    Philip Senechal avatar
    69 posts
    Registered:
    07 Apr 2008
    29 Jul 2010
    Link to this post
    This is the part that I'm not able to get past

    if (webCtrl.ContainerID == "LeftContent" && webCtrl.ControlType == typeof(RadGrid))

    the code within this IF statement never gets executed. If I remove the second part of the IF statement and just qualify on the ContainerID, I can get the code within the IF statement to run, but adding the ControlType qualifier causes this IF statement to return false.

    Perhaps it's the way I have my contentplaceholder and the user control defined that is different from what this code would work for. My contentplaceholder is in a master page and looks pretty standard...

    <asp:ContentPlaceHolder ID="LeftContent" runat="server" />

    Within Sitefinity, I'm dropping a User Control into that contentplaceholder that looks like this

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="RequestL.ascx.cs" Inherits="UserControls_EIS_RequestL" %>
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
     
    <telerik:RadGrid ID="RadGrid1">
        GRID CODE
    </telerik:RadGrid>

    Were you maybe thinking I was dropping a RadGrid directly into the contentplaceholder? The RadGrid is actually in a User Control and I'm dropping the User Control into the contentplaceholder.

    Let me know if that changes anything in your mind about how this should work. Thanks again!
  13. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    30 Jul 2010
    Link to this post
    Hello Philip Senechal,

    Thank you for getting back to us.

    Your control will not be of type RadGrid - the grid is nested within a user cotnrol. The control would be of type:
    ASP.UserControls_EIS_RequestL_ascx which is the container of your grid. You can double check this by using this snippet which outputs all controls on the page and their types:
    protected void Page_Load()
    {
        // find the sitemap node of the current page
        Telerik.Cms.Web.CmsSiteMapNode currentNode = (Telerik.Cms.Web.CmsSiteMapNode)SiteMap.CurrentNode;
        // get the CmsPage associated with the current node
        Telerik.Cms.ICmsPage currentPage = currentNode.CmsPage;
        // we are going to use Controls collection of a staged version of a page to
        // access all controls of current page
        System.Collections.Generic.IList<Telerik.Cms.ICmsWebControl> pageControls = currentPage.Staged.Controls;
        foreach (Telerik.Cms.ICmsWebControl webCtrl in pageControls)
        {
            // let's write out some basic info on each control of this page
            string ctrlInfo = String.Concat("Control ID = ", webCtrl.ID,
                                            ", Control type = ", webCtrl.ControlType,
                                            ", Container ID = ", webCtrl.ContainerID,
                                            ", Is UserControl = ", webCtrl.IsAscx);
            Response.Write(ctrlInfo + "<br />");
        }
    }

    Regards,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Register for webinar
13 posts, 0 answered