Reputation: 300
I've just started working with custom controls in ASP.NET and wanted to attempt to use it to create a table for a list of objects.
Here is my custom control:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.ModelBinding;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Jordan.Custom.CS.Controls
{
[DefaultProperty("Text"), ToolboxData("<{0}:ObjectTable runat=\"server\"> </{0}:ObjectTable>")]
public class ObjectTable<T> : WebControl
{
public ObjectTable() { }
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
string s = (string)ViewState["Text"];
return ((string.IsNullOrEmpty(s)) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["Text"] = value;
}
}
[Bindable(true), Category("Data"), DefaultValue(""), Localizable(true)]
public List<T> ObjectValue
{
get { return (List<T>)ViewState["ObjectValue"]; }
set { ViewState["ObjectValue"] = value; }
}
[Bindable(true), Category("Appearance"), DefaultValue(""), Localizable(true)]
public string Heading
{
get { return ViewState["heading"].ToString(); }
set { ViewState["Heading"] = value; }
}
protected override HtmlTextWriterTag TagKey
{
get { return HtmlTextWriterTag.Div; }
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Style, "text-align:center;color:red;");
}
protected override void RenderContents(HtmlTextWriter writer)
{
writer.Write("<h1>"+this.Heading+"</h1>");
writer.Write("<br />");
writer.RenderBeginTag(HtmlTextWriterTag.Table);
writer.RenderBeginTag("<tr>");
foreach (PropertyInfo prop in typeof(T).GetProperties()) //Pulls all the properties from the generic object
{
writer.RenderBeginTag("<th>");
writer.Write(prop.Name);
writer.RenderEndTag(); // th
}
writer.RenderEndTag(); // tr
writer.RenderEndTag(); // table
}
}
}
But when I attempt to use my custom control on the page, it doesn't work. Instead of doing what I would expect it to do, it gives this:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="Jordan" Namespace="Jordan.Custom.CS.Controls" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<Jordan:ObjectTable`1 />
</div>
</form>
</body>
</html>
Any help would be appreciated. I'd like to know if it's possible to use generics in custom controls and if so how to fix my problem?
Upvotes: 2
Views: 388
Reputation: 6520
I don't think what you are doing is possible with a custom control with respect to putting the control on the page. So
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<Jordan:ObjectTable`1 />
</div>
</form>
</body> </html>
doesn't know how to pass a populated data object. In the markup you only have access to string type properties. So what you could do is define the typename you are trying to bind to so that you could use reflection to load the type and spin through all the properties like you are currently doing. But you would still have to set something like DataSource and use databinding to bind to an Enumerable object.
See this related question on SO.
Upvotes: 2