简体   繁体   English

在 ASP.NET 中可以有自定义的通用控件吗?

[英]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.我刚刚开始使用 ASP.NET 中的自定义控件,并想尝试使用它为对象列表创建一个表。

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.但是您仍然需要设置类似 DataSource 的内容并使用数据绑定来绑定到 Enumerable 对象。

See this related question on SO.请参阅有关 SO 的相关问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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