简体   繁体   English

动态Gridview-项目模板控件事件处理

[英]Dynamic Gridview - item template control event handling

I have created a custom gridview control that inherits the asp.net gridview. 我创建了一个自定义的gridview控件,该控件继承了asp.net gridview。 I am required to use item templates in this gridview. 我需要在此gridview中使用项目模板。 I create a method in my custom gridview that generates the item template. 我在自定义gridview中创建一个生成项目模板的方法。

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 这就是我实现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. 在需要显示Default.aspx.cs的页面中,我创建此gridview onPreInit并附加其事件处理程序onInit。

I add a checkbox to the grid by calling the addTemplateField(). 我通过调用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. //如果删除此数据绑定,则每次都会处理checkchanged。 If i keep the databind, event is handled only alternate times. 如果我保留databind,则事件仅交替处理一次。 } }

The issue is the checkbox checkchanged event is fired for alternate times. 问题是复选框checkchanged事件在备用时间触发。 Every other time, the page post backs but the checkchanged event is not handled. 每隔一次,页面回发一次,但是checkchanged事件未处理。 I am lost in finding the cause, let alone the solution.!?!?! 我迷失了寻找原因,更不用说解决了。

I found the root cause of the problem. 我找到了问题的根本原因。 It was in the Copy method of the gridviewtemplate class. 它在gridviewtemplate类的Copy方法中。 The problem being for each postback, the controls generated were being done in a unique id. 问题在于每次回发,生成的控件都是在唯一的ID中完成的。 So on postback the event triggered by the control, had changed its id, so no event was triggered. 因此,在回发时,控件触发的事件已更改了其ID,因此未触发任何事件。

To be more crystal... 为了更加水晶...

  1. Page loads initially with controls having a unique id, 页面最初使用具有唯一ID的控件加载,
  2. Click on the control to trigger an event 单击控件以触发事件
  3. The page post backs with the controls being generated with the same id. 该页面回传带有相同ID的控件。
  4. Click on the control to trigger the event. 单击控件以触发事件。
  5. The page posts back, but the controls are generated with a different it that does not match the event source of step 4. 该页面回发,但是生成的控件与步骤4的事件源不匹配。

Solution was to remove the control count variable. 解决方案是删除控件计数变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM