CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Eric Wise

Business & .NET

User Defined Grid Layouts

The challenge: Allow users to define the columns shown and order for datagrid displays in ASP .NET webpages.  Here is my first stab at a solution.

I'm going to create a class object called Employer, with some text fields, a true/false to be displayed as a checkbox, a hyperlink on the company name, and an image path (just so we can cover several different types of columns in one example).  I am not going to post the class layout, just note that the properties in the class are as follows:

  • Type
  • CompanyName (hyperlink)
  • Length
  • Position
  • Phone
  • Supervisor
  • ImagePath (image)
  • IsChecked (checkbox)

So the first thing I did was write an xml file that would specificy the order of the columns, and have attributes defining what property on the employer object belongs in each column.  (This will be generated through a config interface in the future, but for now I wrote it by hand)

<?xml version="1.0" encoding="utf-8" ?>

<Columns>

<Column headerText="Type" type="Label" bindTo="Type"/>

<Column headerText="CompanyName" type="HyperLink" linkText="CompanyName" navURL="editPage" target="_blank"/>

<Column headerText="Length" type="Label" bindTo="Length"/>

<Column headerText="Position" type="Label" bindTo="Position"/>

<Column headerText="Main Phone" type="Label" bindTo="MainPhone"/>

<Column headerText="Supervisor" type="Label" bindTo="Supervisor"/>

<Column headerText="Image" type="Image" bindTo="ImagePath"/>

<Column headerText="Check" type="CheckBox" bindTo="isChecked"/>

</Columns>

 

So now in my .aspx page I'm going to instantiate my employer object, read the xml layout file, build the datagrid programatically from the xml layout, add it to the page, and bind it.  (For the purposes of this example I put default values in my employer object and just added a few of them to an arraylist and bound the arraylist to the grid).  Here is the .aspx code:

Protected emp As New Employer

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

Dim dgr As New System.Web.UI.WebControls.DataGrid

Dim doc As New System.Xml.XmlDocument

doc.Load("C:\Dev\StreamLend.Net\CoreGUI\XMLFiles\XMLFile1.xml")

Dim columnNodeList As System.Xml.XmlNodeList = doc.SelectNodes("//Columns/Column")

Dim columnNode As System.Xml.XmlNode

For Each columnNode In columnNodeList

Dim dgrCol As System.Web.UI.WebControls.DataGridColumn

Select Case (columnNode.Attributes.GetNamedItem("type").Value.ToUpper)

Case "LABEL"

Dim bCol As New System.Web.UI.WebControls.BoundColumn

bCol.DataField = columnNode.Attributes.GetNamedItem("bindTo").Value

dgrCol = bCol

Case "HYPERLINK"

Dim hCol As New System.Web.UI.WebControls.HyperLinkColumn

hCol.DataTextField = columnNode.Attributes.GetNamedItem("linkText").Value

hCol.NavigateUrl = columnNode.Attributes.GetNamedItem("navURL").Value

hCol.Target = columnNode.Attributes.GetNamedItem("target").Value

dgrCol = hCol

Case "CHECKBOX"

Dim tCol As New System.Web.UI.WebControls.TemplateColumn

tCol.ItemTemplate = New DataGridCheckBoxColumn(emp)

dgrCol = tCol

Case "IMAGE"

Dim tCol As New System.Web.UI.WebControls.TemplateColumn

tCol.ItemTemplate = New DataGridImageColumn(emp)

dgrCol = tCol

End Select

dgrCol.HeaderText = columnNode.Attributes.GetNamedItem("headerText").Value

dgr.Columns.Add(dgrCol)

Next

'Build Arraylist and bind grid

emp = New Employer

Dim employers As New ArrayList

employers.Add(emp)

employers.Add(emp)

employers.Add(emp)

employers.Add(emp)

dgr.AutoGenerateColumns = False

dgr.Width = Unit.Percentage(100)

dgr.DataSource = employers

dgr.DataBind()

page.Controls.Add(dgr)

End Sub

Public Class DataGridCheckBoxColumn

Implements System.web.UI.ITemplate

Dim mContainer As Object

Dim mBindTo As String

Public Sub New(ByVal Container As Object)

mContainer = Container

End Sub

Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn

Dim chkbox As New System.Web.UI.WebControls.CheckBox

chkbox.Checked = DataBinder.Eval(mContainer, "isChecked")

chkbox.ID = "chk1"

container.Controls.Add(chkbox)

End Sub

End Class

Public Class DataGridImageColumn

Implements System.web.UI.ITemplate

Dim mContainer As Object

Public Sub New(ByVal Container As Object)

mContainer = Container

End Sub

Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn

Dim img As New System.Web.UI.WebControls.Image

img.ImageUrl = "Images/" & DataBinder.Eval(mContainer, "ImagePath")

img.ID = "img1"

container.Controls.Add(img)

End Sub

End Class

Feedback and questions welcome!



Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!