How to create a GridView, e.g. DataBound Templated Custom ASP.NET Server Control

I am trying to develop a very simple template server-side user control similar to a GridView. Basically, I want the control to be added on the .aspx page as follows:

<cc:SimpleGrid ID="SimpleGrid1" runat="server"> <TemplatedColumn>ID: <%# Eval("ID") %></ TemplatedColumn> <TemplatedColumn>Name: <%# Eval("Name") %></ TemplatedColumn> <TemplatedColumn>Age: <%# Eval("Age") %></ TemplatedColumn> </cc:SimpleGrid> 

and when providing the following data source:

  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(); 

the result should be an HTML table like this.

  ------------------------------- | ID: 1 | Name: Bob | Age: 35 | ------------------------------- | ID: 2 | Name: Sam | Age: 44 | ------------------------------- | ID: 3 | Name: Ann | Age: 26 | ------------------------------- 

The main problem is that I cannot define TemplatedColumn. When I tried to do it like this ...

  private ITemplate _TemplatedColumn; [PersistenceMode(PersistenceMode.InnerProperty)] [TemplateContainer(typeof(TemplatedColumnItem))] [TemplateInstance(TemplateInstance.Multiple)] public ITemplate TemplatedColumn { get { return _TemplatedColumn; } set { _TemplatedColumn = value; } } 

.. and subsequently create an instance of the template in CreateChildControls, I got the following result, which is not what I want:

  ----------- | Age: 35 | ----------- | Age: 44 | ----------- | Age: 26 | ----------- 
  • I know that what I want to achieve is pointless and that I can use the DataGrid to achieve it, but I give this very simple example, because if I know how to do this, I could develop the control I need, Thanks.
+4
source share
3 answers

Take a look at this article: Creating DataBound Templates with Custom ASP.NET Controls

It is quite old, but I think it is still valid.

+1
source

I faced the same problem as you.

After some searching, I found a way to do what you want. It is not ideal, as it requires the definition of a control + template for each column (the example you give defines the template directly), but it works.

 //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; } } } 

Then you can do:

  <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> 
0
source

I know how to get from this:

 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 | ------------------------------- 

Withdraw from ITemplate:

 public class CustomColumnDefiner : ITemplate { ... 

Add a public field to CustomColumnDefiner for the column name and ListItemType.

override this function in CustomColumnDefiner:

 void ITemplate.InstantiateIn(System.Web.UI.Control container) 

In InstantiateIn, if the ListItemType is ListItemType.Item, check the column name. If the column name is Age, change the value of the inbound label to Age: + the inbound value. This is basically the post-processing of each cell in the column to add the "Age:" part.

On the installation side there is such a function:

 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; } 

and then in your aspx page code.

 myGridView.Columns.Add(GetTemplateColumn("Age")); 

I used this method to bend GridViews as I wanted. It will work to transition from your datatable to the html table you want. Will it fit into your overall decision, I do not know.

-1
source

Source: https://habr.com/ru/post/1306840/


All Articles