HOWTO: Create Snaps on the server in Web.UI 2007.1

This post has 15 replies

Top 10 Contributor
Posts: 6,424
hwan Posted: Mon Oct 15, 2007 @ 12:31 PM | Locked

In Web.UI 2007.1 we deprecated the old templated approach to creating Snaps. Here is a version of the "Runtime Instantiation" demo, modified to use both the old and new method of creating Snap controls on the server.

Note: A minor bug requires one to clear out the default Snap content and give them explicit IDs. This should be fixed in an upcoming build.

 

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using ComponentArt.Web.UI; 

namespace RuntimeSnapInstantiation
{
  public class WebForm1 : System.Web.UI.Page
  {
    protected ComponentArt.Web.UI.Snap Snap1; 
    protected ComponentArt.Web.UI.Snap Snap2; 
    protected System.Web.UI.WebControls.PlaceHolder PlaceHolder1; 
  
    private void Page_Load(object sender, System.EventArgs e)
    {
      createSnapInstances(); 
    }

  private void createSnapInstances()
  {
    /* Snap1, using new method */
    Snap1 = new ComponentArt.Web.UI.Snap(); 

    Snap1.ID = "Snap1"; 
    Snap1.DockingContainers = "LeftColumn,RightColumn"; 
    Snap1.CurrentDockingContainer = "LeftColumn";
    Snap1.CurrentDockingIndex = 0;

    Snap1.Controls.Clear();  // remove default SnapHeader/SnapContent

        SnapContent snapHeader = new SnapContent();
        snapHeader.ID = "HeaderSpan";  // need to give explicit ID to avoid minor bug in 2007.1
        snapHeader.Controls.Add(GetHeaderControl("Snap1", "Page Options"));
        Snap1.Controls.Add(snapHeader);
    Snap1.Header = snapHeader;

        SnapContent snapContent = new SnapContent();
        snapContent.ID = "InnerSpan";  // need to give explicit ID to avoid minor bug in 2007.1
    UserControl uc1 = (UserControl)Page.LoadControl("PageOptions.ascx"); 
        snapContent.Controls.Add(uc1);
    Snap1.Controls.Add(snapContent);
        Snap1.Content = snapContent;

    SnapContent snapFooter = new SnapContent();
        snapFooter.ID = "FooterSpan";  // need to give explicit ID to avoid minor bug in 2007.1
    UserControl uc2 = (UserControl)Page.LoadControl("Footer.ascx"); 
    snapFooter.Controls.Add(uc2);
    Snap1.Controls.Add(snapFooter);
    Snap1.Footer = snapFooter;

    PlaceHolder1.Controls.Add(Snap1); 


    /* Snap2, using old deprecated method */
    Snap2 = new ComponentArt.Web.UI.Snap(); 

    Snap2.ID = "Snap2"; 
    Snap2.DockingContainers = "LeftColumn,RightColumn"; 
    Snap2.CurrentDockingContainer = "LeftColumn";
    Snap2.CurrentDockingIndex = 1;
    SnapHeader Header2 = new SnapHeader(); 
    Header2.Title = "Developer Tools"; 
    Header2.SnapID = "Snap2"; 
    Snap2.HeaderTemplate = Header2; 
    Snap2.ContentTemplate = Page.LoadTemplate("DeveloperTools.ascx"); 
    Snap2.FooterTemplate = Page.LoadTemplate("Footer.ascx"); 
    PlaceHolder1.Controls.Add(Snap2); 
  }

  #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
      //
      // CODEGEN: This call is required by the ASP.NET Web Form Designer.
      //
      InitializeComponent();
      base.OnInit(e);    
    }
  
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {    
      this.Load += new System.EventHandler(this.Page_Load);
    }
  #endregion


/* older Snaps required the usage of an Itemplate class object */
  public class SnapHeader : ITemplate
  {
    public string SnapID; 
    public string Title; 

    public void InstantiateIn(Control container)
    {
      Literal L1 = new Literal(); 
      L1.Text = "<div style=\"CURSOR: move; width: 100%;\"><table cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">";
      L1.Text += "<tr><td class=\"SnapHeader\" onmousedown=\"" + SnapID + ".startDragging(event);\">" + Title + "</td>";
      L1.Text += "<td width=\"10\" style=\"cursor: hand\" align=\"right\"><img onclick=\"" + SnapID + ".toggleExpand();\" src=\"images/i_open.gif\" width=\"22\" height=\"19\" border=\"0\"></td>";
      L1.Text += "</tr></table></div>";
      container.Controls.Add(L1); 
    }
  }

/* new Snaps use control */
    private Control GetHeaderControl(string SnapID, string Title)
    {
      Literal L1 = new Literal(); 
      L1.Text = "<div style=\"CURSOR: move; width: 100%;\"><table cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">";
      L1.Text += "<tr><td class=\"SnapHeader\" onmousedown=\"" + SnapID + ".startDragging(event);\">" + Title + "</td>";
      L1.Text += "<td width=\"10\" style=\"cursor: hand\" align=\"right\"><img onclick=\"" + SnapID + ".toggleExpand();\" src=\"images/i_open.gif\" width=\"22\" height=\"19\" border=\"0\"></td>";
      L1.Text += "</tr></table></div>";
      return L1;
    }
  }
}

Top 500 Contributor
Posts: 26
dglover Posted: Wed Dec 5, 2007 @ 10:35 AM
Do you have this in VB?
Top 10 Contributor
Posts: 6,424
hwan Posted: Wed Dec 5, 2007 @ 3:04 PM

Interestingly enough, I do. Enjoy!

Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports ComponentArt.Web.UI

Namespace RuntimeSnapInstantiation

  Public Class WebForm1
      Inherits System.Web.UI.Page
    Protected Snap1 As ComponentArt.Web.UI.Snap
    Protected Snap2 As ComponentArt.Web.UI.Snap
    Protected PlaceHolder1 As System.Web.UI.WebControls.PlaceHolder

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      createSnapInstances()
    End Sub

    Private Sub createSnapInstances()

    ' Snap1, using new method
    Snap1 = New ComponentArt.Web.UI.Snap()

    Snap1.ID = "Snap1"
    Snap1.DockingContainers = "LeftColumn,RightColumn" 
    Snap1.CurrentDockingContainer = "LeftColumn"
    Snap1.CurrentDockingIndex = 0

    Snap1.Controls.Clear()  'Remove default SnapHeader/SnapContent

    Dim snapHeader As New SnapContent()
    snapHeader.ID = "HeaderSpan"  ' need to give explicit ID to avoid minor bug in 2007.1
    snapHeader.Controls.Add(GetHeaderControl("Snap1", "Page Options"))
    Snap1.Controls.Add(snapHeader)
    Snap1.Header = snapHeader

    Dim snapContent As New SnapContent()
    snapContent.ID = "InnerSpan"  ' need to give explicit ID to avoid minor bug in 2007.1
    Dim uc1 As UserControl = Page.LoadControl("PageOptions.ascx") 
    snapContent.Controls.Add(uc1)
    Snap1.Controls.Add(snapContent)
    Snap1.Content = snapContent

    Dim snapFooter As New SnapContent()
    snapFooter.ID = "FooterSpan"  ' need to give explicit ID to avoid minor bug in 2007.1
    Dim uc2 As UserControl = Page.LoadControl("Footer.ascx") 
    snapFooter.Controls.Add(uc2)
    Snap1.Controls.Add(snapFooter)
    Snap1.Footer = snapFooter

    PlaceHolder1.Controls.Add(Snap1) 


' Old version
      Dim Snap2 As New ComponentArt.Web.UI.Snap
      Snap2.ID = "Snap2"
      Snap2.DockingContainers = "LeftColumn,RightColumn"
      Snap2.CurrentDockingContainer = "LeftColumn"
      Dim Header2 As New SnapHeader
      Header2.Title = "Developer Tools"
      Header2.SnapID = "Snap2"
      Snap2.HeaderTemplate = Header2
      Snap2.ContentTemplate = Page.LoadTemplate("DeveloperTools.ascx")
      Snap2.FooterTemplate = Page.LoadTemplate("Footer.ascx")
      PlaceHolder1.Controls.Add(Snap2)
    End Sub 


  #Region " Web Form Designer Generated Code "

      'This call is required by the Web Form Designer.
      <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

      End Sub

      Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
   'CODEGEN: This method call is required by the Web Form Designer
   'Do not modify it using the code editor.
   InitializeComponent()
      End Sub


' New Snaps use control
    Private Function GetHeaderControl(ByVal SnapID As String, ByVal Title As String) As Control
      Dim L1 As New Literal
      L1.Text = "<div style=""CURSOR: move; width: 100%;""><table cellSpacing=""0"" cellPadding=""0"" width=""100%"" border=""0"">"

      L1.Text = L1.Text & "<tr><td class=""SnapHeader"" onmousedown=""" + SnapID + ".startDragging(event);"">" + Title + "</td>"

      L1.Text = L1.Text & "<td width=""10"" style=""cursor: hand"" align=""right""><img onclick=""" + SnapID + ".toggleExpand();"" src=""images/i_open.gif"" width=""22"" height=""19"" border=""0""></td>"

      L1.Text = L1.Text & "</tr></table></div>"
      Return L1
    End Function

  #End Region

  End Class


' Older Snaps required the usage of an Itemplate class object
  Public Class SnapHeader 
    Implements ITemplate
    
    Public SnapID As String 
    Public Title As String 

    Public Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn
      Dim L1 As New Literal
      L1.Text = "<div style='CURSOR: move; width: 100%;'><table cellSpacing='0' cellPadding='0' width='100%' border='0'>"
      L1.Text = L1.Text & "<tr><td class='SnapHeader' onmousedown='" & SnapID & ".startDragging(event);'>" & Title & "</td>"
      L1.Text = L1.Text & "<td width='10' style='cursor: hand' align='right'><img onclick='" & SnapID & ".toggleExpand();' src='images/i_open.gif' width='22' height='19' border='0'></td>"
      L1.Text = L1.Text & "</tr></table></div>"
      container.Controls.Add(L1)
    End Sub     
  End Class 

End Namespace 

Top 150 Contributor
Posts: 47
andrewhore Posted: Mon Nov 3, 2008 @ 7:17 AM
OK, this helped a lot...still not got the examples updated yet or the documentation....that is pretty poor.

Anyway, I need to take this one step further and have different expanded and collapsed headers. So, I guessed that the following would be the way to go:

        Dim snapCollapsedHeader As New SnapContent()
        snapCollapsedHeader.ID = "HeaderCollapsedSpan"  ' need to give explicit ID to avoid minor bug in 2007.1
        snapCollapsedHeader.Controls.Add(GetCollapsedHeaderControl(ID, Title))
        Snap.Controls.Add(snapCollapsedHeader)
        Snap.CollapsedHeader = snapCollapsedHeader

Unfortunately, when I do this I get the expanded header TWICE, with the collapse icon working, just not changing:( Any help with this?

Thanks,
Andy.
Top 10 Contributor
Posts: 6,424
hwan Posted: Thu Nov 13, 2008 @ 11:26 AM
This appears to be a bug -- defining a CollapsedHeader on the server is not properly recognized as such. As you noticed, it simply tacks it on to the existing header. I will notify the developers of this bug.
Not Ranked
Posts: 1
MikeStahr Posted: Tue Jan 13, 2009 @ 2:20 PM
Thanks for the post - this is great!
Top 500 Contributor
Posts: 21
hichame Posted: Tue Jun 30, 2009 @ 2:22 AM
Hi,

Has this problem been solutioned ? I have the 2008.2 version and I still have the problem that the header is being rendered twice.

Any solution ?
Top 10 Contributor
Posts: 6,424
hwan Posted: Tue Jun 30, 2009 @ 1:11 PM
Ok, I've asked the developers to increase the priority of a fix for D5861 "Defining a CollapsedHeader on the server is appended to existing header".
Not Ranked
Posts: 10
matt@builtwith.net Posted: Tue Jul 14, 2009 @ 12:18 AM
Any news on this bug (D5861)? The post outlining the bug is now 8 months old and I'm assuming this bug has been present from version 2007.1 and still exists in 2009.1.

I dynamically create 2 SnapContents, one assigned to Header, the other to CollapsedHeader but they both render.
Top 10 Contributor
Posts: 6,424
hwan Posted: Fri Jul 24, 2009 @ 12:59 PM
Still in effect, I'm afraid, but a good candidate for SP1 of 2009.2.
Not Ranked
Posts: 13
srtech Posted: Wed Sep 9, 2009 @ 2:17 AM
is there a suggested workaround for this?
Top 10 Contributor
Posts: 6,424
hwan Posted: Thu Sep 17, 2009 @ 12:28 PM

I just tested this with Web.UI 2009.2.1509 and the bug appears to have been since fixed. Here's the code I used:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using ComponentArt.Web.UI; 

namespace RuntimeSnapInstantiation
{
  public class WebForm1 : System.Web.UI.Page
  {
    protected ComponentArt.Web.UI.Snap Snap1; 
    protected ComponentArt.Web.UI.Snap Snap2; 
    protected System.Web.UI.WebControls.PlaceHolder PlaceHolder1; 
  
    private void Page_Load(object sender, System.EventArgs e)
    {
      createSnapInstances(); 
    }

  private void createSnapInstances()
  {
    /* Snap1, using new method */
    Snap1 = new ComponentArt.Web.UI.Snap(); 

    Snap1.ID = "Snap1"; 
    Snap1.DockingContainers = "LeftColumn,RightColumn"; 
    Snap1.CurrentDockingContainer = "LeftColumn";
    Snap1.CurrentDockingIndex = 0;

    Snap1.Controls.Clear();  // remove default SnapHeader/SnapContent

        SnapContent snapHeader = new SnapContent();
        snapHeader.ID = "HeaderSpan";  // need to give explicit ID to avoid minor bug in 2007.1
        snapHeader.Controls.Add(GetHeaderControl("Snap1", "Page Options", "images/i_open.gif"));
        Snap1.Controls.Add(snapHeader);
    Snap1.Header = snapHeader;

  SnapContent snapCollapsedHeader = new SnapContent();
  snapCollapsedHeader.ID = "CollapsedHeaderSpan";  // need to give explicit ID to avoid minor bug in 2007.1
  snapCollapsedHeader.Controls.Add(GetHeaderControl("Snap1", "Page asdf Options", "images/i_closed.gif"));
  Snap1.Controls.Add(snapCollapsedHeader);
    Snap1.CollapsedHeader = snapCollapsedHeader;

        SnapContent snapContent = new SnapContent();
        snapContent.ID = "InnerSpan";  // need to give explicit ID to avoid minor bug in 2007.1
    UserControl uc1 = (UserControl)Page.LoadControl("PageOptions.ascx"); 
        snapContent.Controls.Add(uc1);
    Snap1.Controls.Add(snapContent);
        Snap1.Content = snapContent;

    SnapContent snapFooter = new SnapContent();
        snapFooter.ID = "FooterSpan";  // need to give explicit ID to avoid minor bug in 2007.1
    UserControl uc2 = (UserControl)Page.LoadControl("Footer.ascx"); 
    snapFooter.Controls.Add(uc2);
    Snap1.Controls.Add(snapFooter);
    Snap1.Footer = snapFooter;

    PlaceHolder1.Controls.Add(Snap1); 


    /* Snap2, using old deprecated method */
    Snap2 = new ComponentArt.Web.UI.Snap(); 

    Snap2.ID = "Snap2"; 
    Snap2.DockingContainers = "LeftColumn,RightColumn"; 
    Snap2.CurrentDockingContainer = "LeftColumn";
    Snap2.CurrentDockingIndex = 1;
    SnapHeader Header2 = new SnapHeader(); 
    Header2.Title = "Developer Tools"; 
    Header2.SnapID = "Snap2"; 
    Snap2.HeaderTemplate = Header2; 
    Snap2.ContentTemplate = Page.LoadTemplate("DeveloperTools.ascx"); 
    Snap2.FooterTemplate = Page.LoadTemplate("Footer.ascx"); 
    PlaceHolder1.Controls.Add(Snap2); 
  }

  #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
      //
      // CODEGEN: This call is required by the ASP.NET Web Form Designer.
      //
      InitializeComponent();
      base.OnInit(e);    
    }
  
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {    
      this.Load += new System.EventHandler(this.Page_Load);
    }
  #endregion


/* older Snaps required the usage of an Itemplate class object */
  public class SnapHeader : ITemplate
  {
    public string SnapID; 
    public string Title; 

    public void InstantiateIn(Control container)
    {
      Literal L1 = new Literal(); 
      L1.Text = "<div style=\"CURSOR: move; width: 100%;\"><table cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">";
      L1.Text += "<tr><td class=\"SnapHeader\" onmousedown=\"" + SnapID + ".startDragging(event);\">" + Title + "</td>";
      L1.Text += "<td width=\"10\" style=\"cursor: hand\" align=\"right\"><img onclick=\"" + SnapID + ".toggleExpand();\" src=\"images/i_open.gif\" width=\"22\" height=\"19\" border=\"0\"></td>";
      L1.Text += "</tr></table></div>";
      container.Controls.Add(L1); 
    }
  }

/* new Snaps use control */
    private Control GetHeaderControl(string SnapID, string Title, string toggleImagePath)
    {
      Literal L1 = new Literal(); 
      L1.Text = "<div style=\"CURSOR: move; width: 100%;\"><table cellSpacing=\"0\" cellPadding=\"0\" width=\"100%\" border=\"0\">";
      L1.Text += "<tr><td class=\"SnapHeader\" onmousedown=\"" + SnapID + ".startDragging(event);\">" + Title + "</td>";
      L1.Text += "<td width=\"10\" style=\"cursor: hand\" align=\"right\"><img onclick=\"" + SnapID + ".toggleExpand();\" src=\"" + toggleImagePath + "\" width=\"22\" height=\"19\" border=\"0\"></td>";
      L1.Text += "</tr></table></div>";
      return L1;
    }
  }
}

Not Ranked
Posts: 2
m.maddbhavi Posted: Mon Nov 23, 2009 @ 10:09 PM
Adding this line  -  Snap1.Controls.Clear();  // remove default SnapHeader/SnapContent     
Does it support zooming and scrolling within the snap?
Top 25 Contributor
Posts: 168
CLAMONT Posted: Thu Jan 14, 2010 @ 12:11 PM
Seems like this is an old bug... please update the documentation and samples.
Not Ranked
Posts: 8
mbinkley Posted: Fri Aug 20, 2010 @ 2:27 PM
Okay, this is frustrating. 'toggleExpland' is not a valid Snap method. Do I have to write a function to call the Expand and Collapse methods using the isCollapsed property or some such?
Page 1 of 2 (16 items) 1 2 Next >