ArrayList Session - c#

I have a array list formed to each genre of music, for example I will show country music:
public class CountryItemList
{
ArrayList CountryItems = new ArrayList();
protected void CountryBuy1_Click(object sender, ImageClickEventArgs e)
{
CountryItems.Add("Johnny Cash - I Walk The Line - $9");
}
protected void CountryBuy2_Click(object sender, ImageClickEventArgs e)
{
CountryItems.Add("Carrie Underwood - Blown Away - $9");
}
protected void CountryBuy3_Click(object sender, ImageClickEventArgs e)
{
CountryItems.Add("Keith Urban - The Story So Far - $9");
}
protected void CountryBuy5_Click(object sender, ImageClickEventArgs e)
{
CountryItems.Add("Taylor Swift - Red - $11");
}
protected void CountryBuy6_Click(object sender, ImageClickEventArgs e)
{
CountryItems.Add("Willie Nelson - Legend - $9");
}
}
}
for each buy button that is clicked, the selected album is added to the array list, from then on i wish to take the array list into a session and carry it over to a list box on the "shopping cart page". I am having trouble taking the array list and making it into a session to carry over to the next page

You're just going to need to use Session[] to carry it over.
I'd use a List rather than an ArrayList.
Try something like:
private List<string> _countryItems;
public List<string> CountryItems {
get {
if (_countryItems == null) {
_countryItems = (List<string>)Session["CountryItems"];
if (_countryItems == null) {
_countryListItems = new List<string>();
Session["CountryItems"] = _countryItems;
}
}
return _countryItems;
}
set { _countryItems = value; }
}
protected void CountryBuy6_Click(object sender, ImageClickEventArgs e) {
CountryItems.Add("Willie Nelson - Legend - $9");
}
This way you reference CountryListItems directly from the Session. If it exists in the session, you will get the value from session. If it doesn't, you will get an empty List that you can add values to. This should then commit any updates to the session as you add the elements.
Also, look at using CommandEventArgs, which will allow you to create a single click event called from multiple places, then you will be able to send the individual comment event args in on e and get the values right from the markup.

I've always been less than enthusiastic for using Session for things like this. I find it's not as reliable as using a database table, especially for something like a shopping cart.
If you ever needed to restart your application pool, any current users would lose their selections if you store it in Session. You also shouldn't assume that putting something into Session is readily available right away.
You should think about storing this stuff inside a database table. You could sssign each user a GUID when they add something to the cart for the first time and use that in addition to a product ID for each song. Throw that GUID into a cookie so if they come back at a later date, their cart will still be full. You could also use their SessionID if you don't want to use cookies or care if their cart is empty if they close the window.
If you want to continue to use Session, something like this would work
protected List<string> SelectedSongs
{
get
{
List<string> li = new List<string>();
if (Session["SelectedSongs"] != null)
{
try
{
return (List<string>)Session["SelectedSongs"];
}
catch (Exception e)
{
return li; // Something went wrong? Return the empty list.
}
}
else
{
return li;
}
}
set
{
Session["SelectedSongs"] = value;
}
}
For adding them into the List, you could really clean up your code a bit by using just one Event Handler. Something like this
protected void AddToCart(object sender, CommandEventArgs e)
{
List<string> li = SelectedSongs;
li.Add(e.CommandArgument )
SelectedSongs = li;
}
<asp:Button id="btnAddToCart" Text="Add Song" CommandArgument="Johnny Cash - I Walk The Line - $9" CommandName="AddToCart" runat="server"/>
<asp:Button id="btnAddToCart" Text="Add Song" CommandArgument="Carrie Underwood - Blown Away - $9" CommandName="AddToCart" runat="server"/>
And so forth for the other songs.

I don't think this will get a best shopping card award, but it'll do the job.
It basically stored the selected items into Session, so that you can retrieved it back in next page.
Note: ArrayList is deprecated, so please use Generic List.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="CountryItemList.aspx.cs"
Inherits="WebApplication2010.CountryItemList" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button runat="server" ID="Button1" OnCommand="Button_Command"
CommandName="Johnny Cash - I Walk The Line - $9"
Text="Johnny Cash - I Walk The Line - $9" /><br/>
<asp:Button runat="server" ID="Button2" OnCommand="Button_Command"
CommandName="Carrie Underwood - Blown Away - $9"
Text="Carrie Underwood - Blown Away - $9" /><br/>
<asp:Button runat="server" ID="Button3" OnCommand="Button_Command"
CommandName="Keith Urban - The Story So Far - $9"
Text="Keith Urban - The Story So Far - $9" /><br/>
<asp:Button runat="server" ID="Button4" OnCommand="Button_Command"
CommandName="Taylor Swift - Red - $11"
Text="Taylor Swift - Red - $11" /><br/>
<asp:Button runat="server" ID="Button5" OnCommand="Button_Command"
CommandName="Willie Nelson - Legend - $9"
Text="Willie Nelson - Legend - $9" />
</div>
</form>
</body>
</html>
public partial class CountryItemList : System.Web.UI.Page
{
public List<string> CountryItems
{
get { return Session["CountryItems"] as List<string> ?? new List<string>(); }
set { Session["CountryItems"] = value; }
}
protected void Button_Command(object sender, CommandEventArgs e)
{
var items = CountryItems;
items.Add(e.CommandName);
CountryItems = items;
}
}

Try this
Page 1:
protected void Page_Load(object sender, EventArgs e)
{
//Creating Session
ArrayList idList = new ArrayList();
idList.Add("1");
idList.Add("2");
idList.Add("3");
Session["idArrayList"] = idList;
}
Page 2:
protected void Page_Load(object sender, EventArgs e)
{
//Retrieving
ArrayList idList = (ArrayList)Session["idArrayList"];
string id1 = idList[0].ToString() ;
string id2 = idList[1].ToString();
string id3 = idList[2].ToString();
}
Source: http://forums.asp.net/t/1425975.aspx?C+How+to+place+an+arraylist+inside+a+Session+Variable+and+Iterate+through+it

Related

How to put a label into a checkboxlist from another page for asp.net

I tried doing this on the check box list page:
protected void Page_Load(object sender, EventArgs e)
{
(string)Session["name"] = cbl1.Items.Add;
}
but I don't know how to make it work.
You don't really "put a label into" a check box list from another page.
You might say have a check box list on one page, and you want to pass the selection(s) made in the first page, and pass to the 2nd page.
So, say we have a simple check box list of options on page 1
And a button to jump to the next page.
This markup:
<h3>Hotel Options</h3>
<asp:CheckBoxList ID="CheckBoxList1" runat="server"
DataValueField ="ID"
DataTextField="HotelOption" >
</asp:CheckBoxList>
<br />
<br />
<asp:Button ID="Button1" runat="server"
Text="Continue to next page" CssClass="btn" OnClick="Button1_Click" />
And code to load this up:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadCheckBox();
}
void LoadCheckBox()
{
DataTable rstOptions =
MyRst("SELECT ID, HotelOption FROM tblOptions ORDER BY ID");
CheckBoxList1.DataSource = rstOptions;
CheckBoxList1.DataBind();
}
DataTable MyRst(string strSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.Hotels))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
And we now have this:
Ok, so now our code for the button.
We will get + save the above selections, and pass to the next page:
protected void Button1_Click(object sender, EventArgs e)
{
Session["MyItems"] = CheckBoxList1.Items;
Response.Redirect("WebForm2.aspx");
}
Ok, now our markup for the 2nd page.
We have this:
<h3>Hotel Options - on next page</h3>
<asp:CheckBoxList ID="CheckBoxList1" runat="server"
DataValueField ="Value"
DataTextField="Text" >
</asp:CheckBoxList>
<br />
Now, we saved the "items list" for the Check box list. The item list has a text and value property (we LOSE the colum name information that the data sourced used was).
So, note how the DataValueField="value" and DataTextField="Text" now.
So, this code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadCheckBox();
}
void LoadCheckBox()
{
ListItemCollection MyItems = (ListItemCollection)Session["MyItems"];
foreach (ListItem OneItem in MyItems)
{
CheckBoxList1.Items.Add(OneItem);
}
}
And now on 2nd page we have this:
Now it is NOT clear why I can't just bind this passed list directly to the check box list, but I found a foreach loop is required.
Now, it is perhaps not clear, but maybe you ONLY wanted the label text ones selected.
You can do this with this code:
ListItemCollection MyItems = (ListItemCollection)Session["MyItems"];
foreach(ListItem OneItem in MyItems)
{
if (OneItem.Selected)
{
Debug.Print("Label text = " + OneItem.Text);
Debug.Print("Check box value = " + OneItem.Value);
}
}
Output:
Label text = Smoking
Check box value = 1
Label text = Balcony
Check box value = 2
So, keep in mind that a check box list can often have 2 columns of data.
The display "label" or text, or the hidden value.
In my example, the "ID" is the PK value from the database, and I need that.
If you only have one "text" value, and don't care about a hidden database PK value, then often I just set both DataTextField and DataValueField to the SAME column in the database.
And if you using looping, and adding a listitem in code? Then the settings are not the field columns anymore, but Text and Value. You thus still have the ability to have 2 values - the display text, and some key or number value for a checkbox list.
Now perhaps you have two web pages open, and you want to change/set controls in the other web page?
No, you can't do that. Other web pages might say be open to someone's banking web site. You can't mess around with other web pages the user has open, since that would be a MASSIVE security hole, and no one would risk using the world wide web then, right?
Edit: placing the results on a label on the 2nd page
Ok, so the debug.print? That is just a handy debugging way of displaying some code values - only for developers. It really much like using console.log to display value(s) into the console. It certainly not for putting some text into a label (I realy thought that would be crystail clear to you - at a loss as to why you think debug.print has anything of value or is relavent to YOU writing code to put a few text values into a label).
So, ok, on the 2nd page we will have a label and not some check box list.
So, our markup on the 2nd page will now look like this:
<asp:Label ID="Label1" runat="server" Text=""
Font-Bold="true"
Font-Size="Large"
></asp:Label>
And in our page load event, we will have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadLabel();
}
void LoadLabel()
{
ListItemCollection MyChoices = (ListItemCollection)Session["MyItems"];
// process selection list from
// previous page - shove reuslts into label
string strChoices = "";
foreach (ListItem OneChoice in MyChoices)
{
if (OneChoice.Selected)
{
if (strChoices != "")
strChoices += ",";
strChoices += OneChoice.Text;
}
Label1.Text = strChoices;
}
}
So, now on first page, we say select this:
And now on 2nd page, we see this:
Of course, we could change our code to display each choice on a new line,
Say this code:
void LoadLabel()
{
ListItemCollection MyChoices = (ListItemCollection)Session["MyItems"];
// process selection list from
// previous page - shove reuslts into label
string strChoices = "";
foreach (ListItem OneChoice in MyChoices)
{
if (OneChoice.Selected)
{
if (strChoices != "")
strChoices += #"<br/>"; // <-- new line in label
strChoices += OneChoice.Text;
}
Label1.Text = strChoices;
}
}
And now we would see this:
So, you can shove results into that label - separated by ",", or whatever.
Or, you can display the choices on a new line as per last example.

ASP.NET Session State & Postback problems

I have a problem that I believe is a session state issue, but I'm at a loss to figure out what's wrong. I have a sample project to illustrate the problem. (Code below) I have 2 buttons. Each populates a List with some unique data and then uses that data to add a row to a table. The row contains text boxes so that the user can edit the data. (For my sample, there's no update button to persist the data.) To reproduce the problem in VS2010, create a new "ASP.NET Web Application" project and copy/paste the aspx code and the c# code-behind into Default.aspx, then run the application.
Press the DataSet 1 button and the grid should populate with 1 row.
Edit the data in one of the text boxes and tab off of the text box. (The newly entered text should remian, and the font should be blue. This is what I want to happen.)
Now click either of the DataSet buttons to reset the List and refresh the table.
Edit the data in one of the text boxes and tab off the text box. (Immediately, the text in the box refreshes back to its original value. This only happens once, though. If you edit either text box now, it will work normally.)
This is repeatable... the first edit after pressing the DataSet buttons a 2nd, 3rd, etc. time gets reset back to the original value. And I can't figure out why.
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="DebugPostbackIssue._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>
Welcome to ASP.NET!
</h2>
<p>
Populate the table with DataSet #1:<asp:Button runat="server" ID="btnDS1" Text="Dataset 1" OnClick="btnDS1_Click" />
</p>
<p>
Populate the table with DataSet #2:<asp:Button runat="server" ID="btnDS2" Text="Dataset 2" OnClick="btnDS2_Click" />
</p>
<p>
<asp:Table runat="server" ID="tblData">
<asp:TableHeaderRow runat="server" ID="thrData">
<asp:TableHeaderCell Scope="Column" Text="Column 1"></asp:TableHeaderCell>
<asp:TableHeaderCell Scope="Column" Text="Column 2"></asp:TableHeaderCell>
</asp:TableHeaderRow>
</asp:Table>
</p>
</asp:Content>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DebugPostbackIssue
{
public partial class _Default : System.Web.UI.Page
{
private List<string> _MyData = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Page_Init(object sender, EventArgs e)
{
LoadSessionData();
GenerateGrid(false);
}
protected void btnDS1_Click(object sender, EventArgs e)
{
_MyData = new List<string>();
_MyData.Add("111");
_MyData.Add("aaa");
SaveSessionData();
GenerateGrid(true);
}
protected void btnDS2_Click(object sender, EventArgs e)
{
_MyData = new List<string>();
_MyData.Add("222");
_MyData.Add("bbb");
SaveSessionData();
GenerateGrid(true);
}
private void SaveSessionData()
{
Session["MyData"] = _MyData;
}
private void LoadSessionData()
{
if (Session["MyData"] != null)
_MyData = (List<string>)Session["MyData"];
else
_MyData = new List<string>();
}
private void GenerateGrid(bool ClearData)
{
if (ClearData)
while (tblData.Rows.Count > 1)
tblData.Rows.Remove(tblData.Rows[tblData.Rows.Count - 1]);
TableRow tr = new TableRow();
foreach (string s in _MyData)
{
TableCell tc = new TableCell();
TextBox txtBox = new TextBox();
txtBox.Text = s;
txtBox.Attributes.Add("OriginalValue", s);
txtBox.TextChanged += new EventHandler(txtBox_TextChanged);
txtBox.AutoPostBack = true;
tc.Controls.Add(txtBox);
tr.Cells.Add(tc);
}
if (tr.Cells.Count > 0)
tblData.Rows.Add(tr);
}
void txtBox_TextChanged(object sender, EventArgs e)
{
TextBox Sender = (TextBox)sender;
if (Sender.Text == Sender.Attributes["OriginalValue"])
Sender.ForeColor = System.Drawing.Color.Black;
else
Sender.ForeColor = System.Drawing.Color.Blue;
}
}
}
Hi I took some time off of my work to compile your code, and I figured it out, just change your textbox change to the following :
void txtBox_TextChanged(object sender, EventArgs e)
{
TextBox Sender = (TextBox)sender;
if (Sender.Text == Sender.Attributes["OriginalValue"])
Sender.ForeColor = System.Drawing.Color.Black;
else
{
Sender.ForeColor = System.Drawing.Color.Blue;
if (Session["MyData"] != null)
{
List<string> _ss = (List<string>)Session["MyData"];
//_ss.Find(a => a == Sender.Attributes["OriginalValue"]);
_ss.Remove(Sender.Attributes["OriginalValue"]);
_ss.Add(Sender.Text);
}
}
}
ur welcome!
Try creating a datatable. I would, on "event" copy your asp table content to a datatable, then when you get the servers response add that to the datatable. Then copy the datatable back to your asp table, and repeat... Datatables can be used like variables.
Or try using a cookie.
Try changing...
protected void Page_Init(object sender, EventArgs e)
{
LoadSessionData();
GenerateGrid(false);
}
To...
protected override void OnLoadComplete(EventArgs e)
{
LoadSessionData();
GenerateGrid(false);
}
Based on your description I believe that your value is getting reset because of how the page life cycle works in ASP.NET & that is the page_init is getting called before your event due to ASP.NET quirkiness. Above code is how I work around it, I'm sure there's other ways too.
Okay, I have it working, now. Wizpert's answer pointed me in the right direction... Upon discovering that the TextChanged event did not fire during the times when the value was erroneously being reset to the original value, it occurred to me that during the Click events I was calling GenerateGrid(true). This forced the removal of the existing rows and the addition of new rows. (Removing & adding the dynamic controls at that point in the life cycle must be interfering with the TextChange event handler.) Since the Click event fires after Page Init and after Page Load, the state values were already written to the text boxes and I was overwriting them. But the 2nd text box edit did not force GenerateGrid(true) to be called so the state values were not overwritten any more.
If this sounds confusing, I apologize. I'm still wrapping my head around this. But suffice to say that I had to change my GenerateGrid method to reuse any existing rows and not delete them. (If they don't exist, like when GenerateGrid is called from Page Init, then they are added.) So this was a page lifecycle issue after all.
Thank you.

Retrieve value from dynamically created control

I have two dropdown lists, one for days and one for nights. I also have two buttons, one button creates dynamic textboxes where the customer can enter what they want to do in day time and in place where they want to spend night.
e.g., if one customer selects 4 days and 4 nights, a textbox will be created on press of the first button.
When the user clicks the second button, I want to store all those values in database, but I noticed that on postback the fields are lost and I have no data to store.
How do I get the values from the controls created at runtime upon postback?
Here is how you can do it:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["testTextBox"] != null)
{
Request.Form[Session["testTextBox"].ToString()].ToString()
}
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox t = new TextBox { ID = "testTextBox" };
this.Form.Controls.Add(t);
Session["testTextBox"] = t.UniqueID;
}
If you are adding the textbox via a client side call you don't need to store the UniqueID. Button1_Click is the postback method for your button for example.
Even though adding controls in code behind is "fine", it can lead to trouble later. It also isn't very good when editing your view, and you have to change a bunch of code in code-behind. A solution is to use a data bound control, for instance a Repeater control. That way, you can design your view in your aspx file, and leave the coding to the cs-file. It also takes care of holding information when using postbacks, since it's already setup to use the viewstate of the controls, meaning you don't have to do it.
So, using a repeater, your aspx can look something like this.
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RepeaterPage.aspx.cs" Inherits="ASPTest.RepeaterPage" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h1>Test</h1>
<div>
<asp:Button Text="Add textbox" ID="Button1" OnClick="OnAddItem" runat="server" />
<asp:Button Text="Read values" ID="Button2" OnClick="OnReadValues" runat="server" />
</div>
<div>
<asp:Label ID="values" runat="server"></asp:Label>
</div>
<asp:Repeater ID="listofvalues" runat="server">
<ItemTemplate>
<asp:HiddenField ID="ID" Value='<%# Eval("ID") %>' runat="server" />
<asp:TextBox ID="ValueBox" Text='<%# Server.HtmlEncode((string)Eval("Value")) %>' runat="server" />
</ItemTemplate>
</asp:Repeater>
</asp:Content>
Notice that I'm using a master page, so the Content control only links to some ContentPlaceHolder in the master page. In this aspx page, you'll see that the itemtemplate in the repeater control sets up all the design needed to show the values. We'll see how this pans out in the code.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ASPTest
{
public partial class RepeaterPage : Page
{
private List<Item> cache;
public List<Item> ItemValues
{
get
{
if (cache != null)
{
return cache;
}
// load values from database for instance
cache = Session["values"] as List<Item>;
if (cache != null)
{
return cache;
}
Session["values"] = cache = new List<Item>();
return cache;
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
listofvalues.DataBinding += bindValues;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!Page.IsPostBack)
{
DataBind();
}
}
protected void OnAddItem(object sender, EventArgs e)
{
ItemValues.Add(new Item("some value"));
DataBind();
}
protected void OnReadValues(object sender, EventArgs e)
{
foreach (RepeaterItem repeateritem in listofvalues.Items)
{
TextBox box = (TextBox)repeateritem.FindControl("ValueBox");
HiddenField idfield = (HiddenField)repeateritem.FindControl("ID");
Item item = findItem(idfield.Value);
item.Value = box.Text;
}
StringBuilder builder = new StringBuilder();
foreach (Item item in ItemValues)
{
builder.Append(item.Value).Append(";");
}
values.Text = builder.ToString();
}
private Item findItem(string idvalue)
{
Guid guid = new Guid(idvalue);
foreach (Item item in ItemValues)
{
if (item.ID == guid)
{
return item;
}
}
return null;
}
private void bindValues(object sender, EventArgs e)
{
listofvalues.DataSource = ItemValues;
}
}
public class Item
{
private readonly Guid id;
private string value;
public Item(string value)
{
this.value = value;
id = Guid.NewGuid();
}
public Guid ID
{
get { return id; }
}
public string Value
{
get { return value; }
set { this.value = value; }
}
}
}
Sorry about the long code example, but I wanted it to be thorough. You'll see that I introduced a list of Items, in the ItemValues property. You can load the values from wherever you want. I used the Session collection, but you can load from database or some other place if you want.
Also, notice how the only thing we know about the view is the control type and control ID. There's no code describing how controls should be added or styled, we leave that to the aspx page. This creates an easy separation of concerns between the two.
Instead, when we want to add a TextBox, we instead add a new instance of the data item, an instance of the Item class. In the OnReadValues method we can update the data items values bound to the repeater, and then use either the values from the controls or the values from the items in our data list.
I hope this illustrates how one can use ASP.NET to create dynamic pages, without creating the controls in code behind, because it's not really needed if you do it like this.

asp.net c# is checkbox checked?

How do I determine if the checkbox is checked or not checked?
Very perplexed why this is not working - it is so simple!
On my web form:
<asp:CheckBox ID="DraftCheckBox" runat="server" Text="Save as Draft?" />
<asp:Button ID="PublishButton" runat="server" Text="Save" CssClass="publish" />
Code behind which runs in the click event for my save button:
void PublishButton_Click(object sender, EventArgs e)
{
if (DraftCheckBox.Checked)
{
newsItem.IsDraft = 1;
}
}
When debugging it never steps into the If statement when I have the checkbox checked in the browser. Ideas?!
I think there maybe some other code affecting this as follows...
In Page_load I have the following:
PublishButton.Click += new EventHandler(PublishButton_Click);
if (newsItem.IsDraft == 1)
{
DraftCheckBox.Checked = true;
}
else
{
DraftCheckBox.Checked = false;
}
newsItem is my data object and I need to set the checkbox checked status accordingly.
When the save button is hit I need to update the IsDraft property based on the checked status of the checkbox:
void PublishButton_Click(object sender, EventArgs e)
{
if (IsValid)
{
newsItem.Title = TitleTextBox.Text.Trim();
newsItem.Content = ContentTextBox.Text.Trim();
if (DraftCheckBox.Checked)
{
newsItem.IsDraft = 1;
}
else
{
newsItem.IsDraft = 0;
}
dataContext.SubmitChanges();
}
}
So, isDraft = 1 should equal checkbox checked, otherwise checkbox should be un-checked. Currently, it is not showing this.
Specify event for Button Click
<asp:Button ID="PublishButton" runat="server" Text="Save" onclick="PublishButton_Click" />
What i can see you have not got a OnClick on your button. So like this:
<asp:CheckBox ID="DraftCheckBox" runat="server" Text="Save as Draft?" />
<asp:Button ID="PublishButton" runat="server" OnClick="PublishButton_Click"
Text="Save" CssClass="publish" />
And then the function should work like it is:
protected void PublishButton_Click(object sender, EventArgs e)
{
if (DraftCheckBox.Checked)
{
newsItem.IsDraft = 1;
}
}
Please replace code as following code..
void PublishButton_Click(object sender, EventArgs e)
{
if (DraftCheckBox.Checked==True)
{
newsItem.IsDraft = 1;
}
}
Try adding onclick="PublishButton_Click" in the button field on the form. And I don't know if it makes a difference, but generated event handlers are protected void.
For me the best solution in the end has been to create 2 separate pages: 1 for editing a news articles & 1 for a new news article. So Ill never then be in the position of a new news data object being created when the page reloads.
Both page return to the article index list page when the save button is pressed and that seems to work with being able to save the state of the draft checkbox and then show the state on the edit page.
The checkbox.checked isn't used in the context you want it to (this is a boolean that if true, will make the checkbox look checked).
What you could do is to use instead a checkboxlist. Then you could do the following:
foreach(Listitem li in CheckBoxList1.Items)
{
if (li.Selected)
{
NewsItem.Isdraft = 1;
}
}

Persistent dynamic control in ASP.Net

<asp:Button onclick="Some_event" Text="Add TextBox" ID="id1" runat="server" />
//once clicked:
<asp:TextBox ID="txt1" ......></asp:TextBox>
//when clicked again:
<asp:TextBox ID="txt1" ......></asp:TextBox>
<asp:TextBox ID="txt2" ......></asp:TextBox>
//and so on...
Is there a way to create dynamic controls which will persist even after the postback? In other words, when the user clicks on the button, a new textbox will be generated and when clicks again the first one will remain while a second one will be generated. How can I do this using asp.net ? I know that if I can create the controls in the page_init event then they will persist but I dont know if it possible to handle a button click before the page_init occurs, therefore there must be another way.
Yes, this is possible. One way to do this using purely ASP.NET (which seems like what you're asking for) would be to keep a count of the TextBox controls that you have added (storing that value in the ViewState) and recreate the TextBox controls in the Page_Load event. Of course, nowadays most people would probably use Javascript or jQuery to handle this task client side, but I put together a quick example to demonstrate how it works with postbacks:
Front page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicControls.aspx.cs" Inherits="MyAspnetApp.DynamicControls" EnableViewState="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"></head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAddTextBox" runat="server" Text="Add" OnClick="btnAddTextBox_Click" />
<asp:Button ID="btnWriteValues" runat="server" Text="Write" OnClick="btnWriteValues_Click" />
<asp:PlaceHolder ID="phControls" runat="server" />
</div>
</form>
</body>
</html>
Code behind:
using System;
using System.Web.UI.WebControls;
namespace MyAspnetApp
{
public partial class DynamicControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Recreate textbox controls
if(Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int) count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void AddTextBox(int index)
{
var txt = new TextBox {ID = string.Concat("txtDynamic", index)};
txt.Style.Add("display", "block");
phControls.Controls.Add(txt);
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void btnWriteValues_Click(object sender, EventArgs e)
{
foreach(var control in phControls.Controls)
{
var textBox = control as TextBox;
if (textBox == null) continue;
Response.Write(string.Concat(textBox.Text, "<br />"));
}
}
}
}
Since you are recreating the controls on each postback, the values entered into the textboxes will be persisted across each postback. I added btnWriteValues_Click to quickly demonstrate how to read the values out of the textboxes.
EDIT
I updated the example to add a Panel containing a TextBox and a Remove Button. The trick here is that the Remove button does not delete the container Panel, it merely makes it not Visible. This is done so that all of the control IDs remain the same, so the data entered stays with each TextBox. If we were to remove the TextBox entirely, the data after the TextBox that was removed would shift down one TextBox on the next postback (just to explain this a little more clearly, if we have txt1, txt2 and txt3, and we remove txt2, on the next postback we'll create two textboxes, txt1 and txt2, and the value that was in txt3 would be lost).
public partial class DynamicControls : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
for (var i = 0; i < TextBoxCount; i++)
AddTextBox(i);
}
}
protected void btnAddTextBox_Click(object sender, EventArgs e)
{
AddTextBox(TextBoxCount);
TextBoxCount++;
}
protected void btnWriteValues_Click(object sender, EventArgs e)
{
foreach(var control in phControls.Controls)
{
var panel = control as Panel;
if (panel == null || !panel.Visible) continue;
foreach (var control2 in panel.Controls)
{
var textBox = control2 as TextBox;
if (textBox == null) continue;
Response.Write(string.Concat(textBox.Text, "<br />"));
}
}
}
private int TextBoxCount
{
get
{
var count = ViewState["txtBoxCount"];
return (count == null) ? 0 : (int) count;
}
set { ViewState["txtBoxCount"] = value; }
}
private void AddTextBox(int index)
{
var panel = new Panel();
panel.Controls.Add(new TextBox {ID = string.Concat("txtDynamic", index)});
var btn = new Button { Text="Remove" };
btn.Click += btnRemove_Click;
panel.Controls.Add(btn);
phControls.Controls.Add(panel);
}
private void btnRemove_Click(object sender, EventArgs e)
{
var btnRemove = sender as Button;
if (btnRemove == null) return;
btnRemove.Parent.Visible = false;
}
}
I read an article by Scott Mitchell that explains that ViewState only persists changed control state across post-back, and not the actual controls themselves. I did not have your exact scenario, but a project I was working on required dynamically added user controls and I had to add them on every postback. In that case, it is still useful to create them in Init so that they can retain their state. Here is the link: Understanding ASP.NET View State. Check section “View State and Dynamically Added Controls”.
You may have to keep track of all the controls that you are adding (in session state for example) and re-create them on post back. I just did a small test where I keep a List<string> of all the Textbox ids in Session. On postback, I recreate all the textboxes.

Categories