I am currently using a multiview control within a web forms user control page, navigating between views, our data does not persist.
Three view, last view contains a summary of what was entered within the first two view, If I click through to the summary view on ly data from the seconds view is available.
Clicking back and forth between views, our form data is lost.
Any ideas where to begin?
.ascx Page
<asp:MultiView ID="MultiView1" ActiveViewIndex="0" EnableViewState="true" runat="server">
<asp:View ID="View1" runat="server">
Name:<br />
<asp:TextBox ID="txtName" runat="server" />
</asp:View>
<asp:View ID="View2" runat="server">
Surname:<br />
<asp:TextBox ID="txtSurname" runat="server" />
</asp:View>
<asp:View ID="View3" runat="server">
<b>Summary</b><br />
Name:
<asp:Label ID="lblName" runat="server" /><br />
Surname:
<asp:Label ID="lblSurname" runat="server" /><br />
</asp:View>
</asp:MultiView>
<asp:Button ID="btnBack" runat="server" Text="< Back " OnClick="btnBack_Click" />
<asp:Button ID="btnNext" runat="server" Text="Next >" OnClick="btnNext_Click" />
<asp:Button ID="btnSend" runat="server" Text="Submit" OnClick="btnSend_Click" />
ascx.cs Codebehind
protected void btnBack_Click(object sender, EventArgs e)
{
MultiView1.ActiveViewIndex--;
}
protected void btnNext_Click(object sender, EventArgs e)
{
MultiView1.ActiveViewIndex++;
}
protected void btnSend_Click(object sender, EventArgs e)
{
}
protected override void OnPreRender(EventArgs e)
{
if (MultiView1.ActiveViewIndex == MultiView1.Views.Count - 1)
{
FillSummary();
}
btnBack.Visible = MultiView1.ActiveViewIndex > 0;
btnNext.Visible = MultiView1.ActiveViewIndex < MultiView1.Views.Count - 1;
btnSend.Visible = MultiView1.ActiveViewIndex == MultiView1.Views.Count - 1;
base.OnPreRender(e);
}
private void FillSummary()
{
lblName.Text = txtName.Text;
lblSurname.Text = txtSurname.Text;
}
Related
Below is the markup page:
<%# Page Title="" Language="C#" MasterPageFile="~/Master/MainPage.master" EnableViewState="true" AutoEventWireup="true" CodeBehind="edit.aspx.cs" Inherits="Website.View.edit" %>
...
<asp:Repeater runat="server" ID="rptSample">
<ItemTemplate>
<asp:HyperLink runat="server" ID="refLink" href='http://www.sample.com' Text='Test data' />
<asp:CheckBox runat="server" ID="chkbxDelete" Text="Delete" />
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
</asp:Repeater>
Here's how I bind data on code behind:
protected void Page_Load(object sender, EventArgs e)
{
rptSample.DataSource = getData();
rptSample.DataBind();
}
I've also tried this one:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
rptSample.DataSource = getData();
rptSample.DataBind();
}
}
And tried to get the data on btnSave_Click function
protected void btn_save_Click(object sender, EventArgs e)
{
foreach(RepeaterItem item in rptSample.Items)
{
CheckBox chkbx = (CheckBox) item.FindControl("chkbxDelete");
if (chkbx.Checked)
{
//Do something
}
}
}
If I didn't add the !IsPostBack, the rptSample.Items will be empty but if I remove it, the checkbox will always be false.
What's the problem??
Edit:
As per a user requested, here's the full page load function:
protected void Page_Load(object sender, EventArgs e)
{
bindData();
}
protected void bindData()
{
List<sp_SelectAttachments_Result> attachments = DAL.SelectAttachmentsByID(Request["ID"]);
if (attachments.Count == 0)
divAttachments.Visible = false;
else
{
divAttachments.Visible = true;
rptAttachments.DataSource = attachments;
rptAttachments.DataBind();
}
}
Here's the markup page for divAttachments and rptAttachments
<div runat="server" id="divAttachments" visible="false">
<asp:Repeater runat="server" ID="rptAttachments">
<ItemTemplate>
<asp:HiddenField Value='<%# Eval("ID") %>' runat="server" ID="hidID" />
<asp:HyperLink runat="server" ID="refLink" href='<%# $"/Utils/getFile.ashx?ID={ID}" %>' Text='<%# ((sp_SelectAttachments_Result)Container.DataItem).FileName %>' />
<asp:CheckBox runat="server" ID="chkbxDeleteAttachment" Text="Delete" />
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
</asp:Repeater>
</div>
I suspect that there is something in your code which clears the check boxes or resets the data source of the repeater control.
I suggest creating a clean page and using the code below(which I've tested and it works).Once you have it working slowly start adding any additional logic to the page until you figure out what's causing the problem:
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
rptSample.DataSource = getData();
rptSample.DataBind();
}
}
private List<string> getData()
{
return new List<string> { "1", "2", "3" };
}
protected void btn_save_Click(object sender, EventArgs e)
{
foreach (RepeaterItem item in rptSample.Items)
{
CheckBox chkbx = (CheckBox)item.FindControl("chkbxDelete");
if (chkbx.Checked)
{
System.Diagnostics.Debugger.Break();
}
}
}
.ASPX:
<form id="form1" runat="server">
<asp:Repeater runat="server" ID="rptSample">
<ItemTemplate>
<asp:HyperLink runat="server" ID="refLink" href='http://www.sample.com' Text='Test data' />
<asp:CheckBox runat="server" ID="chkbxDelete" Text="Delete" />
</ItemTemplate>
<SeparatorTemplate>
<br />
</SeparatorTemplate>
</asp:Repeater>
<asp:Button ID="btn_save" runat="server" Text="Save" OnClick="btn_save_Click" />
</form>
Use Viewstate to hold data. bind viewstate to repeater on load and also use the !IsPostBack for rptSample.DataBind();
When ever i hide or show the Panel, the items i add (dynamically) to the Table are gone, and another thing is that when i try add new Row to the Table, it won't show it, it's overwriting the same Row, why ??.
Here's the CodeBehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button2_Click(object sender, EventArgs e)
{
DropDownList1.Items.Add(TextBox3.Text);
}
protected void Button3_Click(object sender, EventArgs e)
{
if (Panel1.Visible == true)
Panel1.Visible = false;
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Panel1.Visible == false)
Panel1.Visible = true;
}
protected void Button4_Click(object sender, EventArgs e)
{
TableCell tdStudentName = new TableCell();
tdStudentName.Text = TextBox1.Text;
TableCell tdStudentCourse = new TableCell();
tdStudentCourse.Text = DropDownList1.SelectedValue;
TableCell tdStudentGrade = new TableCell();
tdStudentGrade.Text = TextBox2.Text;
TableRow tr = new TableRow();
tr.Cells.Add(tdStudentName);
tr.Cells.Add(tdStudentCourse);
tr.Cells.Add(tdStudentGrade);
Table1.Rows.Add(tr);
}
}
}
Here's the Html Source:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Student Name:"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:Label ID="Label2" runat="server" Text="Course:"></asp:Label>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Add Course" />
<br />
<asp:Label ID="Label3" runat="server" Text="Grade:"></asp:Label>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button4" runat="server" OnClick="Button4_Click" Text="Add" />
<br />
<br />
<asp:Panel ID="Panel1" runat="server" GroupingText="Course Settings" Visible="False">
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<asp:Button ID="Button2" runat="server" OnClick="Button2_Click" Text="Add" />
<asp:Button ID="Button3" runat="server" OnClick="Button3_Click" Text="Close" />
</asp:Panel>
<br />
<br />
<asp:Table ID="Table1" runat="server" BorderStyle="Solid">
<asp:TableRow runat="server">
<asp:TableCell runat="server">Name</asp:TableCell>
<asp:TableCell runat="server">Course</asp:TableCell>
<asp:TableCell runat="server">Grade</asp:TableCell>
</asp:TableRow>
</asp:Table>
</div>
</form>
</body>
</html>
Here's a preview of how it looks like:
If you add anything dynamically, then you must re-add it on any subsequent post-back. They will not automatically just "be there" on the next post-back.
This requires you to store the fact that the dynamic controls have been created and added, and therefore allows you to detect that on the post-back and add the controls back in again.
It is better (if possible) to add dynamic controls as part of the init stage of the life cycle, as this will mean they will pick up view state information before the load stage.
Edit
In response to the comment by the OP...
Where do i store these controls ? and where do i add them back ? inside Page_Load ?
You don't store the controls... you store the fact that the controls have been added.
The "easiest" way would be to use the ViewState, but that puts you in a catch-22 situation... because the ViewState is not available at the init stage of the life cycle, which is the preferred place to re-add those controls.
Another option would be to "store the fact" within an <asp:HiddenField> which you can check for within the init stage. However you would have to get the value directly from the Request object, as the field would not have the correct .Value at the init stage. You'd do that like...
if (!Page.IsPostBack)
{
string hdnValue = Request[hdnFieldCtrl.UniqueId];
// Recreate controls based on the details you need
}
I'm just starting to get to grips with web development and trying to build up some experience.
I am implementing the HtmlEditorExtender in my website. I have added all the files and references necessary to use this control and I've got the control displaying correctly. The problem I'm having is I don't seem to be able to get the content of the textbox after making changes.
I have attached the control to a textbox, then populated the textbox with the content I wish to edit. Once I've made changes I have a save button that will save the current content in the HTML editor. What I'm seeing is that the Text property of the Textbox is exactly the same as before I made the changes. Is there something obvious that I'm missing.
Code is below:
Markup in UserControl:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Panel ID="pnlPopup" runat="server" Style="display: none" CssClass="modalPopup">
<asp:Panel ID="Panel3" runat="server" Style="background-color: #DDDDDD; border: solid 1px Gray;
color: Black;">
<p>
Edit:
</p>
</asp:Panel>
<asp:TextBox runat="server" ID="txtHTMLContent" CssClass="WhiteTextBox" TextMode="MultiLine"
Columns="50" Rows="10" />
<br />
<ajaxToolkit:HtmlEditorExtender ID="htmlEditor" TargetControlID="txtHTMLContent" Runat="server" EnableSanitization="false" />
<center>
<asp:Button ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" />
</center>
</asp:Panel>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
string content = GetContent();
txtHTMLContent.Text = content;
}
protected void btnSave_Click(object sender, EventArgs e)
{
DatabaseManager dm = new DatabaseManager();
dm.UpdateContent(txtHTMLContent.Text);
}
I would appreciate any help.
wrap txtHTMLContent initialization code in the Page_Load method in if(!IsPostback) check:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string content = GetContent();
txtHTMLContent.Text = content;
}
}
I have created a html5 canvas and javascript signature pad that I would like to implement as a web user control with an update panel to handle the button clicks. For some reason if I add the update panel and signature pad controls directly into the aspx file the auto postback events work but when I place the same code into a web user control the fields (canvas, buttons, divs, etc) appear but the auto postback no longer works. In both cases I am placing my script manager above the update panel.
Here's my ascx code:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="Signature_Pad.ascx.cs" Inherits="Controls_Signature_Pad" %>
<asp:UpdatePanel runat="server" ID="signatureUpdate" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="signatureApprove" eventname="Click" />
<asp:AsyncPostBackTrigger controlid="sigClear" eventname="Click" />
<asp:AsyncPostBackTrigger controlid="sigCancel" eventname="Click" />
</Triggers>
<ContentTemplate>
<fieldset id="SignatureFieldSet" runat="server" style=" border: 1 solid black;">
<p><asp:Label ID="signatureTextLabel" AutoPostBack="true" runat="server" Text=""></asp:Label></p>
<div id="canvasDiv" style="height: 300px; border:0px solid #000000; ">
<canvas id="canvasSignature" style="border:1px solid #000000;"></canvas>
</div>
<div id="sigButtonDiv" style=" border:0px solid #000000;">
<br /><br />
<asp:Button AutoPostBack="true" runat="server" OnClick="OnApprove" ID="signatureApprove" Text="Approve" />
<asp:Button AutoPostBack="true" runat="server" OnClick="OnClear" ID="sigClear" Text="Clear" />
<asp:Button AutoPostBack="true" runat="server" OnClick="OnCancel" ID="sigCancel" Text="Cancel" />
</div>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
Here's my ascx code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Controls_Signature_Pad : System.Web.UI.UserControl
{
private string signatureData;
private string signatureText;
public string SignatureData
{
get { return signatureData; }
set { signatureData = value; }
}
public string SignatureText
{
get { return signatureText; }
set { signatureText = value; }
}
public void OnApprove(object sender, EventArgs e)
{
UtilityClass.showMessageBox("Approve Clicked", this);
SignatureText = "Approved Clicked";
}
public void OnClear(object sender, EventArgs e)
{
UtilityClass.showMessageBox("Clear Clicked", this);
SignatureText = "Clear Clicked";
}
public void OnCancel(object sender, EventArgs e)
{
UtilityClass.showMessageBox("Cancel Clicked", this);
SignatureText = "Cancel Clicked";
}
public void Page_Load(object sender, EventArgs e)
{
signatureTextLabel.Text = signatureText;
}
}
Here's my relevant aspx:
...
<%# Register TagPrefix="mjt" TagName="SignaturePad" Src="~/Controls/Signature_Pad.ascx" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<asp:ScriptManager ID="ScriptManager" runat="server" EnablePartialRendering="true" EnablePageMethods="true"></asp:ScriptManager>
<mjt:SignaturePad ID="SignaturePad" runat="server" Visible="true" SignatureData="" SignatureText="Test Signature Test." />
...
Adding event handlers in the code behind fixed the problem. Here's my code:
The control had three buttons that needed to trigger events (Approve, Clear, and Canceled).
In ascx.cs:
public event EventHandler Approved;
public event EventHandler Cleared;
public event EventHandler Canceled;
protected void signatureApprove_clicked(object sender, EventArgs e)
{
if(Approved != null)
Approved(this, EventArgs.Empty);
}
protected void sigClear_clicked(object sender, EventArgs e)
{
if (Cleared != null)
Cleared(this, EventArgs.Empty);
}
protected void sigCancel_clicked(object sender, EventArgs e)
{
if (Canceled != null)
Canceled(this, EventArgs.Empty);
}
In ascx:
<asp:UpdatePanel runat="server" ID="signatureUpdate" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="signatureApprove" eventname="Click" />
<asp:AsyncPostBackTrigger controlid="sigClear" eventname="Click" />
<asp:AsyncPostBackTrigger controlid="sigCancel" eventname="Click" />
</Triggers>
<ContentTemplate>
<fieldset id="SignatureFieldSet" class="fieldSetStyle" >
<p><asp:Label ID="signatureTextLabel" AutoPostBack="true" runat="server" Text=""></asp:Label></p>
<div id="canvasDiv" runat="server" >
<canvas id="canvasSignature" class="canvasStyle"></canvas>
</div>
<div id="sigButtonDiv">
<br />
<asp:Button AutoPostBack="true" runat="server" OnClick="signatureApprove_clicked" ID="signatureApprove" Text="Approve" CssClass="buttonStyle" />
<asp:Button AutoPostBack="true" runat="server" OnClick="sigClear_clicked" ID="sigClear" Text="Clear" CssClass="buttonStyle"/>
<asp:Button AutoPostBack="true" runat="server" OnClick="sigCancel_clicked" ID="sigCancel" Text="Cancel" CssClass="buttonStyle"/>
</div>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
In aspx:
<mjt:SignaturePad OnApproved="Signature_Approved" OnCanceled="Signature_Canceled" OnCleared="Signature_Cleared" ID="SignaturePad" runat="server" />
In aspx.cs:
protected void Signature_Approved(object sender, EventArgs e)
{
//Do signature approved action
}
protected void Signature_Canceled(object sender, EventArgs e)
{
//Do signature cancel action
}
protected void Signature_Cleared(object sender, EventArgs e)
{
//Do signature cleared action
}
I'm getting "Type 'ViewStateTest._Default+sInfo' in Assembly... is not marked as serializable" error when trying to keep generic list values after postback, what am I doing wrong here?
code:
public partial class _Default : System.Web.UI.Page
{
List<sInfo> InfoList1 = new List<sInfo>();
sInfo Info1;
struct sInfo
{
public int LSR;
public string BrandAcc;
public string CreateDate;
public string QName;
}
private void CreateArray()
{
Info1.LSR = 2;
Info1.BrandAcc = "AA";
Info1.CreateDate = "12/12/2011";
Info1.QName = "Completed";
InfoList1.Add(Info1);
}
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["arrayListInViewState"] != null)
{
InfoList1 = (List<sInfo>)ViewState["arrayListInViewState"];
}
else
{
// ArrayList isn't in view state, so we need to load it from scratch.
CreateArray();
}
// Code that uses PageArrayList.
Label1.Text = InfoList1[0].LSR.ToString();
Label2.Text = InfoList1[0].BrandAcc;
Label3.Text = InfoList1[0].CreateDate;
Label4.Text = InfoList1[0].QName;
}
void Page_PreRender(object sender, EventArgs e)
{
// Save PageArrayList before the page is rendered.
ViewState.Add("arrayListInViewState", InfoList1);
}
protected void Timer1_Tick(object sender, EventArgs e)
{
}
html code:
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick"></asp:Timer>
<asp:HiddenField ID="hfTableTopInfoCount" runat="server" Value="0" />
<div id="Container">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<br />
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
<br />
<asp:Label ID="Label3" runat="server" Text="Label"></asp:Label>
<br />
<asp:Label ID="Label4" runat="server" Text="Label"></asp:Label>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
[Serializable]
struct sInfo
Objects that go into viewstate need to be marked serialializable.