![]() |
Web Development »
ASP.NET »
Web Parts
Beginner
License: The Code Project Open License (CPOL)
Flexible ASP.NET Web Part UI PatternBy Dan_PA pattern for building a templated UI for Web parts |
C#.NET 2.0, ASP.NET, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Typically, building a Web part for ASP.NET means that you are following the MSDN samples and building your UI elements in code and adding them to the Web part controls collection. This means that to make any changes, you are forced to recompile and redeploy. There are some solutions to this problem already such as the Smart Part, which makes use of user controls, but this article shows a different approach. It separates the HTML into a property of the Web part that end users can manipulate, the Web part code then binds any data sources to the controls that the end user defined.
I found this pattern particularly useful when I was asked to create a webpart that was the front end to a search engine, the Web part would POST the details the user entered to an intranet search site. The catch was that the webpart was used in a number of different parts of the site and in each instance, it had to present the user with a different view. What I really needed was a templating system, the resulting code is what I present below.
The code I present below is fairly simple, the power is in the call to Page.ParseControl.
The property TemplateHTML is decorated with attributes to make it editable via the Web part's tool part, which gives the end users the ability to change the look and feel.
In the example below, I've defined the Web part to have a textbox and an image button. In the CreateChildControls method, I add the template to the controls collection after the Page.ParseControl method. Next I use the FindControl method to hook up the control to any code that needs to manipulate it, this might include data binding to any dropdowns, etc.
using System;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;
namespace Template
{
public class Template : System.Web.UI.WebControls.WebParts.WebPart
{
//string with UI code to be added to the page
protected string templateHTML = string.Empty;
//Control IDs, the template must use these ID's
private string searchButtonID = "searchImgBtn";
private string allTextID = "allTxt";
//controls that will be found from the template
protected TextBox allTxt = null;
protected ImageButton searchBtn = null;
public Template()
{
}
protected override void CreateChildControls()
{
if (templateHTML != string.Empty)
{
try
{
//create a control that has been parsed by ASP.NET
Control template = Page.ParseControl(templateHTML);
//add it to the page
this.Controls.Add(template);
//search for the known controls
allTxt = template.FindControl(allTextID) as TextBox;
searchBtn = template.FindControl(searchButtonID) as ImageButton;
//hook up any events
if (searchBtn != null)
{
searchBtn.Click += new ImageClickEventHandler(btnSearch_Click);
}
}
catch (Exception err)
{
this.Controls.Add(
new LiteralControl(string.Format
("Error applying template: {0}", err.Message))
);
}
}
else
{
this.Controls.Add(new LiteralControl
("Please enter a template in the toolpart settings"));
}
base.CreateChildControls();
}
void btnSearch_Click(object sender, ImageClickEventArgs e)
{
//if the template included the textbox, show its results
if (allTxt != null)
{
this.Controls.Add(new LiteralControl("Searched On: " + allTxt.Text));
}
}
[System.Web.UI.WebControls.WebParts.WebBrowsable(true),
System.Web.UI.WebControls.WebParts.WebDisplayName("Layout Template"),
System.Web.UI.WebControls.WebParts.WebDescription
("Template that is used for layout"),
System.Web.UI.WebControls.WebParts.Personalizable(
System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared),
System.ComponentModel.Category("Template Settings"),
System.ComponentModel.DefaultValue("")
]
public string TemplateHTML
{
get{return templateHTML;}
set{templateHTML = value;}
}
}
}
A template for the example might look like...
<table>
<tr>
<td>Search On:</td>
<td><asp:TextBox ID="allTxt" runat="server" />
</tr>
<tr>
<td colspan="2"><asp:ImageButton runat="server"
ID="searchImgBtn" ImageUrl="Search.gif"/>
</tr>
</table>
or:
<div>
<p>Search On:<asp:TextBox ID="allTxt" runat="server" /></p>
<p><asp:ImageButton runat="server" ID="searchImgBtn" ImageUrl="Search.gif"/></p>
</div>
This isn't really a framework to reuse code, but more of a pattern that can prove helpful if you work in an environment where users are constantly asking for minor UI changes.
There is still a large coupling of concerns in this pattern, the control IDs in the template must match what the code behind is looking for; in that respect the UI and code are very tightly coupled.
| You must Sign In to use this message board. | ||||||||
|
||||||||
|
||||||||
|
||||||||
|
||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 15 Oct 2008 Editor: Deeksha Shenoy |
Copyright 2008 by Dan_P Everything else Copyright © CodeProject, 1999-2009 Web16 | Advertise on the Code Project |