简体   繁体   中英

Is It Possible To Have Custom Generic Controls in ASP.NET?

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM