I have an Asp:ListView control which I am showing in a pop up in a web form. Currently, it does all the changes directly in database as soon as I click the Insert, Update or Delete LinkButtons.
But I need all the changes to be done in database only when Web Form is submitted.
So, what I figured was I would need to keep the data which I am binding to ListView in a session, and on all inserts, updates and delete operations, do all the changes manually on OnInserting, OnDeleting, OnUpdating events by
Step 1) retrieving data every time from Session["ListView1"],
Step 2) doing the Insert/Delete/Update operation on retrieved data
Step 3) binding it to ListView
Step 4) replacing data in Session["ListView1"] after update.
Step 5) On web form submit, taking the updated data and Replace All in database?
I did these steps but it is not working as expected. On Update, ListView displays blank values for 2 columns and binds data incorrectly. I have binded with the right columns. After Insert, TextBox doesn't get changed to Labels as expected. Below is my ListView and code-behind code:
ListView:
<asp:updatepanel id="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:ListView ID="ListView1" runat="server"
OnItemCanceling="ListView1_ItemCanceling" OnItemEditing="ListView1_ItemEditing"
OnItemDeleting="ListView1_ItemDeleting" OnItemUpdating="ListView1_ItemUpdating"
OnItemInserting="ListView1_ItemInserting" DataKeyNames="Id"
InsertItemPosition="LastItem">
<AlternatingItemTemplate>
<tr style="">
<td width="200">
<asp:LinkButton ClientIDMode="AutoID" ID="DeleteButton" runat="server"
CommandName="Delete" Text="Delete" CausesValidation="false" />
<asp:LinkButton ClientIDMode="AutoID" ID="EditButton" runat="server"
CommandName="Edit" Text="Edit" CausesValidation="false" />
</td>
<td>
<asp:Label ID="IdLabel" runat="server" Text='<%# Eval("Id") %>' />
</td>
<td>
<asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' />
</td>
<td>
<asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' />
</td>
<td>
<asp:Label ID="Column3Label" runat="server" Text='<%# Eval("Column3") %>' />
</td>
<td>
<asp:Label ID="Column4Label" runat="server" Text='<%# Eval("Column4") %>' />
</td>
</tr>
</AlternatingItemTemplate>
<EditItemTemplate>
<tr style="">
<td>
<asp:LinkButton ClientIDMode="AutoID" ID="UpdateButton" runat="server"
CommandName="Update" Text="Update" ValidationGroup="popup1" CausesValidation="true" />
<asp:LinkButton ClientIDMode="AutoID" ID="CancelButton" runat="server"
CommandName="Cancel" Text="Cancel" CausesValidation="false" />
</td>
<td>
<asp:Label ID="IdLabel1" runat="server" Text='<%# Eval("Id") %>' />
</td>
<td>
<asp:TextBox ID="FirstNameTextBox" Style="width: 100px; background-color: white;"
runat="server" Text='<%# Bind("FirstName") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="NameReq" runat="server" ControlToValidate="FirstNameTextBox"
ErrorMessage="First name is required." ToolTip="First name is required."
ValidationGroup="popup1">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="LastNameTextBox" Style="width: 100px; background-color: white;"
runat="server" Text='<%# Bind("LastName") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server"
ControlToValidate="LastNameTextBox" ErrorMessage="Last name is required."
ToolTip="Last name is required." ValidationGroup="popup1">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="Column3TextBox" Style="width: 100px; background-color: white;"
runat="server" Text='<%# Bind("Column3") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" runat="server"
ControlToValidate="Column3TextBox" ErrorMessage="ID is required." ToolTip="ID is required."
ValidationGroup="popup1">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="Column4Text" placeholder="mm/dd/yyyy" Style="width: 100px;
background-color: white;" runat="server" Text='<%# Bind("Column4") %>'
CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" runat="server"
ControlToValidate="Column4Text" ErrorMessage="Date is required."
ToolTip="Date is required." ValidationGroup="popup1">*</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td>
<asp:RegularExpressionValidator ID="dateValRegex" runat="server"
ControlToValidate="Column4Text" ErrorMessage="Please Enter a valid date in the format (mm/dd/yyyy)"
ValidationExpression="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$"
ValidationGroup="popup"></asp:RegularExpressionValidator>
</td>
</tr>
</EditItemTemplate>
<EmptyDataTemplate>
<table id="Table1" runat="server" style="">
<tr>
<td>No data was returned.</td>
</tr>
</table>
</EmptyDataTemplate>
<InsertItemTemplate>
<tr>
<td width="200">
<asp:LinkButton ClientIDMode="AutoID" ID="InsertButton" runat="server" CommandName="Insert"
Text="Insert" ValidationGroup="popup" CausesValidation="true" />
<asp:LinkButton ClientIDMode="AutoID" ID="LinkButton1" runat="server" CommandName="Cancel"
Text="Clear" CausesValidation="false" />
</td>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Id") %>' />
</td>
<td>
<asp:TextBox ID="TextBox1" Style="width: 100px; background-color: white;" runat="server"
Text='<%# Bind("FirstName") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
ControlToValidate="FirstNameTextBox" ErrorMessage="First name is required."
ToolTip="First name is required." ValidationGroup="popup">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="TextBox2" Style="width: 100px; background-color: white;" runat="server"
Text='<%# Bind("LastName") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator3" runat="server"
ControlToValidate="LastNameTextBox" ErrorMessage="Last name is required."
ToolTip="Last name is required." ValidationGroup="popup">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="TextBox3" Style="width: 100px; background-color: white;" runat="server"
Text='<%# Bind("Column3") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator4" runat="server"
ControlToValidate="Column3TextBox" ErrorMessage="ID is required."
ToolTip="ID is required." ValidationGroup="popup">*</asp:RequiredFieldValidator>
</td>
<td>
<asp:TextBox ID="TextBox4" placeholder="mm/dd/yyyy" Style="width: 100px;
background-color: white;" runat="server" Text='<%# Bind("Column4") %>' CausesValidation="true" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server" ControlToValidate="Column4Text"
ErrorMessage="Date is required." ToolTip="Date is required."
ValidationGroup="popup">*</asp:RequiredFieldValidator>
</tr>
<tr>
<td>
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
ControlToValidate="Column4Text" ErrorMessage="Please Enter a valid date in the format (mm/dd/yyyy)"
ValidationExpression="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$"
ValidationGroup="popup"></asp:RegularExpressionValidator>
</td>
</tr>
</InsertItemTemplate>
<ItemTemplate>
<tr>
<td width="200">
<asp:LinkButton ClientIDMode="AutoID" ID="LinkButton2" runat="server" CommandName="Delete"
Text="Delete" CausesValidation="false" />
<asp:LinkButton ClientIDMode="AutoID" ID="LinkButton3" runat="server" CommandName="Edit"
Text="Edit" CausesValidation="false" />
</td>
<td>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("Id") %>' />
</td>
<td>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("FirstName") %>' />
</td>
<td>
<asp:Label ID="Label4" runat="server" Text='<%# Eval("LastName") %>' />
</td>
<td>
<asp:Label ID="Label5" runat="server" Text='<%# Eval("Column3") %>' />
</td>
<td>
<asp:Label ID="Label6" runat="server" Text='<%# Eval("Column4") %>' />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="Table2" runat="server">
<tr id="Tr1" runat="server">
<td id="Td1" runat="server">
<table id="itemPlaceholderContainer" runat="server" border="0" style="">
<tr id="Tr2" runat="server" style="">
<th id="Th1" runat="server">Action</th>
<th id="Th2" runat="server">Id</th>
<th id="Th3" runat="server">First Name</th>
<th id="Th4" runat="server">Last Name</th>
<th id="Th5" runat="server">Column3 Name</th>
<th id="Th6" runat="server">Column4 Name</th>
</tr>
<tr id="itemPlaceholder" runat="server">
</tr>
</table>
</td>
</tr>
</table>
<table width="900" align="center" style="text-align: center;">
<tr id="Tr3" runat="server">
<td id="Td2" runat="server" style="">
<asp:DataPager ID="DataPager1" runat="server">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="True"
ShowNextPageButton="False" ShowPreviousPageButton="False" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="True"
ShowNextPageButton="False" ShowPreviousPageButton="False" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</LayoutTemplate>
<SelectedItemTemplate>
<tr style="">
<td>
<asp:LinkButton ID="LinkButton4" runat="server" CommandName="Delete" Text="Delete"
CausesValidation="false" />
<asp:LinkButton ID="LinkButton5" runat="server" CommandName="Edit" Text="Edit"
CausesValidation="false" />
</td>
<td>
<asp:Label ID="Label7" runat="server" Text='<%# Eval("Id") %>' />
</td>
<td>
<asp:Label ID="Label8" runat="server" Text='<%# Eval("FirstName") %>' />
</td>
<td>
<asp:Label ID="Label9" runat="server" Text='<%# Eval("LastName") %>' />
</td>
<td>
<asp:Label ID="Label10" runat="server" Text='<%# Eval("Column3") %>' />
</td>
<td>
<asp:Label ID="Label11" runat="server" Text='<%# Eval("Column4") %>' />
</td>
</tr>
</SelectedItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:updatepanel>
Below is Code Behind code:
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!IsPostBack)
{
LoadListView();
}
}
private void LoadListView()
{
try
{
List lstDetails = Session["ListView1Data"] as List;
ListView1.DataSource = lstDetails;
ListView1.DataBind();
Session["ListView1Data"] = lstDetails ;
}
catch (Exception ex)
{
ExceptionLogger.LogException(ex);
}
}
protected void ListView1_ItemDeleting(object sender, ListViewDeleteEventArgs e)
{
List lstDetails = Session["ListView1Data"] as List;
int id = Convert.ToInt32(e.Values["Id"]);
if (lstDetails.Exists(x => x.Id == id))
{
var tableDetail = lstDetails.Where(x => x.Id == id).FirstOrDefault();
lstDetails.Remove(tableDetail);
hdnListDeleteIds.Value = id + "|";
ListView1.DataSource = lstDetails;
ListView1.DataBind();
ListView1.EditIndex = -1;
}
}
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
List lstDetails = Session["ListView1Data"] as List;
int id = Convert.ToInt32(e.OldValues["Id"]);
if (lstDetails.Exists(x => x.Id == id))
{
var tableDetail = lstDetails.Where(x => x.Id == id).FirstOrDefault();
tableDetail.FirstName = e.NewValues["FirstName"].ToString();
tableDetail.LastName = e.NewValues["LastName"].ToString();
tableDetail.Column3 = e.NewValues["Column3"].ToString();
tableDetail.Column4 = Convert.ToDateTime(e.NewValues["Column4"]);
hdnListUpdateIds.Value = id + "|";
ListView1.DataSource = lstDetails;
ListView1.DataBind();
ListView1.EditIndex = -1;
Session["ListView1Data"] = lstDetails;
}
}
protected void ListView1_ItemInserting(object sender, ListViewInsertEventArgs e)
{
List lstDetails = Session["ListView1Data"] as List;
EntityFrameworkModel.TableDetails tableDetail = new EntityFrameworkModel.TableDetails()
{
FirstName = e.Values["FirstName"].ToString(),
LastName = e.Values["LastName"].ToString(),
Column3 = e.Values["Column3"].ToString(),
Column4 = Convert.ToDateTime(e.Values["Column4"]),
Id = 0
};
lstDetails.Add(tableDetail);
Session["ListView1Data"] = lstDetails;
ListView1.DataSource = lstDetails;
ListView1.DataBind();
ListView1.EditIndex = -1;
}
protected void ListView1_ItemCanceling(object sender, ListViewCancelEventArgs e)
{
List lstDetails = Session["ListView1Data"] as List;
ListView1.DataSource = lstDetails;
ListView1.DataBind();
e.Cancel = true;
ListView1.EditIndex = -1;
}
protected void ListView1_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListView1.EditIndex = e.NewEditIndex;
}
What am I doing wrong? Please help.
Many Thanks
I have modified your code to Insert/Update/Delete data at one shot. Hope it will help you.
While editing you need to bind the data again,
protected void ListView1_ItemEditing(object sender, ListViewEditEventArgs e)
{
ListView1.EditIndex = e.NewEditIndex;
BindData();
}
private void BindData()
{
ListView1.DataSource = Session["ListView1Data"] as List<TableDetails>;
ListView1.DataBind();
}
While deleting the items, you can consider keeping them(only the existing items, not newly added) in a separate session.
protected void ListView1_ItemDeleting(object sender, ListViewDeleteEventArgs e)
{
List<TableDetails> lstDetails = Session["ListView1Data"] as List<TableDetails>;
if (lstDetails.Count >= e.ItemIndex + 1)
{
var tableDetail = lstDetails[e.ItemIndex];
DeletedItems(tableDetail);
lstDetails.Remove(tableDetail);
ListView1.EditIndex = -1;
Session["ListView1Data"] = lstDetails;
BindData();
}
}
private void DeletedItems(TableDetails tableDetail)
{
List<TableDetails> lstDelItems = new List<TableDetails>();
if (Session["DeletedItems"] != null)
{
lstDelItems = Session["DeletedItems"] as List<TableDetails>;
}
// No need to keep track of New Items(whose ID is 0)
if (tableDetail.Id > 0)
{
lstDelItems.Add(tableDetail);
Session["DeletedItems"] = lstDelItems;
}
}
Now, your save button click event can be
protected void btnSave_Click(object sender, EventArgs e)
{
List<TableDetails> lstDelItems = new List<TableDetails>();
List<TableDetails> lstDetails = Session["ListView1Data"] as List<TableDetails>;
EntityFrameworkModel entity = new EntityFrameworkModel();
if (Session["DeletedItems"] != null)
{
lstDelItems = Session["DeletedItems"] as List<TableDetails>;
}
foreach (TableDetails det in lstDetails)
{
// Insert. For all the new entries, the ID value will be 0
if (det.Id == 0)
{
entity.TableDetails.Add(det);
}
// Update. If ID exists in the db, its a modified data
else if (entity.TableDetails.Any(d => d.Id == det.Id))
{
TableDetails detail = entity.TableDetails.First(d => d.Id == det.Id);
detail.FirstName = det.FirstName;
detail.LastName = det.LastName;
detail.Column3 = det.Column3;
detail.Column4 = det.Column4;
}
entity.SaveChanges();
}
// Delete.
foreach (TableDetails det in lstDelItems)
{
TableDetails detail = entity.TableDetails.First(d => d.Id == det.Id);
entity.TableDetails.Remove(detail);
entity.SaveChanges();
}
LoadListView();
Session["DeletedItems"] = null;
}
Update:
Yes, you need to modify your Updating event. Since all of your new items will have 0 as your ID value, you can't depend with that. You can depend with the RowIndex
for this.
protected void ListView1_ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
List<TableDetails> lstDetails = Session["ListView1Data"] as List<TableDetails>;
if (lstDetails.Count >= e.ItemIndex + 1)
{
var tableDetail = lstDetails[e.ItemIndex];
tableDetail.FirstName = e.NewValues["FirstName"].ToString();
tableDetail.LastName = e.NewValues["LastName"].ToString();
tableDetail.Column3 = e.NewValues["Column3"].ToString();
tableDetail.Column4 = Convert.ToDateTime(e.NewValues["Column4"]);
ListView1.EditIndex = -1;
Session["ListView1Data"] = lstDetails;
BindData();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.