有没有ASP ?. NET databinable控件(如Repeater),它只需要一个项目

本文关键字:项目 一个 控件 databinable NET ASP 有没有 Repeater | 更新日期: 2023-09-27 18:11:23

我正在尝试在Web表单上显示来自业务对象的许多属性。当然,我可以创建大量的标签,并在代码隐藏中分配所有的值,但我觉得必须有一种不那么冗长的方法。

我想要的是类似于asp:Panel的东西,但是你可以指定一个数据源。面板似乎不支持任何类型的数据绑定。

我想要的是这样的东西

// C#
panel.DataSource = theCompany;
panel.DataBind();

:

// ASPX
<asp:Panel runat="server">
    Name: <%# Eval("Name") %>
    Phone: <%# Eval("Phone") %> 
    ...
</asp:Panel>

. .但是我找不到可以让我这样工作的工作。

我想我可能能够使用asp:FormView,但这只是给出了错误"数据源是无效类型。它必须是IListSource、IEnumerable或IDataSource。"

一个警告是,我想要调用一个全局的DataBind()(这在过去给我们带来了没完没了的问题)-我希望将数据绑定限制在页面的特定部分。

有没有ASP ?. NET databinable控件(如Repeater),它只需要一个项目

似乎你可以使用面板来做到这一点,但是你必须首先将你的业务对象分配给页面属性,因为没有办法将业务对象设置为面板的"数据源"(就像你对Repeater控件一样,例如)。

一旦对象被指定为页面属性,您就可以在.aspx中使用以下语法来访问该对象的属性,而无需在后面的代码中手动为每个项分配控制值:

<%# Company.Name %>

您不需要进行数据绑定(尽管您可以)。您需要的是一个简单的表达式求值器。在后面的代码中添加如下属性

public string Test { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
    Test = "<script>alert('test');</script>";
}

然后使用它将代码直接呈现到页面,如下所示

The value: <%: Test %>

注意<%:语法转义输入。如果希望不转义输入,则可以使用<%=语法。注意,你不需要有一个字符串对象,你可以访问任何你喜欢的属性,例如

The value lenght: <%: Test.Length %>

使用如下:

<asp:DetailsView runat="server">
    Name: <%# Eval("Name") %>
    Phone: <%# Eval("Phone") %>
</asp:DetailsView>

使用DetailsView。您可以从工具箱中添加它。它用于单行数据表示。

<asp:DetailsView runat="server">
    Name: <%# Eval("Name") %>
    Phone: <%# Eval("Phone") %>
</asp:DetailsView>

为什么不使用DetailsView ?这正是你想要的。仅显示单行数据,并且也是两列形式

我建议使用标准的Repeater,与包含单个项目的数组绑定。

Repeater.DataSource = new [] { theCompany };
Repeater.DataBind();

优于绑定到Panel的优势:您仍然可以使用ItemType属性,并且可以访问不错的强类型Item对象,而不必使用Eval,即:

<asp:Repeater runat="server" Id="Repeater" ItemType="CompanyViewModel">
    <ItemTemplate>
        Name: <%# Item.Name %>
        Phone: <%# Item.Phone %>
    </ItemTemplate>
</asp:Repeater>

(将"CompanyViewModel"替换为"the company "的类型)

您也可以尝试使用DetailsView,但它不像Repeater那样具有可塑性。

创建显示对象属性的用户控件。您可以使用反射读取属性名称和值并在控件中显示。

在用户控件中为对象创建属性。在用户控制代码后面写函数Show()和下面的代码。

//Build html strin from all propeties
PropertyInfo[] properties = yourObject.GetType().GetProperties();
string lbl = "<label>{0}</label>";
string value= "<span>{0}</span>";
string tab ="'t";
StringBuilder sb = new StringBuilder();
foreach (PropertyInfo pi in properties)
{
    var label = string.Format(lbl,pi.Name);
    var val =  string.Format(value, pi.GetValue(yourObject, null))
    sb.Append(label+tab+val);
    sb.Append("<br/>")    
}
Response.Write(sb.ToString()); 

现在在页面中添加该控件并在后面的代码中设置其对象属性,如

myControl.MyObject = yourObject;
myControl.Show(); 

NickG的回答会起作用…但是考虑两种情况。

  1. 如果您的业务对象为null,则页面将崩溃并出现"对象引用"错误。这可以通过繁琐的外观来避免% if(MyObject != null) {%><%= MyObject。Prop %><%} %>…但是每次这样做都会导致代码混乱。

  2. 如果你的页面通过UpdatePanel使用PostBack处理,业务对象将不得不在每次页面生命周期运行时重新加载到属性…,即使页面的那一部分没有被重绘。这是因为IIS将解析所有的<%= MyObject。如果您的对象来自数据库,则会导致浪费CPU周期和可能浪费的数据库调用。

由于这些原因,我总是使用Repeater控件,它是轻量级的,支持ViewState,可以很容易地分配一个项目列表,并避免了上述问题。下面是一个使用HttpContext.Current.Request对象作为"业务对象"的例子。
<asp:Repeater ID="rptTest" runat="server">
            <ItemTemplate>
                Request.URL = <%# Eval("Url") %>
            </ItemTemplate>
</asp:Repeater>

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        var objTest = Request; //Using the Request object as a test business object
        rptTest.DataSource = new List<System.Web.HttpRequest>() { objTest };
        rptTest.DataBind();
    }
}

要做到这一点,我们可以自定义ASP。. NET面板,通过继承它并使用自定义服务器控件。净

使用下面的代码修改ASP。. NET面板。. NET自定义服务器控件项目:

[DefaultProperty("Text")]
[ToolboxData("<{0}:CustomPanel runat=server></{0}:CustomPanel>")]
public class CustomPanel : Panel
{
    [Bindable(true)]
    public object MyDataSource
    {
        get;
        set;
    }
    [Bindable(true)]
    [Category("Appearance")]
    [DefaultValue("")]
    [Localizable(true)]
    public StringBuilder Text
    {
        get;
        set;
    }
    public void MyDataBind()
    {
        Text = new StringBuilder();
        foreach (PropertyInfo p in MyDataSource.GetType().GetProperties())
        {
            Text.Append(string.Format("<b>{0}</b>", p.Name));
            Text.Append(":");
            if (p.GetIndexParameters() == null || p.GetIndexParameters().Length == 0)
                Text.Append(p.GetValue(MyDataSource, null));
            Text.Append("<br />");
        }
    }
    protected override void RenderContents(HtmlTextWriter output)
    {
        output.Write(Text);
    }
}

然后将此控件的引用和工具箱项添加到您的ASP。NET页面:

<cc2:CustomPanel ID="MyCustomPanel" runat="server">
</cc2:CustomPanel>

使用如下所示的控件:

        MyCustomPanel.MyDataSource = theCompany;
        MyCustomPanel.MyDataBind();
相关文章: