我正在尝试开发一个非常简单的模板化自定义服务器控件,类似于GridView。基本上,我希望将控件添加到.aspx页面中,如下所示:
<cc:SimpleGrid ID="SimpleGrid1" runat="server">
<TemplatedColumn>ID: <%# Eval("ID") %></ TemplatedColumn>
<TemplatedColumn>Name: <%# Eval("Name") %></ TemplatedColumn>
<TemplatedColumn>Age: <%# Eval("Age") %></ TemplatedColumn>
</cc:SimpleGrid>
并在提供以下数据源时:
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Age", typeof(int));
table.Rows.Add(1, "Bob", 35);
table.Rows.Add(2, "Sam", 44);
table.Rows.Add(3, "Ann", 26);
SimpleGrid1.DataSource = table;
SimpleGrid1.DataBind();
结果应该是像这样的HTML表格。
-------------------------------
| ID: 1 | Name: Bob | Age: 35 |
-------------------------------
| ID: 2 | Name: Sam | Age: 44 |
-------------------------------
| ID: 3 | Name: Ann | Age: 26 |
-------------------------------
主要问题是我无法定义TemplatedColumn。当我试图这样做时......
private ITemplate _TemplatedColumn;
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(TemplatedColumnItem))]
[TemplateInstance(TemplateInstance.Multiple)]
public ITemplate TemplatedColumn
{
get { return _TemplatedColumn; }
set { _TemplatedColumn = value; }
}
..然后在CreateChildControls中实例化模板我得到了以下结果,这不是我想要的:
-----------
| Age: 35 |
-----------
| Age: 44 |
-----------
| Age: 26 |
-----------
答案 0 :(得分:1)
看一下这篇文章:Building DataBound Templated Custom ASP.NET Server Controls
它已经很老了,但我猜它仍然有效。
答案 1 :(得分:0)
我遇到了和你一样的问题。
经过一番搜索,我找到了一种方法来做你想做的事。它并不完美,因为它需要为每个列定义一个控件+一个模板(你给出的例子直接定义了一个模板),但是它可以工作。
//define a new property "Columns" in the grid
//it will hold a collection of controls of type "TemplatedColumn"
public class Grid : WebControl
{
private ColumnsCollection _columnsCollection;
public virtual ColumnsCollection Columns
{
get
{
if (_columnsCollection == null)
_columnsCollection = new ColumnsCollection();
return _columnsCollection;
}
}
}
//define ColumnsCollection class (must implement IList)
public class ColumnsCollection : List<TemplatedColumn> { ... }
//define TemplatedColumn webcontrol (in this case, must have a template)
public TemplatedColumn : WebControl
{
private ITemplate _Template;
[...] //attributes
public ITemplate Template
{
get { return _Template; }
set { _Template = value; }
}
}
然后你可以这样做:
<cc:Grid runat="server">
<Columns>
<cc:TemplatedColumn runat="server">
<Template>ID: <%# Eval("ID") %></Template>
</cc:TemplatedColumn>
<cc:TemplatedColumn runat="server">
<Template>Name: <%# Eval("Name") %></Template>
</cc:TemplatedColumn>
<Columns>
</cc:Grid>
答案 2 :(得分:-1)
我知道如何解决这个问题:
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Age", typeof(int));
table.Rows.Add(1, "Bob", 35);
table.Rows.Add(2, "Sam", 44);
table.Rows.Add(3, "Ann", 26);
SimpleGrid1.DataSource = table;
SimpleGrid1.DataBind();
到此:
-------------------------------
| ID: 1 | Name: Bob | Age: 35 |
-------------------------------
| ID: 2 | Name: Sam | Age: 44 |
-------------------------------
| ID: 3 | Name: Ann | Age: 26 |
-------------------------------
来自ITemplate:
public class CustomColumnDefiner : ITemplate { ...
为CustomColumnDefiner添加一个公共字段,用于列名和ListItemType。
在CustomColumnDefiner中覆盖此函数:
void ITemplate.InstantiateIn(System.Web.UI.Control container)
在InstantiateIn中,如果成员ListItemType是ListItemType.Item,请检查列名称。如果列名称为Age,则将传入标签的值编辑为“Age:”+传入值。它基本上是对列的每个单元格进行后处理,以添加“年龄:”部分。
在设置方面有一个这样的功能:
private static TemplateField GetTemplateColumn(string sColName)
{
TemplateField templateField = new TemplateField();
templateField.HeaderTemplate = new CustomColumnDefiner(ListItemType.Header, sColName);
templateField.ItemTemplate = new CustomColumnDefiner(ListItemType.Item, sColName);
return templateField;
}
然后在您的aspx页面代码后面。
myGridView.Columns.Add(GetTemplateColumn("Age"));
我已经使用这种方法将GridViews弯曲到我的意愿。它适用于从您的数据表转到您想要的html表。它是否适合您的整体解决方案我不知道。