我正在尝试在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()(这导致我们过去没有问题) - 我希望数据绑定被限制为页面的特定部分。
答案 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的回答将起作用......但考虑两种情况。
如果您的业务对象始终为null,则页面将因“对象引用”错误而崩溃。这可以通过麻烦的外观来避免 &lt;%if(MyObject!= null){%&gt;&lt;%= MyObject.Prop%&gt;&lt;%}%&gt; ...但每次这样做会导致代码混乱。
如果您的页面通过UpdatePanel使用PostBack处理,则每次页面生命周期运行时,业务对象都必须重新加载 ... 即使该部分页面未重绘。这是因为IIS将解析所有&lt;%= MyObject.Prop%&gt;无论如何引用都会导致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();
}
}
答案 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();