views:

362

answers:

3

When defining the markup for an asp gridview and the tag Columns, one can only choose from a predefined set of controls to add within it (asp:BoundField, asp:ButtonField etc).

Im curious about if i can add the same type of behavior, say restricting the content to a custom control with the properties "Text" and "ImageUrl" to a TemplateContainer defined in a standard usercontrol and then handle the rendering of each element within the container from code behind somehow?

A: 

FYI The fields (asp:BoundField, asp:ButtonField etc) are not actually controls but are instead derived from the DatControlField class. Likewise, the columns property is not a ITemplate but is a DataFieldCollection.

Something like that should be possible if your controls all derive from the same class or implement the same interface.

drs9222
While doing some testing, adding a DataControlFieldCollection property to my usercontrol allows me to insert DataControlField´s just like the gridview so thats a nice start.However, im guessing that i have to derive my own collection somehow as youre saying which has its own custom set of DataControlFields.I cant be the first who have tried to do this, any ideas to guide me further into the light would be highly appreciated :)
CodeSpeaker
A: 

I'm thinking maybe you want something like this:

http://www.developer.com/net/asp/article.php/10917_3609991_1

If you want to create a custom column type for a GridView, you need to start out by deciding what goes in each cell of the column. Is it just a TextBox or Button? Or is it something more complicated? If it's more complicated, you need to create your own template class by inheriting from ITemplate.

Once you have that done, you need to write a class that inherits from the proper column type (BoundField, ButtonField, etc. for simple columns or TemplateField if you need to plug in your own template).

You can create your own properties for your custom column class (e.g., Text and ImageUrl), but if it's a TemplateField, you will have to actually loop through your cells to manipulate the data of the controls that comprise each cell. This is not hard to do, but it's not as easy as just using a BoundField and setting DataField property.

DanM
Great article, thanks! Although i need to figure out how to apply it to a custom collection of controls as mentioned above.
CodeSpeaker
+1  A: 

Alright i finally solved it, which means i can do the following

<%@ Register src="~/Controls/Core/ContextMenu.ascx" tagname="ContextMenu" tagprefix="uc" %>
<%@ Register Assembly="App_Code" Namespace="Core.Controls.ContextMenu" TagPrefix="cc"   %>

<uc:ContextMenu ID="ContextMenuMain" runat="server">
    <Items>
      <cc:ContextMenuItem Text="New" ImageUrl="..." />
      <cc:ContextMenuItem Text="Save" ImageUrl="..." />
    </Items>
</uc:ContextMenu>

Where each ContextMenuItem is a custom class in app code, notice that i have to register the app_code assembly in order for the markup to recognize the class. The namespace points to the location of the class. For the code behind of the usercontrol we just add this:

private List<ContextMenuItem> items = new List<ContextMenuItem>();

[PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<ContextMenuItem> Items
{
 get
 {
  if (items == null)
  {
   items = new List<ContextMenuItem>();
  }

  return items;
 }

 set
 {
  items = value;
 }
}

Which can be processed by the usercontrol when its time to render :)

CodeSpeaker
Sorry I got back to this to late but it looks like you got it anyway! :)
drs9222