Чтобы выполнить то, что вы хотите, у вас есть два варианта, как я вижу:
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);
}
Итак, вот оно. Пользовательские шаблоны элементов управления без всякой неприятной головной боли при попытке собрать их все вручную в коде. Я собираюсь опубликовать полностью ручной способ сделать это в другом ответе, но как только вы увидите это, я думаю, вы согласитесь, что этот метод предпочтительнее.