如何在 ASP.NET 中使用标记声明对象
How to declare an object using markup in ASP.NET
假设我们有一个 Person
class:
public class Person
{
public string FamilyName {get;set;}
public string GivenName {get;set;}
}
并且有一个控件可以以某种方式显示人员列表的信息。这是 aspx 的伪代码:
<uc1:EmployeesViewer runat="server">
<Employees>
<Person>
<GivenName>John</GivenName>
<FamilyName>Kerry</GivenName>
</Person>
<Person>
<GivenName>Jack</GivenName>
<FamilyName>Lew</GivenName>
</Person>
<Employees>
</uc1:EmployeesViewer>
EmployeesViewer.Employees
属于 List<Person>
类型,属性为 [PersistenceMode(PersistenceMode.InnerProperty)]
.
但是 Visual Studio 不编译它。是否可以使用标记声明 Person
对象?
这是可能的。然而,它完全是它自己的动物。虽然所有方法都是微软的,但令人惊讶的是它被广泛采用。
您可以使用 xsd style sheets to format the data. Then you plug in an object, and it renders that object. In some versions of visual studio, there are even methods of generating 样式 sheet 中的对象模型。
GL
不能把Person做成用户控件吗?
并这样添加:
<uc1:EmployeesViewer runat="server">
<Employees>
<uc1:Person GivenName="John"/>
</Employees>
<uc1:EmployeesViewer/>
编辑
做了一个测试例子。
将以下内容添加到 employeesView 以便能够访问标记中的人员:
Private _emptyDataTemplate As New List(Of Person)
<Browsable(False)>
<PersistenceMode(PersistenceMode.InnerProperty)>
<TemplateContainer(GetType(Person))>
Public ReadOnly Property Persons() As List(Of Person)
Get
Return _emptyDataTemplate
End Get
End Property
做了一个人class:
Public Class Person
Inherits System.Web.UI.UserControl
Private msFirstName As String
Public Property FirstName() As String
Get
Return msFirstName
End Get
Set(ByVal value As String)
msFirstName = value
End Set
End Property
End Class
在 main.aspx 中,我将此添加到标记中:
<!-- top of page -->
<%@ Register TagPrefix="pd" TagName="Person" Src="Person.ascx" %>
<%@ Register TagPrefix="pd" TagName="pView" Src="WebUserControl1.ascx" %>
<!-- wherever you use employeesView -->
<pd:EmployeesView ID="PView1" runat="server">
<Persons>
<pd:Person ID="Person2" FirstName="blabal" runat="server"></pd:Person>
<pd:Person ID="Person3" FirstName="bobba" runat="server"></pd:Person>
</Persons>
</pd:EmployeesView>
希望对您有所帮助:)
Is it possible to declare a Person
object using markup?
是的,只对标记做了一些小改动(没有 对你的人物 class 的改动:
<%@ Page Language="C#" CodeBehind="DemoPage.aspx.cs" Inherits="DemoApp.DemoPage" %>
<%@ Register TagPrefix="uc1" Assembly="DemoApp" Namespace="DemoApp" %>
<uc1:EmployeesViewer runat="server">
<Employees>
<uc1:Person GivenName="John" FamilyName="Kerry" />
<uc1:Person GivenName="Jack" FamilyName="Lew" />
</Employees>
</uc1:EmployeesViewer>
uc1:
标记前缀假定您的 Person class 与 EmployeesViewer 位于同一程序集和命名空间中。如果不是,只需 <%@ Register %>
Person 的另一个标签前缀。
注意:即使 Person 不是从 Control 派生的,您也可以使用 <uc1:Person>
语法:
namespace DemoApp
{
public class Person
{
public string FamilyName {get;set;}
public string GivenName {get;set;}
}
}
下面是呈现员工列表的简单 EmployeesViewer 控件:
namespace DemoApp
{
[ParseChildren(true)]
[PersistChildren(false)]
public class EmployeesViewer : Control
{
private readonly List<Person> _employees = new List<Person>();
[PersistenceMode(PersistenceMode.InnerProperty)]
public List<Person> Employees
{
get { return _employees; }
}
protected override void Render(HtmlTextWriter writer)
{
foreach (Person person in this.Employees)
{
writer.RenderBeginTag(HtmlTextWriterTag.P);
writer.WriteEncodedText(string.Format("{0} {1}", person.GivenName, person.FamilyName));
writer.RenderEndTag();
}
}
}
}
需要 [ParseChildren(true)]
属性以便在 运行 时 ASP.NET 将 <Employees>
标签解释为 属性 名称而不是文字标记被渲染。
需要 [PersistChildren(false)]
和 [PersistenceMode(PersistenceMode.InnerProperty)]
属性,以便在设计时使用设计器的属性 window、[=39= 修改员工 collection ] 正确地将 collection 保存到标记中。
是的,有可能。
<% Person person1 = new Person();
person1.FamiliName="Brown";
person1.GivenName="John";
List<Person> persons = new List<Person>();
persons.Add(person1);
EmployeesViewer.DataSource = persons;
%>
除了学术原因,我不确定你为什么要这样做。由于其他一些 post 用户主要关注使用控件来创建标记,为什么不使用类似 DataSet 的东西来实现您想要实现的目标呢?
您可以通过从上下文菜单中选择“添加”>“新项目”>“数据”>“数据集”中的“数据集”来创建数据集。 DataSet 可以是强类型的并为您提供完整的 Intellisense 功能,但这可能不适合您的场景。只是想我会把这个想法扔出去。
使用数据集:
过程:创建数据集,创建数据表,为数据表创建列 (DataColumns),实例化并绑定到给定的 .aspx 控件。
标准 DataSet/DataTable/DataColumn:
DataSet ds = new DataSet("MyDataSetNameSpace");
DataTable person = new DataTable();
//add columns to the datatable
person.Columns.Add(new DataColumn(typeof(string)), "FamilyName");
person.Columns.Add(new DataColumn(typeof(string)), "GivenName");
强类型数据集:
PersonDataSet personDs = new PersonDataSet("PersonDataSetNameSpace");
//DataTable should already exist in your strongly-typed DataSet because you define the datatables in the vs designer
//accessing the datatable
personDs.Person person = new PersonDataSet.Person();
person.GivenName = "John Eisenhower Smith";
person.FamilyName = "Johnny";//nickname? I'm guessing this might actually be Smith
如果您想在标记中使用数据集,您可以将它绑定到您试图用来创建列表的特定列表控件。
//you can define the DataSource in Markup or in CodeBehind. You'd have to define a protected or public variable so that you can access the item in your markup.
//In markup, you would set DataSource = <%# Person%>
myGridViewControl.DataBind();//bind the dataset/datatable to the control
MSDN 参考:
https://msdn.microsoft.com/en-us/library/ss7fbaez(v=vs.110).aspx
编辑:
要完成您使用 XAML 完成的任务,您必须通过使用 Silverlight 控件注入 XAML。有关如何执行此操作的更多信息,请参阅此 post:
Is there a way to insert Silverlight XAML into my page using ASP.NET code-behind?
简答在 WebForms 中,目前无法完成。您必须通过 hack 来完成此操作,因为该框架不支持它。您可以使用 C# 代码块来完成您想要做的事情,但您仍然无法正确完成您想要完成的事情。
假设我们有一个 Person
class:
public class Person
{
public string FamilyName {get;set;}
public string GivenName {get;set;}
}
并且有一个控件可以以某种方式显示人员列表的信息。这是 aspx 的伪代码:
<uc1:EmployeesViewer runat="server">
<Employees>
<Person>
<GivenName>John</GivenName>
<FamilyName>Kerry</GivenName>
</Person>
<Person>
<GivenName>Jack</GivenName>
<FamilyName>Lew</GivenName>
</Person>
<Employees>
</uc1:EmployeesViewer>
EmployeesViewer.Employees
属于 List<Person>
类型,属性为 [PersistenceMode(PersistenceMode.InnerProperty)]
.
但是 Visual Studio 不编译它。是否可以使用标记声明 Person
对象?
这是可能的。然而,它完全是它自己的动物。虽然所有方法都是微软的,但令人惊讶的是它被广泛采用。
您可以使用 xsd style sheets to format the data. Then you plug in an object, and it renders that object. In some versions of visual studio, there are even methods of generating 样式 sheet 中的对象模型。
GL
不能把Person做成用户控件吗? 并这样添加:
<uc1:EmployeesViewer runat="server">
<Employees>
<uc1:Person GivenName="John"/>
</Employees>
<uc1:EmployeesViewer/>
编辑
做了一个测试例子。 将以下内容添加到 employeesView 以便能够访问标记中的人员:
Private _emptyDataTemplate As New List(Of Person)
<Browsable(False)>
<PersistenceMode(PersistenceMode.InnerProperty)>
<TemplateContainer(GetType(Person))>
Public ReadOnly Property Persons() As List(Of Person)
Get
Return _emptyDataTemplate
End Get
End Property
做了一个人class:
Public Class Person
Inherits System.Web.UI.UserControl
Private msFirstName As String
Public Property FirstName() As String
Get
Return msFirstName
End Get
Set(ByVal value As String)
msFirstName = value
End Set
End Property
End Class
在 main.aspx 中,我将此添加到标记中:
<!-- top of page -->
<%@ Register TagPrefix="pd" TagName="Person" Src="Person.ascx" %>
<%@ Register TagPrefix="pd" TagName="pView" Src="WebUserControl1.ascx" %>
<!-- wherever you use employeesView -->
<pd:EmployeesView ID="PView1" runat="server">
<Persons>
<pd:Person ID="Person2" FirstName="blabal" runat="server"></pd:Person>
<pd:Person ID="Person3" FirstName="bobba" runat="server"></pd:Person>
</Persons>
</pd:EmployeesView>
希望对您有所帮助:)
Is it possible to declare a
Person
object using markup?
是的,只对标记做了一些小改动(没有 对你的人物 class 的改动:
<%@ Page Language="C#" CodeBehind="DemoPage.aspx.cs" Inherits="DemoApp.DemoPage" %>
<%@ Register TagPrefix="uc1" Assembly="DemoApp" Namespace="DemoApp" %>
<uc1:EmployeesViewer runat="server">
<Employees>
<uc1:Person GivenName="John" FamilyName="Kerry" />
<uc1:Person GivenName="Jack" FamilyName="Lew" />
</Employees>
</uc1:EmployeesViewer>
uc1:
标记前缀假定您的 Person class 与 EmployeesViewer 位于同一程序集和命名空间中。如果不是,只需 <%@ Register %>
Person 的另一个标签前缀。
注意:即使 Person 不是从 Control 派生的,您也可以使用 <uc1:Person>
语法:
namespace DemoApp
{
public class Person
{
public string FamilyName {get;set;}
public string GivenName {get;set;}
}
}
下面是呈现员工列表的简单 EmployeesViewer 控件:
namespace DemoApp
{
[ParseChildren(true)]
[PersistChildren(false)]
public class EmployeesViewer : Control
{
private readonly List<Person> _employees = new List<Person>();
[PersistenceMode(PersistenceMode.InnerProperty)]
public List<Person> Employees
{
get { return _employees; }
}
protected override void Render(HtmlTextWriter writer)
{
foreach (Person person in this.Employees)
{
writer.RenderBeginTag(HtmlTextWriterTag.P);
writer.WriteEncodedText(string.Format("{0} {1}", person.GivenName, person.FamilyName));
writer.RenderEndTag();
}
}
}
}
需要 [ParseChildren(true)]
属性以便在 运行 时 ASP.NET 将 <Employees>
标签解释为 属性 名称而不是文字标记被渲染。
需要 [PersistChildren(false)]
和 [PersistenceMode(PersistenceMode.InnerProperty)]
属性,以便在设计时使用设计器的属性 window、[=39= 修改员工 collection ] 正确地将 collection 保存到标记中。
是的,有可能。
<% Person person1 = new Person();
person1.FamiliName="Brown";
person1.GivenName="John";
List<Person> persons = new List<Person>();
persons.Add(person1);
EmployeesViewer.DataSource = persons;
%>
除了学术原因,我不确定你为什么要这样做。由于其他一些 post 用户主要关注使用控件来创建标记,为什么不使用类似 DataSet 的东西来实现您想要实现的目标呢?
您可以通过从上下文菜单中选择“添加”>“新项目”>“数据”>“数据集”中的“数据集”来创建数据集。 DataSet 可以是强类型的并为您提供完整的 Intellisense 功能,但这可能不适合您的场景。只是想我会把这个想法扔出去。
使用数据集:
过程:创建数据集,创建数据表,为数据表创建列 (DataColumns),实例化并绑定到给定的 .aspx 控件。
标准 DataSet/DataTable/DataColumn:
DataSet ds = new DataSet("MyDataSetNameSpace");
DataTable person = new DataTable();
//add columns to the datatable
person.Columns.Add(new DataColumn(typeof(string)), "FamilyName");
person.Columns.Add(new DataColumn(typeof(string)), "GivenName");
强类型数据集:
PersonDataSet personDs = new PersonDataSet("PersonDataSetNameSpace");
//DataTable should already exist in your strongly-typed DataSet because you define the datatables in the vs designer
//accessing the datatable
personDs.Person person = new PersonDataSet.Person();
person.GivenName = "John Eisenhower Smith";
person.FamilyName = "Johnny";//nickname? I'm guessing this might actually be Smith
如果您想在标记中使用数据集,您可以将它绑定到您试图用来创建列表的特定列表控件。
//you can define the DataSource in Markup or in CodeBehind. You'd have to define a protected or public variable so that you can access the item in your markup.
//In markup, you would set DataSource = <%# Person%>
myGridViewControl.DataBind();//bind the dataset/datatable to the control
MSDN 参考:
https://msdn.microsoft.com/en-us/library/ss7fbaez(v=vs.110).aspx
编辑:
要完成您使用 XAML 完成的任务,您必须通过使用 Silverlight 控件注入 XAML。有关如何执行此操作的更多信息,请参阅此 post:
Is there a way to insert Silverlight XAML into my page using ASP.NET code-behind?
简答在 WebForms 中,目前无法完成。您必须通过 hack 来完成此操作,因为该框架不支持它。您可以使用 C# 代码块来完成您想要做的事情,但您仍然无法正确完成您想要完成的事情。