Reputation: 11
I have created a custom gridview control that inherits the asp.net gridview. I am required to use item templates in this gridview. I create a method in my custom gridview that generates the item template.
public void addTemplateField(Control headerTemplateControl, Control itemTemplateControl, EventHandler bindHandler, EventHandler initHandler, string headerText, string sortExpression, bool isVisible, int? heightPx, int? widthPercent)
{
TemplateField tField = new TemplateField();
if (headerTemplateControl != null)
tField.HeaderTemplate = new GridViewTemplate(ListItemType.Header, headerTemplateControl);
if (bindHandler != null && initHandler != null)
tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl, bindHandler, initHandler);
else if (bindHandler != null)
tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl, bindHandler, false);
else if (initHandler != null)
tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl, initHandler, true);
else
tField.ItemTemplate = new GridViewTemplate(ListItemType.Item, itemTemplateControl);
if (sortExpression != null)
tField.SortExpression = sortExpression;
tField.Visible = isVisible;
if (headerText != null)
tField.HeaderText = headerText;
if (heightPx.HasValue)
tField.HeaderStyle.Height = new Unit(heightPx.Value, UnitType.Pixel);
if (widthPercent.HasValue)
tField.HeaderStyle.Height = new Unit(widthPercent.Value, UnitType.Percentage);
addColumnField(tField);
}
And this is how I have implemented ITemplate
public class GridViewTemplate : ITemplate
{
int _controlCount = 0;
ListItemType _templateType;
EventHandler _bindHandler;
EventHandler _initHandler;
Control _control;
public GridViewTemplate(ListItemType type, Control control)
{
this._templateType = type;
this._control = control;
}
public GridViewTemplate(ListItemType type, Control control, EventHandler Handler, bool isInitHandler)
{
this._templateType = type;
this._control = control;
if (isInitHandler)
this._initHandler = Handler;
else
this._bindHandler = Handler;
}
public GridViewTemplate(ListItemType type, Control control, EventHandler bindHandler, EventHandler initHandler)
{
this._templateType = type;
this._control = control;
this._bindHandler = bindHandler;
this._initHandler = initHandler;
}
public Control Copy(Control ctrlSource)
{
Type _type = ctrlSource.GetType();
Control ctrlDest = (Control)Activator.CreateInstance(_type);
foreach (PropertyInfo prop in _type.GetProperties())
{
if (prop.CanWrite)
{
if (prop.Name == "ID")
{
ctrlDest.ID = ctrlSource.ID + "_copy_" + _controlCount;
}
else
{
prop.SetValue(ctrlDest, prop.GetValue(ctrlSource, null), null);
}
}
}
_controlCount++;
return ctrlDest;
}
public void InstantiateIn(Control container)
{
switch (_templateType)
{
case ListItemType.Header:
container.Controls.Add(_control);
break;
case ListItemType.Item:
Control temp = Copy(_control);
if(_bindHandler != null)
temp.DataBinding += _bindHandler;
if (_initHandler != null)
temp.Init += _initHandler;
container.Controls.Add(temp);
break;
}
}
}
In the page that needs say Default.aspx.cs, I create this gridview onPreInit and attach its event handlers onInit.
I add a checkbox to the grid by calling the addTemplateField().
cbl = new CheckBox();
cbl.AutoPostBack = true;
init = new EventHandler(cbl_Init);
grd.addTemplateField(null, cbl, null, init, "SERVER", null, true, 20, 20);
void cbl_Init(object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
c.CheckedChanged +=new EventHandler(cbl_CheckedChanged);
}
void cbl_CheckedChanged(object sender, EventArgs e)
{
// Modify datasource
// databind();
// if i remove this databind, checkchanged is handled every time. If i keep the databind, event is handled only alternate times. }
The issue is the checkbox checkchanged event is fired for alternate times. Every other time, the page post backs but the checkchanged event is not handled. I am lost in finding the cause, let alone the solution.!?!?!
Upvotes: 0
Views: 1323
Reputation: 11
I found the root cause of the problem. It was in the Copy method of the gridviewtemplate class. The problem being for each postback, the controls generated were being done in a unique id. So on postback the event triggered by the control, had changed its id, so no event was triggered.
To be more crystal...
Solution was to remove the control count variable.
Upvotes: 1