需求背景:绑定列数量不稳定,可能会发生变化;或者需要允许用户自己定义显示列
解决方案:GridView 动态增加列,使用ITemplate 接口实现ItemTemplate
1.通过实现ITemplate接口的InstantiateIn方法,定义自己希望的列展示内容。并且定义嵌入内容的DataBinding事件。
Code
public class RoomNameTemplate : WebControl, ITemplate
{
private string _text;
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public RoomNameTemplate()
{ }
public RoomNameTemplate(string text)
{
this._text = text;
}
#region ITemplate 成员
public void InstantiateIn(Control container)
{
HtmlGenericControl spanText = new HtmlGenericControl();
spanText.TagName = "span";
spanText.Attributes.Add("id", "spanText");
spanText.Attributes.Add("runat", "server");
spanText.DataBinding += new EventHandler(spanText_DataBinding);
container.Controls.Add(spanText);
}
void spanText_DataBinding(object sender, EventArgs e)
{
HtmlGenericControl spanText = sender as HtmlGenericControl;
GridViewRow container = spanText.NamingContainer as GridViewRow;
if (container != null)
{
RoomStatusDomain domain = container.DataItem as RoomStatusDomain;
spanText.InnerText = domain.Room.Name;
}
}
#endregion
}
2.重写页面的CreateChildControls方法,按自己的需求创建GridView列,但是页面的样式需要自己通过代码来控制。
Code
protected override void CreateChildControls()
{
base.CreateChildControls();
if (gridRoomStatus != null)
{
gridRoomStatus.Columns.Clear();
TemplateField roomColumn = new TemplateField();
roomColumn.HeaderStyle.Width = Unit.Pixel(100);
roomColumn.HeaderStyle.HorizontalAlign = HorizontalAlign.Center;
roomColumn.HeaderText = "会议室";
RoomNameTemplate roomItem = new RoomNameTemplate();
roomColumn.ItemTemplate = roomItem;
roomColumn.ItemStyle.HorizontalAlign = HorizontalAlign.Center;
gridRoomStatus.Columns.Add(roomColumn);
}
}
值得注意的是,通过代码创建GridView列的ControlState并不是我们能够控制的,如果混合使用HTML方式和代码动态创建,容易出现PostBack以后无法重新Render ItemTemplate中的内容。最好能够统一用代码创建,每次创建前先将所有列清空。这样不会影响绑定。