【问题标题】:GridView RowEditing event only fires on alternate rowsGridView RowEditing 事件仅在备用行上触发
【发布时间】:2013-12-11 11:55:11
【问题描述】:

我有一个 GridView 如下:

<asp:GridView ID="gvChain" runat="server" Font-Size="Small" CellPadding="3" CellSpacing="1" GridLines="None"
                AutoGenerateColumns="False">
                <HeaderStyle BackColor="#CCCCCC" />
                <Columns>                       
                    <asp:TemplateField HeaderText="Department" ControlStyle-Width="175px">
                        <EditItemTemplate>
                            <asp:Label ID="lblDepartment" runat="server" Text='<%# Bind("Department") %>'></asp:Label>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="lblDepartment" runat="server" Text='<%# Bind("Department") %>'></asp:Label>
                        </ItemTemplate>
                        <ControlStyle Width="175px" />
                    </asp:TemplateField>

                    <asp:TemplateField HeaderText="Manager Level 1" ControlStyle-Width="175px">
                        <ItemTemplate>
                            <asp:Label ID="lblManager1" runat="server" Text=""></asp:Label>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:DropDownList ID="cbManager1" runat="server"></asp:DropDownList>
                        </EditItemTemplate>
                        <ControlStyle Width="175px" />
                    </asp:TemplateField>

                    <asp:TemplateField HeaderText="Manager Level 2" ControlStyle-Width="175px">
                        <ItemTemplate>
                            <asp:Label ID="lblManager2" runat="server" Text=""></asp:Label>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:DropDownList ID="cbManager2" runat="server"></asp:DropDownList>
                        </EditItemTemplate>
                        <ControlStyle Width="175px" />
                    </asp:TemplateField>

                    <asp:TemplateField>
                        <ItemTemplate>
                            <asp:LinkButton ID="btnEdit" CommandName="Edit" runat="server" Text="Edit" CssClass="buttonStyle" CausesValidation="false"/>
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:LinkButton ID="btnSave" CommandName="Update" runat="server" Text="Save" CssClass="buttonStyle" CausesValidation="false"/>
                            <asp:LinkButton ID="btnCancel" CommandName="Cancel" runat="server" Text="Cancel" CssClass="buttonStyle" CausesValidation="false" />
                        </EditItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField>
                        <ItemTemplate>
                            <asp:LinkButton ID="btnDelete" CommandName="Delete" runat="server" Text="Delete" CssClass="buttonStyle" CausesValidation="false" />
                        </ItemTemplate>      
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>

BoundField 填充在 Page_Load 事件中,如下所示:

Dim dHandler As DepartmentHandler = New DepartmentHandler
    Dim depts As New List(Of Department)
    depts = dHandler.GetDepartmentList
    gvChain.DataSource = depts.

If Not Page.IsPostBack Then
       gvChain.DataBind()
End If

然后在 RowDataBound 事件中填充 TemplateFields,如下所示:

If e.Row.RowType = DataControlRowType.DataRow Then

        If e.Row.RowState = DataControlRowState.Edit Then

            Dim cbManager1 As DropDownList = TryCast(e.Row.FindControl("cbManager1"), DropDownList)
            Dim cbManager2 As DropDownList = TryCast(e.Row.FindControl("cbManager2"), DropDownList)

            Dim eHandler As EmployeeHandler = New EmployeeHandler

            ' Get the list of managers
            Dim mgrs As New List(Of Manager)
            mgrs = eHandler.GetManagerList
            cbManager1.DataSource = mgrs
            cbManager2.DataSource = mgrs
            cbManager1.DataValueField = "Name"
            cbManager1.DataTextField = "Name"
            cbManager2.DataValueField = "Name"
            cbManager2.DataValueField = "Name"
            cbManager1.DataBind()
            cbManager2.DataBind()

            ' Get the department name from the label in cell 0
            Dim lbl As Label = e.Row.Cells(0).FindControl("lblDepartment")
            Dim dept As Department = New Department
            dept.Department = lbl.Text

            ' Pass the department name to the getManager1/2 functions to return the correct manager for that department
            Dim mgr1 As Manager = eHandler.getManager1(dept)
            Dim mgr2 As Manager = eHandler.getManager2(dept)

            ' Upper case the manager name to search the DDLs for item
            Dim mgr1Name As String = mgr1.Name.ToUpper()
            Dim mgr2Name As String = mgr2.Name.ToUpper()

            ' Find the manager in the DDL and select
            cbManager1.SelectedValue = mgr1Name
            cbManager2.SelectedValue = mgr2Name
        Else
            ' If GV isnt in edit mode then populate labels in itemtemplate with manager 1 and 2 values
            Dim lblManager1 As Label = DirectCast(e.Row.FindControl("lblManager1"), Label)
            Dim lblManager2 As Label = DirectCast(e.Row.FindControl("lblManager2"), Label)


            Dim eHandler As EmployeeHandler = New EmployeeHandler
            Dim lbl As Label = e.Row.Cells(0).FindControl("lblDepartment")
            Dim dept As Department = New Department
            dept.Department = lbl.Text
            Dim mgr1 As Manager = eHandler.getManager1(dept)
            Dim mgr2 As Manager = eHandler.getManager2(dept)

            lblManager1.Text = mgr1.Name
            lblManager2.Text = mgr2.Name
        End If
    End If

然后我在 RowEditing 事件中有以下内容

gvChain.EditIndex = e.NewEditIndex
gvChain.DataBind()

当 GridView 中只显示 1 条记录时,我单击编辑按钮,GridView 进入编辑模式,我可以使用 RowUpdating 事件更新该记录,这工作正常。但是,如果我向 GridView 添加另一条记录,则单击该记录的编辑按钮会产生 NullReference 异常。如果我再添加另一条记录,则第三条记录将进入编辑模式。第 4 条记录将再次失败,并出现 NullReference 异常等等。

调试时,似乎在行索引 1、3、5 等上,GridView 没有进入编辑模式,但在行索引 0、2、4 等上,GridView 将切换到编辑模式。

这看起来真的很奇怪。有什么想法可能导致 GridView 在这些行上不进入编辑模式?

【问题讨论】:

    标签: asp.net vb.net gridview


    【解决方案1】:

    行的状态可以是 DataControlRowState 值之一或组合,因此请使用按位运算来确定行的状态是否包含 DataControlRowState 值。 here

    RowState 包含多个使用位逻辑的值(Alternate | Edit,如果您在编辑模式期间检查 RowState 属性)。

    试试

     If (e.Row.RowState And DataControlRowState.Edit) > 0 Then
    

    【讨论】:

    • 试过了,不幸的是它仍然不起作用,当单击行索引 1、3、5 等中的编辑按钮时,GridView 仍然没有进入编辑模式。
    【解决方案2】:

    我通过修改 getDepartmentList 函数以返回 Manager1 和 Manager 2 字段然后将它们数据绑定到与绑定“部门”相同的数据来解决这个问题。

    然后我将 RowDataBound 事件修改为以下内容:

    If e.Row.RowType = DataControlRowType.DataRow Then
    
            If e.Row.RowState And DataControlRowState.Edit Then
    
                Dim cbManager1 As DropDownList = TryCast(e.Row.FindControl("cbManager1"), DropDownList)
                Dim cbManager2 As DropDownList = TryCast(e.Row.FindControl("cbManager2"), DropDownList)
    
                Dim eHandler As EmployeeHandler = New EmployeeHandler
    
                ' Get the list of managers
                Dim mgrs As New List(Of Manager)
                mgrs = eHandler.GetManagerList
                cbManager1.DataSource = mgrs
                cbManager2.DataSource = mgrs
                cbManager1.DataValueField = "Name"
                cbManager1.DataTextField = "Name"
                cbManager2.DataValueField = "Name"
                cbManager2.DataValueField = "Name"
                cbManager1.DataBind()
                cbManager2.DataBind()
    
                ' Get the department name from the label in cell 0
                Dim lbl As Label = e.Row.Cells(0).FindControl("lblDepartment")
                Dim dept As Department = New Department
                dept.Department = lbl.Text
    
                ' Pass the department name to the getManager1/2 functions to return the correct manager for that department
                Dim mgr1 As Manager = eHandler.getManager1(dept)
                Dim mgr2 As Manager = eHandler.getManager2(dept)
    
                ' Upper case the manager name to search the DDLs for item
                Dim mgr1Name As String = mgr1.Name.ToUpper()
                Dim mgr2Name As String = mgr2.Name.ToUpper()
    
                ' Find the manager in the DDL and select
                cbManager1.SelectedValue = mgr1Name
                cbManager2.SelectedValue = mgr2Name
            End If
    
        End If
    

    【讨论】:

      猜你喜欢
      • 2012-10-21
      • 2012-09-10
      • 1970-01-01
      • 1970-01-01
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多