Итак, это мой сценарий

У меня есть этот gridview внутри настраиваемого элемента управления. Каждый элемент строки этой сетки можно открыть в отдельном всплывающем окне для редактирования его деталей (да, всплывающее окно, так, как этого хочет клиент).

Итак, чтобы отредактировать и получить отредактированные данные этой строки, я сохраняю их в переменной сеанса, чтобы показать детали во всплывающем окне и позже.

    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.Remove("EditObjectVar");
    StoreValuesOnObject();
    Session["EditObjectVar"] = editObject;
    ScriptManager.RegisterStartupScript(this.Page, GetType(), "Close Popup", "window.opener.__doPostBack();window.close();", true);

В событии control 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, помимо сохранения объекта, сохраняется место в памяти объекта, что означает, что при принудительной обратной передаче отредактированный объект уже обновляется в источник данных сетки (который также хранится в переменной сеанса), поэтому я привязываю gridview к обновленному DS с обновленным объектом, но, тем не менее, gridview не обновляется, он все еще извлекает состояние строк из состояния просмотра

Есть идеи, как я могу выполнить свою задачу? Я знаю, что панель обновлений - это вариант, но у меня нет разрешения на их использование

У меня уже есть что-то подобное, сведения об объекте, также содержит набор объектов, которые отображаются в сетке во всплывающем окне с подробностями, и в качестве его родительского объекта пользователь также может открывать детали дочернего объекта в отдельном всплывающем окне. Здесь применяется описанная ранее логика, но с учетом деталей объекта, gridview дочерних объектов объекта обновляется правильно!

Отредактировано : добавлено столько кода, сколько я мог, чтобы лучше объяснить, учитывая, что у меня очень строгое конфиденциальное соглашение, и публикация реального кода в Интернете может вызвать некоторые проблемы, но у меня уже нет идей

Редактировать 2 : забыл добавить .DataBind() в пример, но он есть в коде

Редактировать 3 : забыл упомянуть, что GridView, который не обновляется, имеет элементы управления, позволяющие изменять некоторые значения непосредственно в gridview. Это HTML-код gridview

    <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, я вижу измененное значение там, но оно все еще показывает значение, взятое из состояния просмотра

0
CJLopez 13 Фев 2015 в 22:24

2 ответа

Лучший ответ

Итак, я наконец добрался до этого и заставил его работать.

В конце я установил кнопку на том же настраиваемом элементе управления, где находится сетка, и заставил этот элемент управления получать информацию о том, что он находится в сеансе, и обновлять сетку, а не делать это при обратном вызове

Изменить: эта кнопка скрыта от глаз пользователя с помощью css (отображение: нет). Не очень изящный способ сделать это, но он работает

Итак, при получении объекта для редактирования я также сохраняю в сеансе уникальный идентификатор кнопки, которая обновляет DS.

 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);

И когда я собираюсь сохранить и закрыть всплывающее окно с подробностями, я настраиваю обратную передачу, которая обновляет DS, вызывая событие btnRefreshDS OnClick

    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);
    }
}

Учитывая, что в переменной сеанса хранится место в памяти объекта, поскольку вместо объекта как такового у меня уже есть обновленный объект на моем DS (который также хранится в сеансе), поэтому мне нужно только назначить DS и вызвать привязку данных .

Надеюсь, это кому-нибудь поможет!

0
CJLopez 16 Фев 2015 в 16:29

Я не пробовал отслеживать все, но это не потому, что вы пропустили "gv.DataBind ();" там, не так ли? Я знаю, что это может случиться, когда вы переключаетесь с приложений для ПК на веб-приложения ...

0
Steve 13 Фев 2015 в 20:19