是否有一个ASP.NET databindable控件(如Repeater),只需要一个项目?

时间:2014-07-04 13:18:41

标签: c# asp.net

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

我想要的是像asp:Panel,但你可以指定一个数据源。看起来Panels似乎不支持任何类型的数据绑定。

我想要的是这样的

// 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()(这导致我们过去没有问题) - 我希望数据绑定被限制为页面的特定部分。

9 个答案:

答案 0 :(得分:4)

您似乎可以使用Panel执行此操作,但您必须首先将业务对象分配给页面属性,因为无法将业务对象设置为&#34; DataSource&#34;对于面板(例如,与Repeater控件一样)。

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

<%# Company.Name %>

答案 1 :(得分:2)

您不需要数据绑定(尽管可以)。你需要的是一个简单的表达式评估器。像这样

在后面的代码中添加一个属性
public string Test { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
    Test = "<script>alert('test');</script>";
}

然后使用它直接将代码呈现给页面

The value: <%: Test %>

请注意,&lt;%:语法会转义输入。如果您不想转义输入,那么您可以使用&lt;%= syntax。请注意,您不需要拥有一个字符串对象,您可以访问任何您喜欢的属性,例如

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

使用以下内容:

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

答案 4 :(得分:1)

为什么不使用DetailsView。它非常适合您的需求。仅显示单行数据,也以两列形式显示。

答案 5 :(得分:1)

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

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

优于数据绑定到Panel:您仍然可以使用ItemType属性,并且可以访问优秀的强类型Item对象,而不必使用{ {1}},即:

Eval

(将“CompanyViewModel”替换为您的类型:“theCompany”。)

您也可以尝试使用<asp:Repeater runat="server" Id="Repeater" ItemType="CompanyViewModel"> <ItemTemplate> Name: <%# Item.Name %> Phone: <%# Item.Phone %> </ItemTemplate> </asp:Repeater> 进行试验,但它不像转发器那样具有可塑性。

答案 6 :(得分:0)

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

在用户控件中为对象创建属性。内部用户控制代码后面的写函数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(); 

答案 7 :(得分:0)

NickG的回答将起作用......但考虑两种情况。

  1. 如果您的业务对象始终为null,则页面将因“对象引用”错误而崩溃。这可以通过麻烦的外观来避免 &lt;%if(MyObject!= null){%&gt;&lt;%= MyObject.Prop%&gt;&lt;%}%&gt; ...但每次这样做会导致代码混乱。

  2. 如果您的页面通过UpdatePanel使用PostBack处理,则每次页面生命周期运行时,业务对象都必须重新加载 ... 即使该部分页面未重绘。这是因为IIS将解析所有&lt;%= MyObject.Prop%&gt;无论如何引用都会导致CPU周期浪费,如果您的对象来自数据库,可能会浪费数据库调用。

  3. 由于这些原因,我总是使用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();
        }
    }
    

答案 8 :(得分:0)

为了完成这项工作,我们可以通过继承ASP.NET Panel并使用ASP.NET的自定义服务器控件

来自定义它

使用以下代码修改ASP.NET自定义服务器控件项目中的ASP.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();