Trapline Trapline - 1 month ago 7
ASP.NET (C#) Question

Insert My .NET Control In Template

I am new to ASP.NET. As a follow up question from THIS POST I have the following .Net Control in Ektron that I would like to display in my webpage template.

Control:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Gallery.ascx.cs" Inherits="Source_Controls_Alumni_Gallery" %>
<asp:ListView ID="uxPhotoGallery" runat="server" ItemPlaceholderID="itemPlaceholder">
<LayoutTemplate>
<ul>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</ul>
</LayoutTemplate>
<ItemTemplate>
<li>
<%--
I'm mixing up two different ways of referencing the incoming data. One is by casting
the DataItem to the incoming type, which gives you intellisense access to the properties.

The other is more of a dictionary approach in which you have to type out the property name
as a string.

I really like the casting approach, but it's mega-wordy.
--%>
<a href="<%#((Ektron.Custom.ViewModels.PressPhotoViewModel)Container.DataItem).ImageUrl %>">
<img src="<%#((Ektron.Custom.ViewModels.PressPhotoViewModel)Container.DataItem).ImageUrl %>" alt="<%#Eval("Description") %>" />
<div><%#Eval("Description") %></div>
</a>
</li>
</ItemTemplate>
</asp:ListView>


and code behind:

using Ektron.Custom.SmartForms;
using System;
using System.Linq;

public partial class Source_Controls_Alumni_Gallery : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
var pressPhotoManager = new PressPhotoManager();

// Whichever folder Id...
var photos = pressPhotoManager.GetList(75);

if (photos != null && photos.Any())
{
uxPhotoGallery.DataSource = photos;
uxPhotoGallery.DataBind();
}
}
}


I would like to insert the control into this template:

<%@ Page Title="" Language="C#" MasterPageFile="~/Source/Masterpages/MainMaster.master" AutoEventWireup="true" CodeFile="AlumniJobOpenings.aspx.cs" Inherits="Source_Templates_AlumniJobOpenings" %>

<%@ Register Src="~/Source/Controls/SubHeader.ascx" TagPrefix="uc1" TagName="SubHeader" %>
<%@ Register Src="~/Source/Controls/Shared/PrimarySection.ascx" TagPrefix="uc1" TagName="PrimarySection" %>
<%@ Register Src="~/Source/Controls/JoinUs/StaffAndParalegals/SPOpenings.ascx" TagPrefix="uc1" TagName="SPOpenings" %>
<%@ Register Src="~/Source/Controls/JoinUs/StaffAndParalegals/SPFilters.ascx" TagPrefix="uc1" TagName="SPFilters" %>
<%@ Register Src="~/Source/Controls/Shared/RelatedContentModules.ascx" TagPrefix="uc1" TagName="RelatedContentModules" %>
<%@ Register Src="~/Source/Controls/JoinUs/StaffAndParalegals/SPContactDetails.ascx" TagPrefix="uc1" TagName="SPContactDetails" %>
<%@ Register Src="~/Source/Controls/Shared/TextImageAssetBlockModules.ascx" TagPrefix="uc1" TagName="TextImageAssetBlockModules" %>
<%@ Register Src="~/Source/Controls/Shared/TextLinkBlockControl.ascx" TagPrefix="uc1" TagName="TextLinkBlockControl" %>
<%@ Register TagPrefix="sp" TagName="Spinner" Src="~/Source/Controls/Alumni/Gallery.ascx" %>




<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<uc1:SubHeader runat="server" ID="SubHeader" />
<div class="container non-responsive">
<div class="row">
<div class="col-sm-8 alpha">
<uc1:PrimarySection runat="server" ID="PrimarySection" />
<div class="primary">
<div class="container non-responsive">
<div class="row">
<div class="col-sm-8 alpha">
<div class="primary">
IMAGE GALLERY LIST SHOULD BE INSERTED HERE.
</div>
</div>
<div class="col-sm-4 beta">
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-4 beta">
<uc1:SPContactDetails runat="server" ID="SPContactDetails" />
<uc1:SPFilters runat="server" ID="SPFilters" Heading="Staff and Paralegal Openings" Text="Select an office below to learn more about current opportunities" />
<uc1:RelatedContentModules runat="server" ID="RelatedContentModules" />
<uc1:TextLinkBlockControl runat="server" ID="TextLinkBlockControl" />
<uc1:TextImageAssetBlockModules runat="server" ID="TextImageAssetBlockModules" />
</div>
</div>
</div>
</asp:Content>

Answer

Here's your line from the top:

<%@ Register TagPrefix="sp" TagName="Spinner" Src="~/Source/Controls/Alumni/Gallery.ascx" %>

And a similar line used to register another control in the same page:

<%@ Register Src="~/Source/Controls/SubHeader.ascx" TagPrefix="uc1" TagName="SubHeader" %>

Now, take a look at the control placement for the pre-existing item referenced above.

<uc1:SubHeader runat="server" ID="SubHeader" />

What you'll find is that the placement tag is made up of configured properties in the <%@ Register ... %> line. Specifically, the TagPrefix and TagName values. You'll use those values to set up your own control placement, following this format:

<TagPrefix:TagName runat="server" ID="SomeUniqueID" [optional parameters] />

So, in the case of your control, you've set TagPrefix="sp" and TagName="Spinner". So your control placement will look like this:

<sp:Spinner runat="server" ID="uxAlumniSpinner" />

(ID is an example)

From your control code, you don't have any parameters configured, so the above would work fine. But you could provide at least one parameter, and probably should in order to make the control more reusable.

For example, you've got a hard-coded value of 75 in your method call. I assume that's pointing to an Ektron Folder, Taxonomy, or Collection. Regardless, it's some container ID. You might want to use this control in multiple places with different sources for the data - different container IDs. The way you've set this up, you'll have to make a new control every time just to update that value.

So if we add a public property to your control, so that the code-behind looks like this:

using Ektron.Custom.SmartForms;
using System;
using System.Linq;

public partial class Source_Controls_Alumni_Gallery : System.Web.UI.UserControl
{

    // Added Property
    private long _containerId = 0;
    public long ContainerID {
        get { return _containerId; }
        set { _containerId = value; }
    }
    /////////

    protected void Page_Load(object sender, EventArgs e)
    {
        // Added inverted conditional to escape method 
        // if the _containerId is invalid.
        if(_containerId <= 0) return;
        ///////////

        var pressPhotoManager = new PressPhotoManager();

        // Whichever folder Id... 
        var photos = pressPhotoManager.GetList(_containerId);

        if (photos != null && photos.Any())
        {
            uxPhotoGallery.DataSource = photos;
            uxPhotoGallery.DataBind();
        }
    }
}

Then you could specify the container ID whenever and wherever you place the control. Like so:

<sp:Spinner runat="server" ID="uxAlumniSpinner" ContainerID="75" />

Making your final in-template markup:

<%@ Register Src="~/Source/Controls/JoinUs/StaffAndParalegals/SPContactDetails.ascx" TagPrefix="uc1" TagName="SPContactDetails" %>
<%@ Register Src="~/Source/Controls/Shared/TextImageAssetBlockModules.ascx" TagPrefix="uc1" TagName="TextImageAssetBlockModules" %>
<%@ Register Src="~/Source/Controls/Shared/TextLinkBlockControl.ascx" TagPrefix="uc1" TagName="TextLinkBlockControl" %>
<%@ Register TagPrefix="sp" TagName="Spinner" Src="~/Source/Controls/Alumni/Gallery.ascx" %>


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
    <uc1:SubHeader runat="server" ID="SubHeader" />
    <div class="container non-responsive">
        <div class="row">
            <div class="col-sm-8 alpha">
                <uc1:PrimarySection runat="server" ID="PrimarySection" />
                <div class="primary">
                    <div class="container non-responsive">
                        <div class="row">
                            <div class="col-sm-8 alpha">
                                <div class="primary">
                                    <sp:Spinner runat="server" ID="uxAlumniSpinner" ContainerID="75" />
                                </div>
                            </div>
                            <div class="col-sm-4 beta">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-sm-4 beta">
                <uc1:SPContactDetails runat="server" ID="SPContactDetails" />
                <uc1:SPFilters runat="server" ID="SPFilters" Heading="Staff and Paralegal Openings" Text="Select an office below to learn more about current opportunities" />
                <uc1:RelatedContentModules runat="server" ID="RelatedContentModules" />
                <uc1:TextLinkBlockControl runat="server" ID="TextLinkBlockControl" />
                <uc1:TextImageAssetBlockModules runat="server" ID="TextImageAssetBlockModules" />
            </div>
        </div>
    </div>
</asp:Content>
Comments