How to edit data in a nested Listview

I use listview to display a list of items and a nested list to display a list of functions for each item. Both the parent and child list must be able to insert, edit, and delete operations. It works great for parent list. But when I try to edit a child, the "Edit" button does not go into edit mode. Could you offer me what is missing in my code?

<asp:ListView ID="lvParent" runat="server" OnItemDataBound="lvParent_ItemDataBound" onitemcanceling="lvParent_ItemCanceling" onitemcommand="lvParent_ItemCommand" DataKeyNames="ItemID" onitemdeleting="lvParent_ItemDeleting" oniteminserting="lvParent_ItemInserting" > <LayoutTemplate> <asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder> <div align="right"> <asp:Button ID="btnInsert" runat="server" Text="ADD Item" onclick="btnInsert_Click"/> </div> </LayoutTemplate> <ItemTemplate> <table runat="server" cellpadding="0" cellspacing="0" border="0" width="100%"> <tr> <td> <div id="dvDetail"> <span >Description</span> <asp:TextBox ID="txtDescription" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Description") %>' TextMode="MultiLine" ></asp:TextBox> </div> <div id="dvFeature" > <span>Feature List</span> <asp:ListView ID="lvChild" runat="server" InsertItemPosition="LastItem" DataKeyNames="FeatureID" OnItemCommand="lvChild_ItemCommand" OnItemCanceling="lvChild_ItemCanceling" OnItemDeleting="lvChild_ItemDeleting" OnItemEditing="lvChild_ItemEditing" OnItemInserting="lvChild_ItemInserting" OnItemUpdating="lvChild_ItemUpdating" DataSource='<%# DataBinder.Eval(Container.DataItem, "FeatureList") %>' > <LayoutTemplate> <ul > <asp:PlaceHolder runat="server" ID="itemPlaceHolder" ></asp:PlaceHolder> </ul> </LayoutTemplate> <ItemTemplate> <li> <span class="dvList"><%# DataBinder.Eval(Container.DataItem, "FeatureTitle")%></span> <div class="dvButton" > <asp:ImageButton ID="btnEdit" runat="server" ImageUrl="/Images/edit_16x16.gif" AlternateText= "Edit" CommandName="Edit" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FeatureID") %>' Width="12" Height="12" /> <asp:ImageButton ID="btnDelete" runat="server" ImageUrl="/Images/delete_16x16.gif" AlternateText= "Delete" CommandName="Delete" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FeatureID") %>' Width="12" Height="12" /> </div> </li> </ItemTemplate> <EditItemTemplate> <li> <asp:TextBox ID="txtFeature" Text='<%# DataBinder.Eval(Container.DataItem, "FeatureTitle")%>' runat="server"></asp:TextBox> <div class="dvButton"> <asp:ImageButton ID="btnUpdate" runat="server" ImageUrl="/Images/ok_16x16.gif" AlternateText= "Update" CommandName="Update" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FeatureID") %>' Width="12" Height="12" /> <asp:ImageButton ID="btnCancel" runat="server" ImageUrl="/Images/delete_16x16.gif" AlternateText= "Cancel" CommandName="Cancel" Width="12" Height="12" CausesValidation="false" /> </div> </li> </EditItemTemplate> <InsertItemTemplate> <asp:TextBox ID="txtFeature" runat="server"></asp:TextBox> <div class="dvButton"> <asp:ImageButton ID="btnInsert" runat="server" ImageUrl="/Images/ok_16x16.gif" AlternateText= "Insert" CommandName="Insert" Width="12" Height="12" /> <asp:ImageButton ID="btnCancel" runat="server" ImageUrl="/Images/delete_16x16.gif" AlternateText= "Cancel" CommandName="Cancel" Width="12" Height="12" CausesValidation="false" /> </div> </InsertItemTemplate> </asp:ListView> </div> </td> </tr> <tr> <td align="right"> <div id="dvButton" > <asp:Button ID="btnSave" runat="server" Text="Save" CommandName="Save" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "ItemID") %>' /> <asp:Button ID="btnDelete" runat="server" Text="Delete" CssClass="Cancel" CommandName="Delete" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "ItemID") %>' /> </div> </td> </tr> </table> </ItemTemplate> </asp:ListView> 

Code for:

 protected void Page_Load(object sender, EventArgs e) { if (Page.IsPostBack == false) { BindData(); } } private void BindData() { MyDataContext data = new MyDataContext(); var result = from itm in data.ItemLists where itm.ItemID == iItemID select new { itm.ItemID, itm.Description, FeatureList = itm.Features }; lvParent.DataSource = result; lvParent.DataBind(); } protected void lvChild_ItemEditing(object sender, ListViewEditEventArgs e) { ListView lvChild = sender as ListView; lvChild.EditIndex = e.NewEditIndex; lvChild.DataBind(); } 

Edit:

 protected void lvChild_ItemEditing(object sender, ListViewEditEventArgs e) { ListView lvChild = sender as ListView; lvChild.EditIndex = e.NewEditIndex; lvChild.DataBind(); } 

If I use "lvChild.DataBind ()" in the event "ItemEditing", the general list of child items disappears if I click "edit"

 protected void lvChild_ItemEditing(object sender, ListViewEditEventArgs e) { ListView lvChild = sender as ListView; lvChild.EditIndex = e.NewEditIndex; } 

if I get rid of the 'lvChild.Databind' in the ItemEditing event, it goes into edit mode after clicking the edit button twice. And although it shows the control of the EditItemTemplate text field, it looks like an empty text file (does not bind the existing value for editing).

+4
source share
2 answers

This is an interesting problem. There is almost certainly a data binding problem. To enter edit mode, you must do two things:

1) Install EditIndex
2) Call DataBind ()

In the case of nested repeaters, though ... when does Render get called? I suspect you will have to call DataBind () on PARENT so that everything is correct. In this case, you may have to install EditIndex AGAIN, as you are double-checking the parent.

EDIT: OK ... I just tried this with the GridView nested, and I did NOT have the DataBind () parent to get the hook, to enter edit mode. Now I have to lower my own answer .: |

+2
source

Hope someone will serve somewhere.

Here is my code to make this work:

1) I have a Listview that has a custom control when editing. This custom cotnrol itself has a list inside

 <asp:ListView runat=server ID=C_LV_MyObjects DataKeyNames="Id" OnItemDataBound=DataBoundMyObjects OnItemEditing=ItemEditing > <LayoutTemplate> <table runat=server id="itemPlaceholderContainer"> <tr> <th> Description </th> </tr> <tr runat="server" id="itemPlaceholder"> </tr> </table> </LayoutTemplate> <ItemTemplate> <tr> <td> text... </td> <td> <asp:LinkButton runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton> </td> <td> <asp:LinkButton runat="server" CommandName="Delete" Text="Delete"></asp:LinkButton> </td> </ItemTemplate> <EditItemTemplate> <tr> <td colspan=3> <MyTag:MyUC ID=C_UC_MyUserControl runat=server OnEditing=MyObjectEditing /> </td> </tr> </EditItemTemplate> <EmptyDataTemplate> No results found! </EmptyDataTemplate> </asp:ListView> 

The C # code for this list is as follows:

 public int EditIndexComposition; protected void ItemEditing(object sender, ListViewEditEventArgs e) { C_LV_MyObjects.EditIndex = e.NewEditIndex; C_LV_MyObjects.DataBind(); } protected void MyObjectEditing(object sender, EventArgs e) { ListViewEditEventArgs MyEvent = (ListViewEditEventArgs)e; if (MyEvent != null) EditIndexComposition= MyEvent.NewEditIndex; C_LV_MyObjects.DataBind(); } protected void DataBoundMyObjects(object sender, ListViewItemEventArgs e) { MyUC uc = (MyUC)e.Item.FindControl("C_UC_MyUserControl"); if (uc!=null) { uc.EditIndex = EditIndexComposition; ListViewDataItem dataItem = (ListViewDataItem)e.Item; MyObject obj= (MyObject)dataItem.DataItem; uc.DataSource=Myservice.GetDatasource(obj.Id); uc.DataBind(); } } 

and the code of my Usercontrol is as follows:

 <asp:PlaceHolder runat="server" ID="C_PH_ObjComposition"> <asp:ListView runat="server" ID="C_LV_AppaltatoreComposizione" DataSource="<% # DataSource %>" DataKeyNames="Id" OnItemEditing="ItemEditing"> etc... <ItemTemplate> <tr> <td> <asp:LinkButton runat="server" CommandName="Edit" Text="Edit"></asp:LinkButton> </td> </tr> </ItemTemplate> <EditItemTemplate> <tr> <td> Edit Mode </td> </tr> </EditItemTemplate> </asp:ListView> </asp:PlaceHolder> 

with the following C # code:

 public int EditIndex { get {return C_LV_ObjComposition.EditIndex;} set { C_LV_ObjComposition.EditIndex=value;} } public event EventHandler Editing; protected void ItemEditing(object sender, ListViewEditEventArgs e) { C_LV_ObjComposition.EditIndex = e.NewEditIndex; if (Editing != null) Editing(this, e); } 

When you click the edit button of the internal list, we save the index that was clicked, and we run the function in the first user control for the container. This function will be stored in a global value that is indexed by the client and triggers data binding in the outter list. Thus, we get onitemdatabound, which recreates our user control with the corresponding values, we can then assign the index of the edit line to the data binding usercontrol.

That is all, if you have any questions, please feel free to answer.

ciao!

0
source

Source: https://habr.com/ru/post/1286220/


All Articles