Links User Control


As I mentioned in my previous post, one of the more common controls I put on my web sites is a links page.  I wanted the links page to be somewhat dynamic, easily updateable, without having to update the ASPX page.  I wanted to be able to create a simple place where I could store my data, and even, have it sync across multiple sites if I wanted.  I haven’t implemented this part yet, but it is in the works. 


So, I created a user control that reads the links from an XML file.  You specify the XML file in the user control line so it knows where to get it’s data from, and it then puts the data on the page.

<%@ Register Src=”LinkDisplay.ascx” TagName=”LinkDisplay” TagPrefix=”uc1″ %>

<uc1:LinkDisplay DataFile=”~/App_Data/references.xml” ID=”LinkDisplay1″ runat=”server” />


For this one, the code was pretty simple.

<script runat=”server”>

public string DataFile = “”;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (DataFile != “”)
xmlLinks.DataFile = DataFile;
}
}
</script>


And the ASPX was just as easy

<asp:DataList DataSourceID=”xmlLinks” ID=”DataList1″ runat=”server”>
<ItemTemplate>
<asp:HyperLink Target=”_blank” ID=”HyperLink1″ NavigateUrl='<%# XPath(“url”) %>’
runat=”server” Text='<%# XPath(“title”) %>’></asp:HyperLink>
<br />
<asp:Label ID=”lblDesc” CssClass=”LinkLabel” runat=”server” Text='<%# XPath(“description”) %>’ />
</ItemTemplate>
</asp:DataList>
<asp:XmlDataSource ID=”xmlLinks” runat=”server” />

You can see it in use at http://www.bbpphoto.com/links.aspx and http://www.nocommonground.com/blogSamples/links.aspx.  The one on BBPPhoto is actually several of the user controls on the same page, all pointing to different XML files, thus providing different categories.


You can download the whole sample here: http://www.nocommonground.com/blogSamples/links.zip

Comments (2)

  1. Uwe Keim says:

    Wow, great idea!

    And great to see that XmlDataSource. I wasn’t aware that such a control exists.

  2. Jeff Parker says:

    Hey Pete here is a question for you on this. I have done a lot of the same thing. More that I wish to count. And you are aware you can do nested rebinding as well I am sure.

    So for example one quick link list I have, Sorry just copying and pasting code. but it isn’t super secret and perhaps will help someone else learn some new trick the visible to false is intentional it turns of if there are links to display it is a control after all to be used anywhere. So anyway here is a way I am nesting links in a definition style list. which are also separated by multiple categories. Question after the code. And sorry as well usually code in these blogs are mangles they really need a [code][/code] tag

    <asp:repeater id="DictionaryCategories" runat="server" onitemdatabound="DictionaryCategories_OnItemDataBound" visible="False">

    <itemtemplate>

    <h5><%# ((System.Data.DataRowView) Container.DataItem)["CategoryName"] %></h5>

    <dl style="padding-right: 0px; padding-left: 20px; padding-bottom: 0px; padding-top: 0px">

    <asp:repeater id="DictionaryCategoriesLinks" runat="server" visible="False">

    <itemtemplate>

    <dt><a href="<%# ((System.Data.DataRowView) Container.DataItem)["LinkUrl"]%>" target="<%# ((System.Data.DataRowView) Container.DataItem)["LinkTarget"]%>"><%# ((System.Data.DataRowView) Container.DataItem)["LinkText"]%></a></dt>

    <dd><%# ((System.Data.DataRowView) Container.DataItem)["ToolTip"]%></dd>

    </itemtemplate>

    </asp:repeater>

    </dl>

    </ItemTemplate>

    </asp:Repeater>

    protected void DictionaryCategories_OnItemDataBound(object sender, RepeaterItemEventArgs e)

    {

    DataRowView view = (DataRowView) e.Item.DataItem;

    if(view != null)

    {

    Trace.Write("AdvancedLinks",String.Format("DictionaryCategories_OnItemDataBound {0}", view["CategoryId"]));

    DataTable dt = buildLinksTable(Convert.ToInt32( view["CategoryId"]));

    if(dt.Rows.Count > 0)

    {

    Repeater innerLinks = (Repeater) e.Item.FindControl("DictionaryCategoriesLinks");

    innerLinks.Visible = true;

    innerLinks.DataSource = new DataView(dt,"","LinkOrder",DataViewRowState.CurrentRows);

    innerLinks.DataBind();

    }

    }

    else

    {

    Trace.Write("AdvancedLinks","TableCategories_OnItemDataBound View was null!!!");

    }

    }

    Ok, Now I know I could create child views and everything the code is taken a bit out of context.

    However my question In the Databind event Sometimes, not all the time, the event fires, and Null is passed into RepeaterItemEventArgs

    Hence the check if it is null or not. The first repeater doesn’t fire again or at least it doesn’t repeat when this happens. But null does get sent, This could be on the exact same repeater, with the exact same data and this doesn’t happen every time. When it does happen it is always the last time the event fires. I have never been able to figure out why sometimes that null event fires from databinding.