我有一个相当大的asp.net网站,使用GridView绑定到很多地方的同一个对象.我正在使用项目模板来自定义每一行.但是,要在我必须复制的所有页面中使用相同的模板.将项目模板粘贴到每个页面.显然这不是最好的解决方案.除此之外,我希望能够通过更改某些配置文件来更改GridView使用的模板.
一种选择是使用DataGrid创建用户控件,并公开要在每个页面中使用的必要属性.但是,这不能满足能够动态更改模板的第二个要求.
基本上我正在寻找一种方法来告诉GridView使用模板并能够动态地执行此操作.任何想法都会有所帮助.
一种选择是使用DataGrid创建用户控件,并公开要在每个页面中使用的必要属性.但是,这不能满足能够动态更改模板的第二个要求.
基本上我正在寻找一种方法来告诉GridView使用模板并能够动态地执行此操作.任何想法都会有所帮助.
解决方法
为了实现你想要的,你有两个选择:
1.)在代码中动态构建每个TemplateField,并根据某些配置切换它们.
2.)为您的自定义网格创建用户控件并使用它们.
我知道你说你不想使用UserControl,因为这会剥夺你动态改变你的布局的能力,但让我用一个例子来挑战这个预设.
您可以使用内置的ASP.Net功能,以便使用PlaceHolder Control动态切换出您喜欢的用户控件.
<asp:PlaceHolder ID="GridViewPlaceHolder" runat="server" />
您的自定义网格可以在.ascx文件中以声明方式构建,然后在运行时动态加载到位:如下所示:
GridViewPlaceHolder.Controls.Add(LoadControl("~/Controls/MyCustomControl.ascx"));
现在,如果您真的想让自己的生活更轻松,那么您可以创建一个所有自定义网格控件都将继承的抽象基类.通过这种方式,您可以在加载时一般地处理控件.
public abstract class CustomGridControl: System.Web.UI.UserControl { public abstract Object DataSource { get; set; } }
可以在标记中定义简单网格:
<asp:GridView ID="myGridView" runat="server" AutoGenerateColumns="false"> <Columns> <asp:TemplateField HeaderText="Name"> <ItemTemplate> <asp:Label Text='<%#Eval("Name") %>' runat="server"></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Age"> <ItemTemplate> <asp:Label Text='<%#Eval("Age") %>' runat="server"></asp:Label> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
你的控件背后的代码看起来像这样:
public partial class SimpleGrid : CustomGridControl { public override object DataSource { get { return myGridView.DataSource; } set { myGridView.DataSource = value; } } }
现在使用它的页面或控件只需要转换为基类,你可以一般地使用它.以下是一个如何使用它的简单示例,但我认为它清楚地说明了这一点:
protected void Page_Load(object sender,EventArgs e) { var dataSource = new List<MyCustomClass> { new MyCustomClass{Name = "Josh",Age = 43},new MyCustomClass{Name = "Bob",Age = 14},new MyCustomClass{Name = "Ashley",Age = 32},}; DynamicallyLoadUserControlGrid("~/GridViewTemplates/SimpleGrid.ascx",dataSource); } private void DynamicallyLoadUserControlGrid(String controlLocation,List<MyCustomClass> dataSource) { var ctrl = (CustomGridControl)LoadControl(controlLocation); ctrl.DataSource = dataSource; ctrl.DataBind(); GridViewPlaceHolder.Controls.Add(ctrl); }
所以你有它.自定义模板化控件没有尝试在代码中手动构建它们的所有令人讨厌的头痛.我将在另一个答案中发布完全手动的方式,但是一旦你看到它,我想你会同意这种方法是首选.