2010-04-13 4 views
4

J'essaye de développer un contrôle de serveur personnalisé basé sur un modèle très simple qui ressemble à GridView. Au fond, je veux que le contrôle à ajouter dans la page .aspx comme ceci:Comment créer un contrôle serveur ASP.NET personnalisé basé sur un modèle GridView comme un gabarit

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

et lors de la fourniture de la source de données suivante:

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

le résultat devrait être une table HTML comme celui-ci.

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

Le problème principal est que je ne peux pas définir le ColonneModèle. Quand j'ai essayé de le faire comme ça ...

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

.. et ensuite instancier le modèle dans les CreateChildControls je suis arrivé le résultat suivant qui est pas ce que je veux:

----------- 
| Age: 35 | 
----------- 
| Age: 44 | 
----------- 
| Age: 26 | 
----------- 
  • I Je sais que ce que je veux réaliser est inutile et que je peux utiliser DataGrid pour y arriver, mais je donne cet exemple très simple car si je sais comment faire cela, je serais capable de développer le contrôle dont j'ai besoin. Je vous remercie.

Répondre

1

Jetez un oeil à cet article: Building DataBound Templated Custom ASP.NET Server Controls

Il est assez vieux, mais je suppose qu'il est toujours valide.

+0

J'ai lu cet article mais cela n'aide pas. Cet article explique comment développer un contrôle personnalisé avec différents modèles tels que ItemTemplate et HeaderTemplate ou comment tout mettre dans un ItemTemplate. Mon problème est que j'ai le même modèle utilisé plusieurs fois donc cet article ne m'aide pas. – Deyan

0

J'étais confronté au même problème que vous. Après une recherche, j'ai trouvé un moyen de faire ce que vous voulez. Ce n'est pas parfait car cela nécessite de définir un contrôle + un template pour chaque colonne (l'exemple que vous donnez définit un template directement), mais ça marche.

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

Ensuite, vous pouvez faire:

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

Je sais comment vous obtenez de ceci:

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

à ceci:

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

Derive de ITemplate:

Ajouter un champ public à CustomColumnDefiner pour le nom de la colonne et ListItemType.

remplacer cette fonction en CustomColumnDefiner:

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

Dans InstantiateIn, si le membre est listItemType ListItemType.Item, vérifier le nom de la colonne. Si le nom de la colonne est Âge, modifiez la valeur de l'étiquette entrante pour qu'elle soit "Age:" + valeur entrante. C'est essentiellement le post-traitement de chaque cellule de la colonne pour ajouter la partie "Age:".

Du côté de la configuration, il est une fonction comme ceci:

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

puis dans votre code page ASPX derrière. J'ai utilisé cette méthode pour plier GridViews à mon gré.

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

Cela fonctionnera pour aller de votre datatable à la table html que vous voulez. Je ne sais pas si cela va rentrer dans votre solution globale.

Questions connexes