尝试在gridview上更新/取消时无法加载viewstate?

时间:2011-11-16 19:41:51

标签: c# asp.net gridview

背景

我有GridView使用ObjectDataSource构建表格。此源为选择和更新段使用Web服务。在修改部分下,点击后,针对需要修改的两列显示DropDownListDropDownList都使用单独的ObjectDataSource存储Web服务来获取要存储在此DropDownList中的值。

目前正在运作

目前,所有上述工作。当我加载页面时,表格会显示正确的数据。当我单击编辑按钮时,两个DropDownList会从WebService中获取存储在其中的正确数据。

问题

当我选择更新数据库的选项或选择取消时,页面会抛出错误并失败。我不完全确定为什么会发生这种情况,除了它与绑定未正确处理有关。我想知道如何绑定从更新数据库时要使用的DropDownList获取的值?

下面你会找到我到目前为止所尝试的内容:

<asp:GridView ID="GridViewHolder" 
                          runat="server" 
                          AllowPaging="True" 
                          AutoGenerateColumns="False" 
                          BackColor="Transparent" 
                          BorderColor="#999999" 
                          BorderStyle="Ridge" 
                          BorderWidth="3px" 
                          CellPadding="4" 
                          CellSpacing="2" 
                          DataSourceID="MachineDataSet" 
                          ForeColor="Black" 
                          HeaderStyle-HorizontalAlign="Center" 
                          HorizontalAlign="Center"  
                          RowStyle-HorizontalAlign="Center" Width="574px"
                          OnRowUpdating="GridViewHolder_Updating"
                          OnRowCancelingEdit="GridViewHolder_Canceling"
                          OnRowUpdated="GridViewHolder_Updated"
                          OnRowEditing="GridViewHolder_Editing">
                <RowStyle BackColor="Transparent" HorizontalAlign="Center" />
                <Columns>
                    <asp:BoundField DataField="ID" 
                                    HeaderText="ID" 
                                    SortExpression="ID" 
                                    Visible="False" />
                    <asp:BoundField DataField="SiteName" 
                                    HeaderText="Site Name" 
                                    SortExpression="SiteName"
                                    ReadOnly="true" />
                    <asp:BoundField DataField="Name" 
                                    HeaderText="Machine Name" 
                                    ReadOnly="true" 
                                    SortExpression="Name" />
                    <asp:TemplateField HeaderText="Machine Type" SortExpression="MachineType">
                        <EditItemTemplate>
                            <asp:ObjectDataSource ID="GetMachineType" 
                                                  runat="server" 
                                                  SelectMethod="GetMachineTypeList" 
                                                  TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
                                <SelectParameters>
                                    <asp:Parameter Name="siteid" Type="String" />
                                </SelectParameters>
                            </asp:ObjectDataSource>
                            <asp:DropDownList ID="MachineTypeDropDown" 
                                              runat="server" 
                                              AppendDataBoundItems="True" 
                                              DataSourceID="GetMachineType" 
                                              DataTextField="Name" 
                                              DataValueField="ID"                                               
                                              Height="21px" 
                                              Width="217px">
                                <asp:ListItem Enabled="true" 
                                              Text="Select a Machine Type.">
                                </asp:ListItem>
                            </asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" 
                                       runat="server" 
                                       Text='<%# Bind("MachineType") %>'>
                            </asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Machine Model" SortExpression="MachineModel">
                        <EditItemTemplate>
                            <asp:ObjectDataSource ID="GetMachineModel" 
                                                  runat="server" 
                                                  SelectMethod="GetMachineModelList" 
                                                  TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
                                <SelectParameters>
                                    <asp:Parameter Name="siteid" Type="String" />
                                </SelectParameters>
                            </asp:ObjectDataSource>
                            <asp:DropDownList ID="MachineModelDropDown" 
                                              runat="server" 
                                              AppendDataBoundItems="True" 
                                              DataSourceID="GetMachineModel" 
                                              DataTextField="Name" 
                                              DataValueField="ID"                                               
                                              Height="21px" 
                                              Width="217px">
                                <asp:ListItem Enabled="true" 
                                              Text="Select a Machine Model."
                                              Value="NULL">
                                </asp:ListItem>
                            </asp:DropDownList>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label2" 
                                       runat="server" 
                                       Text='<%# Bind("MachineModel") %>'>
                            </asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:CommandField ButtonType="Button" ShowEditButton="True" />
                </Columns>
                <FooterStyle BackColor="Transparent" />
                <PagerStyle BackColor="Transparent" 
                            ForeColor="Black" 
                            HorizontalAlign="Left" />
                <SelectedRowStyle BackColor="Transparent" 
                                  Font-Bold="True" 
                                  ForeColor="White" />
                <HeaderStyle BackColor="Black" 
                             Font-Bold="True" 
                             ForeColor="White" 
                             HorizontalAlign="Center" />
         </asp:GridView>

问题似乎存在于以下区域:

<asp:TemplateField HeaderText="Machine Type" 
    SortExpression="MachineType">
    <EditItemTemplate>
        <asp:ObjectDataSource ID="GetMachineType" 
            runat="server" 
            SelectMethod="GetMachineTypeList" 
            TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
            <SelectParameters>
                <asp:Parameter Name="siteid" Type="String" />
            </SelectParameters>
        </asp:ObjectDataSource>
        <asp:DropDownList ID="MachineTypeDropDown" 
            runat="server" 
            DataSourceID="GetMachineType"
            DataTextField="Name"
            DataValueField="ID"                                               
            Height="21px" 
            Width="217px"
            AppendDataBoundItems="true">
            <asp:ListItem Enabled="true"
                Selected="True"
                Text="Select a Machine Type.">                                 
            </asp:ListItem>
        </asp:DropDownList>
    </EditItemTemplate>
    <ItemTemplate>
        <asp:Label ID="Label1" 
            runat="server" 
            Text='<%# Bind("MachineType") %>'>
        </asp:Label>
    </ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Machine Model" 
    SortExpression="MachineModel">
    <EditItemTemplate>
        <asp:ObjectDataSource ID="GetMachineModel" 
            runat="server" 
            SelectMethod="GetMachineModelList" 
            <asp:TemplateField HeaderText="Machine Type" SortExpression="MachineType">
                    <EditItemTemplate>
                        <asp:ObjectDataSource ID="GetMachineType" 
                                              runat="server" 
                                              SelectMethod="GetMachineTypeList" 
                                              TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
                            <SelectParameters>
                                <asp:Parameter Name="siteid" Type="String" />
                            </SelectParameters>
                        </asp:ObjectDataSource>
                        <asp:DropDownList ID="MachineTypeDropDown" 
                                          runat="server" 
                                          AppendDataBoundItems="True" 
                                          DataSourceID="GetMachineType" 
                                          DataTextField="Name" 
                                          DataValueField="ID"                                               
                                          Height="21px" 
                                          Width="217px">
                            <asp:ListItem Enabled="true" 
                                          Text="Select a Machine Type.">
                            </asp:ListItem>
                        </asp:DropDownList>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="Label1" 
                                   runat="server" 
                                   Text='<%# Bind("MachineType") %>'>
                        </asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Machine Model" SortExpression="MachineModel">
                    <EditItemTemplate>
                        <asp:ObjectDataSource ID="GetMachineModel" 
                                              runat="server" 
                                              SelectMethod="GetMachineModelList" 


TypeName="Datamart.UI.Reporting.Web.FilteredReportInputsSvc.FilteredReportInputsService">
                            <SelectParameters>
                                <asp:Parameter Name="siteid" Type="String" />
                            </SelectParameters>
                        </asp:ObjectDataSource>
                        <asp:DropDownList ID="MachineModelDropDown" 
                                          runat="server" 
                                          AppendDataBoundItems="True" 
                                          DataSourceID="GetMachineModel" 
                                          DataTextField="Name" 
                                          DataValueField="ID"                                               
                                          Height="21px" 
                                          Width="217px">
                            <asp:ListItem Enabled="true" 
                                          Text="Select a Machine Model."
                                          Value="NULL">
                            </asp:ListItem>
                        </asp:DropDownList>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="Label2" 
                                   runat="server" 
                                   Text='<%# Bind("MachineModel") %>'>
                        </asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>

已更新为赏金

我的整体问题是:使用gridview,我无法让我的编辑,更新,取消按钮工作。因此,我想知道的是,因为我正在为此投掷奖金:我如何才能使用ObjectDataSource s使这些事件正常工作?

我已经知道Web服务正常工作,我只是不知道如何使用表中正确的数据值加载必要的参数。非常感谢任何帮助或建议。

此时出现错误:

  

无法加载视图状态。控制树成   正在加载哪个viewstate必须匹配   用于保存视图状态的控制树   在上一个请求期间。例如,何时   动态添加控件,添加控件   在回发期间必须匹配类型和   在期间添加的控件的位置   初始请求。

我不确定如何正确启动更新和取消事件,因此我一直在尝试使用OnRow*事件处理程序,但这些都不起作用或触发,即使我设置了方法的断点只是为了查看事件是否会触发。

UPDATE2

所以这里要求的是处理我认为可能引发的事件背后的代码,(注意:我已经尝试了几乎所有其他事件)。当我运行调试器将页面附加到asp.net进程并单击更新按钮,取消按钮或编辑按钮时,我希望页面转到断点,但这不会发生。

注意:我也知道后面的代码很可能是不正确的,但我不想解决任何问题,直到我知道哪个事件是正确的触发更新和取消按钮。

    protected void GridViewHolder_Updating(object sender, GridViewUpdateEventArgs e) 
{

    int machineid;
    string machineTypeid;
    string machineModelid;

    GridViewRow row = (GridViewRow)GridViewHolder.Rows[e.RowIndex];
    Label id = (Label)row.FindControl("ID");
    DropDownList mType1 = GridViewHolder.Rows[e.RowIndex].FindControl("MachineTypeDropDown") as DropDownList;
    e.NewValues["MachineType"] = mType1.SelectedValue;
    DropDownList mType = (DropDownList)row.FindControl("Machine_Type");
    DropDownList mModel = (DropDownList)row.FindControl("Machine_Model");

    machineid = Convert.ToInt32(id);
    machineTypeid = mType.DataValueField.ToString();
    machineModelid = mModel.DataValueField.ToString();

    inputsService.UpdateMachineTypes(machineid, machineTypeid);
    inputsService.UpdateMachineModels(machineid, machineModelid);

}

protected void GridViewHolder_Updated(object sender, GridViewUpdatedEventArgs e)
{

}

/// <summary>
/// Handles the Click event of the cancel button under edit in the gridview control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Web.UI.WebControls.GridViewCancelEditEventArgs"/> instance containing the event data.</param>
protected void GridViewHolder_Canceling(object sender, GridViewCancelEditEventArgs e)
{
    //reset the edit index
    GridViewHolder.EditIndex = -1;
    //Bind data to GridViewHolder
    BindData();
}

protected void GridViewHolder_Editing(object sender, GridViewEditEventArgs e)
{

}
#endregion

#region Private Methods

private void BindData()
{
    GridViewHolder.DataSource = Session["MachineTable"];
    GridViewHolder.DataBind();
}

#endregion

更新3

好的,您将在上面找到我最近尝试尝试获取更新和取消按钮以在gridview中正常运行的尝试。

非常感谢任何帮助或建议。

谢谢。

3 个答案:

答案 0 :(得分:2)

我怀疑ViewState错误是由代码隐藏的代码引起的,并且不是由您发布的GridView代码触发的。您可以为OnRow...方法和任何Page_Load / Page_Init代码发布代码隐藏吗?

话虽如此,为了让您的更新适用于DropDownList控件,您需要在RowUpdating方法中添加一些代码。这是一个blog post by Peter Kellner,但相关的代码是:

protected void GridViewIncomingUrls_RowUpdating(object sender, GridViewUpdateEventArgs e) { 
        DropDownList dropDownListUser = GridViewIncomingUrls.Rows[e.RowIndex].FindControl("MachineTypeDropDown") as DropDownList;
        e.NewValues["MachineTypeID"] = dropDownListUser.SelectedValue;
}

此外,您可能希望设置下拉列表的SelectedValue属性,以便在用户点击编辑按钮时预先填充先前选择的值:

 <asp:DropDownList 
    ID="MachineModelDropDown"  
    SelectedValue='<%#Bind("MachineModelID") %>'
    ...

答案 1 :(得分:2)

我从未见过ObjectDataSource在模板中使用 - 总是在网格的ItemDataBound事件中显式填充/绑定控件。

像这样的复杂的东西,我只会使用ItemTemplate,然后在其中包含所有控件(在你的情况下为Label和DropDown)。每个都将根据Grid.EditIndex > -1切换。

我首先评论网格的各个部分(就像在EditTemplate中使用ObjectDataSource那样整个部分)并查看是否有效。

如果该下拉列表/字段是罪魁祸首,那么我会重新将其填充到Grid_ItemDataBound()事件中而不是内部标记中。

答案 2 :(得分:0)

一种可能的解决方案是将viewstate设为false:

  

的EnableViewState = “假”

以下链接会有所帮助。

http://forums.asp.net/t/1159585.aspx/1

http://forums.asp.net/t/1295517.aspx/1