所以,这是我的场景
我有这个网格视图,在一个自定义控件中。这个网格的每一行元素都可以在一个单独的弹出窗口中打开,以编辑其详细信息(是的,弹出窗口,它是客户端想要的方式)
因此,为了编辑和检索此行编辑的数据,我将其存储在Session变量中,以在弹出窗口和稍后的上显示详细信息
ObjectType editObject = CurrentDS.FirstOrDeafult(o => o.Index == e.CommandArgument);
Session["EditObjectVar"] = editObject;
ScriptManager.RegisterStartupScript(this.Page, typeof(string), "OPEN_WINDOW", "window.open('ObjDetails.aspx', '_blank','scrollbars=yes,status=yes,toolbar=no,menubar=no,location=no,resizable=1,width=700,height=425,center=yes' );", true);
当关闭并保存更改时,我会再次存储在同一个Session变量上,并在父窗口上强制回发以刷新数据。
Session.Remove("EditObjectVar");
StoreValuesOnObject();
Session["EditObjectVar"] = editObject;
ScriptManager.RegisterStartupScript(this.Page, GetType(), "Close Popup", "window.opener.__doPostBack();window.close();", true);
在controls page_load事件中,我检查是否有回发,Session变量是否有数据,我需要刷新DS和gridview上的对象。
if (Page.IsPostBack && Session["EditObjectVar"] != null)
{
ObjectType modObj = (ContainerType) Session["EditObjectVar"];
ObjectType oldObj = CurrentDS.FirstOrDeafult(o => o.Index == modObj .Index);
CurrentDS.Remove(oldObj);
CurrentDS.Add(modObj);
gv.DataSource = null;
gv.DataSource = CurrentDS;
gv.DataBind();
Session.Remove("EditObjectVar");
}
一切都是正确持久化的,我检索编辑过的对象,更重要的是,考虑到在Session变量上,除了存储对象之外,还存储了对象内存位置,这意味着,通过强制回发,编辑后的对象已经在网格数据源(也存储在Session变量中)上更新了,所以我将网格视图绑定到更新的DS,但是,gridview仍然没有刷新,它仍然从viewstate 中检索行状态
知道我怎样才能完成任务吗?更新面板是一个选项,我知道,但我没有批准使用它们
我已经有了类似的东西,对象详细信息,还包含一个对象集合,这些对象显示在详细信息弹出窗口的网格视图上,作为其父对象,用户也可以在单独的弹出窗口中打开子对象的详细信息。前面描述的逻辑适用于此,但通过对象详细信息,对象子对象网格视图将正确刷新!
编辑:添加了尽可能多的代码来更好地解释,因为我有一个非常严格的保密协议,在网上发布真实的代码可能会带来一些麻烦,但我已经没有主意了
编辑2:忘记在示例中添加.DataBind()
,但它在代码中
编辑3:忘了提一下,它没有刷新的GridView有控件,可以直接在GridView上更改一些值。这是gridview 的html
<asp:GridView ID="gv" runat="server" ShowHeader="false" CellPadding="5" CellSpacing="0" EnableViewState="true" AutoGenerateColumns="False" OnRowCreated="RowCreated"
OnRowDataBound="RowDataBound" GridLines="Both" BorderStyle="Solid" BorderColor="Black" BorderWidth="1px">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton ID="imgDelete" runat="server" CausesValidation="false" AlternateText="Delete Part"
CommandName="cnt_delete" CommandArgument='<%# Eval("ContainerIndex") %>' OnClick="imgDelete_Click"
ImageUrl="~/img/del.png" />
<asp:ImageButton ID="imgDetails" runat="server" CausesValidation="false" AlternateText="View Cnt Details"
CommandName="cnt_details" CommandArgument='<%# Eval("ContainerIndex") %>'
ImageUrl="~/img/edit_icon.png" Height="15px" onclick="imgDetails_Click" />
<asp:Label ID="lblNum" runat="server" Text='<%# Eval("ContainerIndex") %>' ></asp:Label>
</ItemTemplate>
<ItemStyle CssClass="subGridItem" VerticalAlign="Top" />
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<table style="FONT-SIZE: xx-small; FONT-FAMILY: Verdana; background-color:#F5F5F5" cellspacing="1" cellpadding="1"
border="0" width="100%" >
<tr>
<td>
<asp:Label ID="lblQty" runat="server" Text="Qty" ></asp:Label>
<asp:Label ID="lblQtyRq" runat="server" Text="*"></asp:Label>
</td>
<td style="white-space:nowrap">
<asp:Label ID="lblWeight" runat="server" Text="Weight" ></asp:Label>
<asp:Label ID="lblWeightRq" runat="server" Text="*"></asp:Label>
</td>
<td style="white-space:nowrap">
<asp:Label ID="lblCntType" runat="server" Text="Container Type" ></asp:Label>
<asp:Label ID="lblCntTypeRq" runat="server" Text="*"></asp:Label>
</td>
</tr>
<tr valign="top">
<td><asp:TextBox ID="txtQty" Width="50px" runat="server" CssClass="detailsInput" Text='<%# Eval("Quantity") %>' MaxLength="7" ></asp:TextBox><br />
<asp:RequiredFieldValidator ID="validatorQty" runat="server" ControlToValidate="txtQty" Display="Dynamic" ErrorMessage="Required" ></asp:RequiredFieldValidator>
<asp:CompareValidator ID="CompareQty" runat="server" Display="Dynamic" ControlToValidate="txtQty" Operator="GreaterThan" ValueToCompare="0" Type="Double" ErrorMessage="invalid"></asp:CompareValidator>
</td>
<td><asp:TextBox ID="txtWeight" Width="50px" runat="server" CssClass="detailsInput" Text='<%# Eval("Weight") %>' MaxLength="11" ></asp:TextBox><br />
<asp:RequiredFieldValidator ID="ValidatorWgt" runat="server" ControlToValidate="txtWeight" Display="Dynamic" ErrorMessage="Required"></asp:RequiredFieldValidator>
<asp:CompareValidator ID="CompareWeight" runat="server" Display="Dynamic" ControlToValidate="txtWeight" Operator="GreaterThan" ValueToCompare="0" Type="Double" ErrorMessage="invalid"></asp:CompareValidator>
</td>
<td>
<asp:DropDownList ID="lstCntTypes" runat="server" ></asp:DropDownList><br />
<asp:RequiredFieldValidator ID="validatorCntTypes" runat="server" CssClass="TPValidator" ControlToValidate="lstCntTypes" Display="Dynamic" ErrorMessage="Required"></asp:RequiredFieldValidator>
</td>
</tr>
<tr><td colspan="12">
<table width="100%" >
<tr>
<td style="white-space:nowrap">
<asp:label id="lblProperShippingName" CssClass="TPLabel" Runat="server" Visible="false">Proper shipping name</asp:label>
<asp:label id="lblProperShippingNameM" Runat="server" ForeColor="red" Font-Size="xx-small" Visible="false">*</asp:label></td>
<td style="white-space:nowrap">
<asp:label id="lblHazClass" CssClass="TPLabel" Runat="server" Font-Size="xx-small" Visible="false">Hazard class</asp:label>
<asp:label id="lblHazClassM" Font-Bold="true" Runat="server" ForeColor="red" Font-Size="xx-small" Visible="false">*</asp:label>
</td>
<td style="white-space:nowrap">
<asp:label id="lblUNNumber" CssClass="TPLabel" Runat="server" Visible="false" >UN/NA Identification Number</asp:label>
<asp:label id="lblUNNumberM" Runat="server" ForeColor="red" Font-Size="xx-small" Visible="false">*</asp:label>
</td>
<td style="white-space:nowrap">
<asp:label id="lblPackGroup" CssClass="TPLabel" Runat="server" Visible="false" >Packing group</asp:label>
<asp:label id="lblPackGroupM" Font-Bold="true" Runat="server" ForeColor="red" Visible="false" >*</asp:label>
</td>
<td>
<asp:label id="lblIMO" CssClass="TPLabel" Runat="server" Visible="False">IMO Classification</asp:label></td>
<td><asp:label id="lblTunnel" CssClass="TPLabel" Runat="server" Visible="False">Tunnel Restriction</asp:label></td>
</tr>
</table>
</td> </tr>
<tr>
<td colspan="8"> </td></tr>
</table>
</ItemTemplate>
<ItemStyle VerticalAlign="Top" />
</asp:TemplateField>
</Columns>
</asp:GridView>
正如您在这里注意到的,两个txt输入都是从行属性的eval中获取值的,但lst没有。lst值是在RowDataBound事件上设置的,我可以在那里看到修改后的值,但它仍然显示从视图状态中获取的值
我没有试图跟踪所有内容,但这并不是因为你在其中遗漏了"gv.DataBind();",是吗?我知道当你从电脑应用程序切换到网络应用程序时,会发生这种情况。。。
所以,我终于抽出时间来处理它了。
最后,我在网格所在的同一个自定义控件上设置了一个按钮,让这个控件检索它在会话上的信息并刷新网格,而不是在回调上执行
编辑:这个按钮通过css对用户的眼睛隐藏(显示:无)。不是很花哨的方法,但是,它工作
因此,在检索要编辑的对象时,我还将刷新DS 的按钮的UniqueID存储在Session中
ObjectType editObject = CurrentDS.FirstOrDeafult(o => o.Index == e.CommandArgument);
Session["EditObjectVar"] = editObject;
Session["BtnRefreshUniqueID"] = btnRefreshDS.UniqueID;
ScriptManager.RegisterStartupScript(this.Page, typeof(string), "OPEN_WINDOW", "window.open('ObjDetails.aspx', '_blank','scrollbars=yes,status=yes,toolbar=no,menubar=no,location=no,resizable=1,width=700,height=425,center=yes' );", true);
当我准备存储并关闭详细信息弹出窗口时,我设置了回发,该回发将刷新调用btnRefreshDS
OnClick
事件的DS
Session.Remove("EditObjectVar");
StoreValuesOnObject();
Session["EditObjectVar"] = editObject;
ScriptManager.RegisterStartupScript(this.Page, GetType(), "Close Popup", String.Format("window.opener.__doPostBack('{0}', 'OnClick');window.close();", Session["BtnRefreshUniqueID"].ToString()), true);
这是OnClick
事件
protected void btnRefresDS_Click(object sender, EventArgs e)
{
try
{
if (Session["EditObjectVar"] != null)
{
gv.DataSource = CurrentDS;
gv.DataBind();
Session.Remove("EditObjectVar");
}
}
catch (Exception ee)
{
MyPage.Log(ee.StackTrace);
MyPage.Log(ee.Message);
}
}
考虑到,在Session变量上,它存储了对象内存位置,而不是对象本身,我的DS上已经有了更新的对象(它也存储在Session上),所以我只需要初始化DS并调用databind。
希望这能帮助到任何人!