0

我有一个类 BaseTemplate

public abstract class BaseTemplate : ITemplate

这添加了控件,并提供了在继承类中实现的抽象方法。然后继承类根据其数据源添加其html并管理数据绑定。

这一切都很好 - 我让控件显示为正确解析的 html。

问题是基类将控件添加到具有自己的 CommandName 参数的模板中;这个想法是实现自定义模板化 dataList 的类将提供设置 Selected 和 Edit Indexes 的逻辑。此类还管理数据绑定等。它在 Init 方法中设置 datalist 上的所有模板(这是此异常的另一个原因)。

当我点击这些按钮之一时会引发异常 - 我已经尝试在任何地方连接他们的点击和命令事件,以防这是问题所在。我还确保它们的命令名称与任何系统名称都不匹配。堆栈跟踪不包括对我的方法或对象的任何引用,这就是我如此卡住的原因。这是我能想象到的最无益的信息。

真正令人沮丧的是我无法触发断点 - 即问题发生在我单击按钮之后,但在我的代码可以执行之前和之前。

上次发生此异常是当我在用户控件中有此代码并将模板分配给 PageLoad 中的数据列表时。我将这些移入 init 以解决该问题;但是,这是当时存在的一个问题,我不知道是什么原因造成的,更不用说如何解决了(如果不知道什么索引,超出范围的索引并没有真正的帮助。)

异常详情

异常详细信息:System.ArgumentOutOfRangeException:指定的参数超出了有效值的范围。
参数名称:索引

堆栈跟踪:

[ArgumentOutOfRangeException:指定的参数超出了有效值的范围。
参数名称:索引]
   System.Web.UI.ControlCollection.get_Item(Int32 index) +8665582
   System.Web.UI.WebControls.DataList.GetItem(ListItemType itemType, Int32 repeatIndex) +8667655
       System.Web.UI.WebControls.DataList.System.Web.UI.WebControls.IRepeatInfoUser.GetItemStyle(ListItemType itemType, Int32 repeatIndex) +11
   System.Web.UI.WebControls.RepeatInfo.RenderVerticalRepeater(HtmlTextWriter writer, IRepeatInfoUser user, Style controlStyle, WebControl baseControl) +8640873
   System.Web.UI.WebControls.RepeatInfo.RenderRepeater(HtmlTextWriter writer, IRepeatInfoUser user, Style controlStyle, WebControl baseControl) +27
   System.Web.UI.WebControls.DataList.RenderContents(HtmlTextWriter 编写器)+208
   System.Web.UI.WebControls.BaseDataList.Render(HtmlTextWriter writer) +30
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27
   System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer)+25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter 作家,ICollection 孩子)+134
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)+19
   System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter 作家)+163
   System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer)+32
   System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter 输出)+51
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27
   System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99
   System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer) +40
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter 作家,ICollection 孩子)+134
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)+19
   System.Web.UI.Page.Render(HtmlTextWriter 作家)+29
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter 编写器,ControlAdapter 适配器)+27
   System.Web.UI.Control.RenderControl(HtmlTextWriter 编写器,ControlAdapter 适配器)+99
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer)+25
   System.Web.UI.Page.ProcessRequestMain(布尔 includeStagesBeforeAsyncPoint,布尔 includeStagesAfterAsyncPoint)+1266

编码

基类:

public abstract class BaseTemplate : ITemplate 
{
    ListItemType _templateType;
    public BaseTemplate(ListItemType theTemplateType)
    { _templateType = theTemplateType; }     

    public ListItemType ListItemType
    { get { return _templateType; } }

    #region ITemplate Members

    public void InstantiateIn(Control container)
    {
        PlaceHolder ph = new PlaceHolder();
        container.Controls.Add(ph);
    
        Literal l = new Literal();
        switch (_templateType)
        {
            case ListItemType.Header:
            {                         
                ph.Controls.Add(new LiteralControl(@"<table><tr>"));
                InstantiateInHeader(ph);
                ph.Controls.Add(new LiteralControl(@"</tr>"));
                break;
            }
            case ListItemType.Footer:
            {
                ph.Controls.Add(new LiteralControl(@"<tr>"));
                InstantiateInFooter(ph);
                ph.Controls.Add(new LiteralControl(@"</tr></table>"));
                break;
            }
            case ListItemType.Item:
            {
                ph.Controls.Add(new LiteralControl(@"<tr>"));
                InstantiateInItem(ph);
                ph.Controls.Add(new LiteralControl(@"<td>"));

                Button select = new Button();
                select.ID = "btnSelect";
                select.CommandName = "SelectRow";
                select.Text = "Select";
                ph.Controls.Add(select);

                ph.Controls.Add(new LiteralControl(@"</td>"));
                ph.Controls.Add(new LiteralControl(@"</tr>"));
                ph.DataBinding += new EventHandler(ph_DataBinding);

                break;
            }
            case ListItemType.AlternatingItem:
            {
                ph.Controls.Add(new LiteralControl(@"<tr>"));
                InstantiateInAlternatingItem(ph);
                ph.Controls.Add(new LiteralControl(@"<td>"));

                Button select = new Button();
                select.ID = "btnSelect";
                select.CommandName = "SelectRow";
                select.Text = "Select";
                ph.Controls.Add(select);

                ph.Controls.Add(new LiteralControl(@"</td>"));
                ph.Controls.Add(new LiteralControl(@"</tr>"));
                ph.DataBinding+=new EventHandler(ph_DataBinding);
                break;

            }
            case ListItemType.SelectedItem:
            {
                ph.Controls.Add(new LiteralControl(@"<tr>"));
                InstantiateInItem(ph);
                ph.Controls.Add(new LiteralControl(@"<td>"));

                Button edit = new Button();
                edit.ID = "btnEdit";
                edit.CommandName = "EditRow";
                edit.Text = "Edit";
                ph.Controls.Add(edit);

                Button delete = new Button();
                delete.ID = "btnDelete";
                delete.CommandName = "DeleteRow";
                delete.Text = "Delete";
                ph.Controls.Add(delete);

                ph.Controls.Add(new LiteralControl(@"</td>"));
                ph.Controls.Add(new LiteralControl(@"</tr>"));
                ph.DataBinding += new EventHandler(ph_DataBinding);
                break;
            }
            case ListItemType.EditItem:
            {
                ph.Controls.Add(new LiteralControl(@"<tr>"));
                InstantiateInEdit(ph);

                ph.Controls.Add(new LiteralControl(@"<td>"));

                Button save = new Button();
                save.ID = "btnSave";
                save.CommandName = "SaveRow";
                save.Text = "Save";
                ph.Controls.Add(save);

                Button cancel = new Button();
                cancel.ID = "btnCancel";
                cancel.CommandName = "CancelRow";
                cancel.Text = "Cancel";
                ph.Controls.Add(cancel);

                ph.Controls.Add(new LiteralControl(@"</td>"));
                ph.Controls.Add(new LiteralControl(@"</tr>"));
                ph.DataBinding += new EventHandler(ph_DataBinding);
                break;
            }
            case ListItemType.Separator:
            {
                InstantiateInSeperator(ph);
                break;
            }                     
        }            
    }

    void ph_DataBinding(object sender, EventArgs e)
    {
        DataBindingOverride(sender, e);
    }

    /// <summary>
    /// the controls placed into the PlaceHolder will get wrapped in &lt;table&gt;&lt;tr&gt;   &lt;/tr&gt;. I.e. you need to provide the column names wrapped in &lt;td&gt;&lt;/td&gt; tags.
    /// </summary>
    /// <param name="header"></param>
    public abstract void InstantiateInHeader(PlaceHolder ph);
    /// <summary>
    /// the controls will have a column added after them and so require each column to be properly wrapped in &lt;td&gt;&lt;/td&gt; tags. The &lt;tr&gt;&lt;/tr&gt; is handled in the base class.
    /// </summary>
    /// <param name="ph"></param>
    public abstract void InstantiateInItem(PlaceHolder ph);
    /// <summary>
    /// the controls will have a column added after them and so require each column to be properly wrapped in &lt;td&gt;&lt;/td&gt; tags. The &lt;tr&gt;&lt;/tr&gt; is handled in the base class.
    /// </summary>
    /// <param name="ph"></param>
    public abstract void InstantiateInAlternatingItem(PlaceHolder ph);
    /// <summary>
    /// the controls will have a column added after them and so require each column to be properly wrapped in &lt;td&gt;&lt;/td&gt; tags. The &lt;tr&gt;&lt;/tr&gt; is handled in the base class.
    /// </summary>
    /// <param name="ph"></param>
    public abstract void InstantiateInEdit(PlaceHolder ph);
    /// <summary>
    /// Any html used in the footer will have &lt;/tr&gt;&lt;table&gt; appended to the end.
    /// &lt;tr&gt; will be appended to the front.
    /// </summary>
    /// <param name="ph"></param>
    public abstract void InstantiateInFooter(PlaceHolder ph); 
    /// <summary>
    /// the controls will have a column added after them and so require each column to be properly wrapped in &lt;td&gt;&lt;/td&gt; tags. The &lt;tr&gt;&lt;/tr&gt; is handled in the base class.
    /// Adds Delete and Edit Buttons after the table contents.
    /// </summary>
    /// <param name="ph"></param>
    public abstract void InstantiateInSelectedItem(PlaceHolder ph);
    /// <summary>
    /// The base class provides no &lt;tr&gt;&lt;/tr&gt; tags
    /// </summary>
    /// <param name="ph"></param>
    public abstract void InstantiateInSeperator(PlaceHolder ph);        
    /// <summary>
    /// Use this method to bind the controls to their data.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public abstract  void DataBindingOverride(object sender, EventArgs e);

    #endregion
}

继承类:

public class NominalGroupTemplate : BaseTemplate 
{
    public NominalGroupTemplate(ListItemType theListItemType)
        : base(theListItemType) { }

    public override void InstantiateInHeader(PlaceHolder ph)
    {
        ph.Controls.Add(new LiteralControl(@"<td>ID</td><td>Group</td><td>IsPositive</td>"));
    }

    public override void InstantiateInItem(PlaceHolder ph)
    {
        ph.Controls.Add(new LiteralControl(@"<td>"));
        Label lblID = new Label();
        lblID.ID = "lblID";
        ph.Controls.Add(lblID);
        ph.Controls.Add(new LiteralControl(@"</td><td>"));
        Label lblGroup = new Label();
        lblGroup.ID = "lblGroup";
        ph.Controls.Add(lblGroup);
        ph.Controls.Add(new LiteralControl(@"</td><td>"));
        CheckBox chkIsPositive = new CheckBox();
        chkIsPositive.ID = "chkIsPositive";
        chkIsPositive.Enabled = false;
        ph.Controls.Add(chkIsPositive);
        ph.Controls.Add(new LiteralControl(@"</td>"));
    }

    public override void InstantiateInAlternatingItem(PlaceHolder ph)
    {
        InstantiateInItem(ph);
    }

    public override void InstantiateInEdit(PlaceHolder ph)
    {
        ph.Controls.Add(new LiteralControl(@"<td>"));
        Label lblID = new Label();
        lblID.ID = "lblID";
        ph.Controls.Add(lblID);
        ph.Controls.Add(new LiteralControl(@"</td><td>"));
        TextBox txtGroup = new TextBox();
        txtGroup.ID = "txtGroup";
        txtGroup.Visible = true;
        txtGroup.Enabled = true ;
        ph.Controls.Add(txtGroup);
        ph.Controls.Add(new LiteralControl(@"</td><td>"));
        CheckBox chkIsPositive = new CheckBox();
        chkIsPositive.ID = "chkIsPositive";
        chkIsPositive.Visible = true;
        chkIsPositive.Enabled = true ;
        ph.Controls.Add(chkIsPositive);
        ph.Controls.Add(new LiteralControl(@"</td>")); 
    }

    public override void InstantiateInFooter(PlaceHolder ph)
    {
        InstantiateInHeader(ph); 
    }

    public override void InstantiateInSelectedItem(PlaceHolder ph)
    {
        ph.Controls.Add(new LiteralControl(@"<td>"));
        Label lblID = new Label();
        lblID.ID = "lblID";
        ph.Controls.Add(lblID);
        ph.Controls.Add(new LiteralControl(@"</td><td>"));
        TextBox txtGroup = new TextBox();
        txtGroup.ID = "txtGroup";
        txtGroup.Visible = true;
        txtGroup.Enabled = false;
        ph.Controls.Add(txtGroup);
        ph.Controls.Add(new LiteralControl(@"</td><td>"));
        CheckBox chkIsPositive = new CheckBox();
        chkIsPositive.ID = "chkIsPositive";
        chkIsPositive.Visible = true;
        chkIsPositive.Enabled = false;
        ph.Controls.Add(chkIsPositive);
        ph.Controls.Add(new LiteralControl(@"</td>"));  
    }

    public override void InstantiateInSeperator(PlaceHolder ph)
    {             
    }

    public override void DataBindingOverride(object sender, EventArgs e)
    {
        PlaceHolder ph = (PlaceHolder)sender;
        DataListItem li = (DataListItem)ph.NamingContainer;
        int id = Convert.ToInt32(DataBinder.Eval(li.DataItem, "ID"));
        string group = (string)DataBinder.Eval(li.DataItem, "Group");
        bool isPositive = Convert.ToBoolean(DataBinder.Eval(li.DataItem, "IsPositive"));
        switch (this.ListItemType)
        {
            case ListItemType.Item:
            case ListItemType.AlternatingItem:
            {                         
                ((Label)ph.FindControl("lblID")).Text = id.ToString();
                ((Label)ph.FindControl("lblGroup")).Text = group;
                ((CheckBox)ph.FindControl("chkIsPositive")).Text = isPositive.ToString();
                break;
            }
            case ListItemType.EditItem:
            case ListItemType.SelectedItem:
            {
                ((TextBox)ph.FindControl("lblID")).Text = id.ToString();
                ((TextBox)ph.FindControl("txtGroup")).Text = group;
                ((CheckBox)ph.FindControl("chkIsPositive")).Text = isPositive.ToString();
                break;
            }   
        }
    }
}

从这里我将控件添加到页面后面的代码

 public partial class NominalGroupbroke : System.Web.UI.UserControl
{
    public void SetNominalGroupList(IList<BONominalGroup> theNominalGroups)
    {
        XElement data = Serialiser<BONominalGroup>.SerialiseObjectList(theNominalGroups);
        ViewState.Add("nominalGroups", data.ToString());
        dlNominalGroup.DataSource = theNominalGroups;
        dlNominalGroup.DataBind();
    }

    protected void Page_init()
    {
        dlNominalGroup.HeaderTemplate = new NominalGroupTemplate(ListItemType.Header);
        dlNominalGroup.ItemTemplate = new NominalGroupTemplate(ListItemType.Item);
        dlNominalGroup.AlternatingItemTemplate = new NominalGroupTemplate(ListItemType.AlternatingItem);
        dlNominalGroup.SeparatorTemplate = new NominalGroupTemplate(ListItemType.Separator);
        dlNominalGroup.SelectedItemTemplate = new NominalGroupTemplate(ListItemType.SelectedItem);
        dlNominalGroup.EditItemTemplate = new NominalGroupTemplate(ListItemType.EditItem);
        dlNominalGroup.FooterTemplate = new NominalGroupTemplate(ListItemType.Footer);
    } 

    protected void Page_Load(object sender, EventArgs e)
    {          
        dlNominalGroup.ItemCommand += new DataListCommandEventHandler(dlNominalGroup_ItemCommand);
    }

    void dlNominalGroup_Init(object sender, EventArgs e)
    {
        dlNominalGroup.HeaderTemplate = new NominalGroupTemplate(ListItemType.Header);
        dlNominalGroup.ItemTemplate = new NominalGroupTemplate(ListItemType.Item);
        dlNominalGroup.AlternatingItemTemplate = new NominalGroupTemplate(ListItemType.AlternatingItem);
        dlNominalGroup.SeparatorTemplate = new NominalGroupTemplate(ListItemType.Separator);
        dlNominalGroup.SelectedItemTemplate = new NominalGroupTemplate(ListItemType.SelectedItem);
        dlNominalGroup.EditItemTemplate = new NominalGroupTemplate(ListItemType.EditItem);
        dlNominalGroup.FooterTemplate = new NominalGroupTemplate(ListItemType.Footer);
    }

    void dlNominalGroup_DataBinding(object sender, EventArgs e)
    {
    }

    void deleteNominalGroup(int index)
    {
        XElement data = XElement.Parse(Convert.ToString( ViewState["nominalGroups"] ));
        IList<BONominalGroup> list = Serialiser<BONominalGroup>.DeserialiseObjectList(data);
        FENominalGroup.DeleteNominalGroup(list[index].ID);
        list.RemoveAt(index);
        data = Serialiser<BONominalGroup>.SerialiseObjectList(list);
        ViewState["nominalGroups"] = data.ToString();
        dlNominalGroup.DataSource = list;
        dlNominalGroup.DataBind();
    }

    void updateNominalGroup(DataListItem theItem)
    {
        XElement data = XElement.Parse(Convert.ToString(  ViewState["nominalGroups"]));
        IList<BONominalGroup> list = Serialiser<BONominalGroup>.DeserialiseObjectList(data);
        BONominalGroup old = list[theItem.ItemIndex];

        BONominalGroup n = new BONominalGroup();
        byte id = Convert.ToByte(((TextBox)theItem.FindControl("lblID")).Text);
        string group = ((TextBox)theItem.FindControl("txtGroup")).Text;
        bool isPositive = Convert.ToBoolean(((CheckBox)theItem.FindControl("chkIsPositive")).Text);
        n.ID = id;
        n.Group = group;
        n.IsPositive = isPositive;

        FENominalGroup.UpdateNominalGroup(old, n);

        list[theItem.ItemIndex] = n;
        data = Serialiser<BONominalGroup>.SerialiseObjectList(list);
        ViewState["nominalGroups"] = data.ToString();
    }

    void dlNominalGroup_ItemCommand(object source, DataListCommandEventArgs e)
    {
        DataList l = (DataList)source;
        switch (e.CommandName)
        {
            case "SelectRow":
            {
                if (l.EditItemIndex == -1)
                {
                    l.SelectedIndex = e.Item.ItemIndex;
                    l.EditItemIndex = -1;
                }
                break;
            }
            case "EditRow":
            {
                if (l.SelectedIndex == e.Item.ItemIndex)
                {
                    l.EditItemIndex = e.Item.ItemIndex;
                }
                break;
            }
            case "DeleteRow":
            {
                deleteNominalGroup(e.Item.ItemIndex);
                l.EditItemIndex = -1;
                try
                {
                    l.SelectedIndex = e.Item.ItemIndex;
                }
                catch
                {
                    l.SelectedIndex = -1;
                }
                break;
            }
            case "CancelRow":
            {
                l.SelectedIndex = l.EditItemIndex;
                l.EditItemIndex = -1;  
                break;
            }
            case "SaveRow":
            {
                updateNominalGroup(e.Item);
                try
                {
                    l.SelectedIndex = e.Item.ItemIndex;
                }
                catch 
                {
                    l.SelectedIndex = -1;
                }
                l.EditItemIndex = -1; 
                break;
            }
        }
    }   

恐怕那里有很多代码,但它应该构建。

谢谢,如果有人设法发现我的愚蠢。

BOnominalGroup 类(请忽略我疯狂的 getHash 覆盖,我并不以此为荣)。
IAudit 在这里可以只是一个空界面,一切都会好起来的。
它曾经是从另一个类继承的,我已经把它清理掉了——所以这里的序列化逻辑可能会被破坏。

public class BONominalGroup 
{  
    public BONominalGroup()
         

    #region Fields and properties
    private Int16 _ID;
    public Int16 ID
    {
        get { return _ID; }
        set { _ID = value; }
    }  
        
    private string _group;
    public string Group
    {
        get { return _group; }
        set { _group = value; }
    }

    private bool _isPositve;
    public bool IsPositive
    {
        get { return _isPositve; }
        set { _isPositve = value; }
    }
    #endregion

    public override bool Equals(object obj)
    {
        bool retVal = false;
        BONominalGroup ng = obj as BONominalGroup;
            
        if (ng!=null)
            if (ng._group == this._group &&
                ng._ID == this.ID &&
                ng.IsPositive == this.IsPositive)
            {
                retVal = true;
            }
        return retVal;
    } 
    public override int GetHashCode()
    {
        return ToString().GetHashCode();
    }    
    public override string ToString()
    {
        return "BONominalGroup{ID:" + this.ID.ToString() +
              ",Group:" + this.Group.ToString() +
              ",IsPositive:" + this.IsPositive.ToString() +
              "," + "}";
    }

    #region IXmlSerializable Members
    public override void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement("BONominalGroup");
        this.ID = Convert.ToByte(reader.ReadElementString("id"));
        this.Group = reader.ReadElementString("group");
        this.IsPositive = Convert.ToBoolean(reader.ReadElementString("isPositive"));
        base.ReadXml(reader);
        reader.ReadEndElement();
    }

    public override void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("id", this.ID.ToString());
        writer.WriteElementString("group", this.Group);
        writer.WriteElementString("isPositive", this.IsPositive.ToString());
    //    writer.WriteStartElement("BOBase");
    //    base.WriteXml(writer);
        writer.WriteEndElement();
    }
    #endregion
}
4

1 回答 1

4

你有方法

void deleteNominalGroup(int index)

它执行以下代码行(使用 index 参数)

FENominalGroup.DeleteNominalGroup(list[index].ID);

这就是list[index]我认为抛出越界异常的原因。ItemCommand我认为这是因为您在swtich 语句中调用了该方法

case "DeleteRow":
    {
       deleteNominalGroup(e.Item.ItemIndex);

e.Item.ItemIndex导致您的问题。您将要检查此值并且该项目不是页眉/页脚等。我建议(为了理智)将以下检查添加到您的deleteNominalGroup方法中

 void deleteNominalGroup(int index)
 {
      if ((index < 0) || (index > list.Count())
           return;
于 2010-03-25T15:27:33.647 回答