SelectionList always returns NULL - c#

I have a very strange issue where SelectionList always returns NULL when i try check its Selected Item/Value. I Googled a bit and I found out that when i click the submit button, the page is being refreshed and the SelectionList is being data bound again so it will revert back to its original behavior.
Then i tried enclosing the binding code in the Page_Load event in a !IsPostBack but still when i try to access the Selected property it is null and an exception is thrown.
Any help would be greatly appreciated.
My code goes something like this... (the braces are not matched properly)
static SelectionList[] Symptoms;
static string UserID = "";
cmbSymptoms1,cmbSymptoms2,cmbSymptoms3 and cmbSymptoms4 are SelectionLists. I took them in to an array of SelectionList and then set the properties.
I had to make them static or else when i click the button to update, they will not retain their values. Any idea why they don't retain the values?
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack == false)
{
//System.Diagnostics.Debug.WriteLine("Not IsPostBack");
if (Request.QueryString["id"] != null && Request.QueryString.ToString() != "")
{
//System.Diagnostics.Debug.WriteLine("id query string is not null :- " + Request.QueryString["id"]);
myclass = new Class1();
UserID = Request.QueryString["id"];
Symptoms = new SelectionList[4];
Symptoms[0] = cmbSymptoms1;
Symptoms[1] = cmbSymptoms2;
Symptoms[2] = cmbSymptoms3;
Symptoms[3] = cmbSymptoms4;
System.Data.DataTable dt = myclass.getAllSymptoms();
foreach (SelectionList listItem in Symptoms)
{
listItem.DataSource = dt;
listItem.DataTextField = "symptomsname";
listItem.DataValueField = "symptomsid";
listItem.DataBind();
listItem.Items.Insert(0, new MobileListItem("None"));
}
And in the update button click event
protected void cmbUpdate_Click(object sender, EventArgs e)
{
foreach (SelectionList listItem in Symptoms)
{
if (listItem.SelectedIndex != 0)
{
cmd.CommandText = "INSERT INTO Patient_Symptom (patientid,symptomid) VALUES (" + UserID + ",'" + listItem.Selection.Value + "')";
cmd.ExecuteNonQuery();
}
}
}

You can try two things. Try placing the databinding code in the PreRender event. The second and better option would be to use an ObjectDataSource controls and bind the control declaratively.

Related

using global controls in different methods

I am trying to declare a global control (checkboxlist) variable and populate in one methode and check which one are selected in another method
public CheckBoxList chklExtraDrink ;
protected void Page_Load(object sender, EventArgs e)
{
chklExtraDrink = new CheckBoxList();
}
//this function will fill the checkboxlist
public void fillupCheckboxlist(GridViewRow row)
{
chklExtraDrink.RepeatColumns = 3;
Accordion accorExtra = (row.FindControl("accorExtra") as Accordion);
DataSet ds = new DataSet();
string cmdstr = "select p.name + ' (€' + cast(pp.value as varchar) + ')' as name, (CAST(p.product_id as varchar) + ',' + CAST(pp.price_id as varchar))as valueF from product p, price_product pp WHERE p.product_id = pp.product_id and p.main_product_id = #mainProductId";
SqlDataAdapter adp = new SqlDataAdapter(cmdstr, new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["db_pizzaConnectionString"].ConnectionString));
adp.SelectCommand.Parameters.AddWithValue("#mainProductId", 26);
adp.Fill(ds);
chklExtraDrink.DataSource = ds;
chklExtraDrink.DataTextField = "name";
chklExtraDrink.DataValueField = "valueF";
chklExtraDrink.DataBind();
AccordionPane ap1 = new AccordionPane();
ap1.HeaderContainer.Controls.Add(new LiteralControl("text"));
ap1.ContentContainer.Controls.Add(chklExtraDrink);
accorExtra.Panes.Add(ap1);
}
//this function will eventually check all selected items
public void btnOkay_Click(object sender, EventArgs e)
{
foreach (ListItem item in chklExtraDrink.Items)
if (item.Selected) values.Add(new Order(item.Value.Split(',')[0], item.Value.Split(',')[1], emptyList, 1));
}
with this code, i am getting no values back from the checkboxlist.
Can you show the code with the event handler? Typically, the btnClick will have handling code inside. You can use the Events view of the Properties window to see the events and select the events you want to handle.
Getting the button click is just the first step. You need to assign a handler and write a handler method to be called when the event triggers it.
EDIT:
Links are short lived, but while it lasts, here is the Microsoft doco:
https://msdn.microsoft.com/en-us/ie/aa984320%28v=vs.94%29
A quick example is below:
namespace StackOverflow
{
public partial class UserForm : Form
{
public UserForm()
{
InitializeComponent();
}
private void clbCheckedListBox_SelectedIndexChanged(object sender, EventArgs e)
{
// code here or call to generic handler
}
}
}

Calling method from an <li> element , inside the Literal.text string

I am having the following problem: I want to call a method whenever a specific li is clicked. Problem is that the li is dynamically created in a literal.text string, where I do import things from my database.
Whenever I try to call a method it does not work. I want to call a method whenever the user clicks on each li and get that li information inside my method (haven't wrote the method code yet, because I can't get it called.)
Thoughts?
protected void Page_Load(object sender, EventArgs e)
{
string conString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source="
+ Server.MapPath("~/ebookstoredb.mdb");
using (OleDbConnection con = new OleDbConnection(conString))
{
con.Open();
string query = "SELECT * FROM CATEGORY";
using (OleDbCommand cmd = new OleDbCommand(query, con))
{
OleDbDataReader reader = cmd.ExecuteReader();
String msg = "";
while (reader.Read())
{
lit1.Text += "<ul>" + "<li runat=\"server\" OnClick=\"ProductsInfo\">" + reader["ID"]
+ "," + reader["Name"]
+ "</li>"
+ "</ul>";
}
reader.Close();
}
con.Close();
}
}
protected void ProductsInfo(object sender, EventArgs e)
{
Response.Redirect("Default.aspx");
}
Unfortunately, you cannot create server-side events on a Literal Control.
However, you can add client-side javascript functionality to post back a request.
In your aspx using:
<div>
<asp:Literal runat="server" ID="lit1"></asp:Literal>
</div>
Your aspx.cs should contain:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
lit1.Text += "<ul>" + "<li \' onclick=\'javascript: __doPostBack(\"getProduct\", \"1\");\'>"
+ "Product " + "1"
+ "</li>"
+ "</ul>";
}
if (Request.Form["__EVENTTARGET"] != null && Request.Form["__EVENTTARGET"] == "getProduct")
{
getProduct_Click(null, null);
}
}
private void getProduct_Click(object sender, System.EventArgs e)
{
Response.Write("You Clicked on " + Request.Form["__EVENTARGUMENT"]);
}
This will set up each li to pass their own value to the event argument hidden control and perform a postback to the server.
You can then check if the event target is the required one and call a method with the value that was posted back.
Just change the sample lit1 text above to iterate through your data.
I've never used literals before, but from reading about them... with a literal displaying just static html, you will need to have each li call a javascript function that will then do a postback to the method you want. So build your li like this:
lit1.Text += "<ul><li><a onclick=\"CallProductInfo(" + reader["ID"]+ ")\">" + reader["ID"]
+ "," + reader["Name"]
+ "</a></li></ul>";
Then you have to have a javascript function that does the actual postback to your server side code or redirects to the products info page with the passed id. That is, in your page (not the code behind), have a script something like this for the postback...
<script>
function CallProductInfo(id)
{
__doPostBack('ProductInfoId', id);
}
</script>
In you code behind, in your page load event handler, you'd have something like this:
if (Request["__EVENTTARGET"] == "ProductInfoId")
{
ProductInfo(Convert.ToInt64(Request["__EVENTARGUMENT"]));
}
Ok so guys i found out what was the problem. Our mr.genious instructor told us today that we can use a datagrid..Sigh.
Thanks everyone for your replies!

repeater paging viewstate

So finally.. I have my repeater working as I want it to be full of buttons, radio button, image buttons, update panels, AJAX modal popups and a heavy code behind each event.
found out that my repeater getting very slow when the items exceeds 20, so I used paging as a solution. the problem is when I do changes and move on to the next page, all changes are gone when getting back to the previous page. (checked radios, labels, etc all back to normal state).
please help, my system is in production now.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
loadTasks();
}
void loadTasks()
{
string evalidxxx = Request.QueryString["eval_id"].Trim().Replace(" ", "");
SqlConnection conn = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["GappConnectionString2"].ConnectionString);
try
{
conn.Open();
SqlDataAdapter sqlAdapter = new SqlDataAdapter("SELECT Prog_Task_link.pt_seq, Tasks.task_name, Tasks.task_id FROM Tasks INNER JOIN Prog_Task_link ON Tasks.task_id = Prog_Task_link.task_id INNER JOIN Programs ON Prog_Task_link.prog_id = programs.prog_id INNER JOIN Data_Tracker_prepare ON Programs.prog_id = Data_Tracker_prepare.dtpre_prog_id WHERE Data_Tracker_prepare.eval_id =" + evalidxxx, conn);
System.Data.DataTable dt = new System.Data.DataTable();
sqlAdapter.Fill(dt);
PagedDataSource objPds = new PagedDataSource();
objPds.DataSource = dt.DefaultView;
objPds.AllowPaging = true;
objPds.PageSize = 10;
objPds.CurrentPageIndex = CurrentPage;
lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of "
+ objPds.PageCount.ToString();
//Disable Prev or Next buttons if necessary
LinkPrevPage.Enabled = !objPds.IsFirstPage;
LinkNextPage.Enabled = !objPds.IsLastPage;
rptr1.DataSource = objPds;
rptr1.DataBind();
}
catch (SqlException ex)
{
Response.Write(ex.Message);
}
finally { conn.Close(); }
}
public int CurrentPage
{
get
{
// look for current page in ViewState
object o = this.ViewState["_CurrentPage"];
if (o == null)
return 0; // default to showing the first page
else
return (int)o;
}
set
{
this.ViewState["_CurrentPage"] = value;
}
}
protected void LinkPrevPage_Click(object sender, EventArgs e)
{
CurrentPage -= 1;
loadTasks();
}
protected void LinkNextPage_Click(object sender, EventArgs e)
{
CurrentPage += 1;
loadTasks();
}
if you are using .net 4.0 you can use EnablePersistedSelection="True"
sorry to say but this can not be done..
When you are in page one, the rest pages are not actual exists in repeater.
after paging to next page next data will be load so previous data will be reset
i mean to say, When you ask to select all radios, buttons,check boxes are mean what you see. After you change page the other controls are set to default (probably unchecked or reset)
So re design your user interface for what you want to do. And as my suggestion take another button to save the current state of the page.. and then go to next page..
anything other that i can help ??

change controls based on database value

Problem:
I have a value in a database table. This value can either contain a number, or null. If its null I would like to show one group of controls. If its not null I would like to show another group of controls.
Previous Attempts:
I have tried creating the controls in the code behind depending on the value of the database. This worked. However, on postback I get a null reference exception. The control doesn't exist on postback because the page is stateless. I'm building the controls in the page_load handler (depending on the value of the table column). Since I'm creating the controls in the page_load shouldn't they exist on postback?
I also tried recreating the controls in the event handler for the button. I get a "theres already a control with this id" exception (presumably because I already created it in the page_load method).
I read a few posts about how I have to store the controls in a session. This seems like more work than it should be.
Questions:
Am I going about this the wrong way? This seems like it should have been simple but is turning into a mess.
If this is the correct way to do this, Where do I add the session information? I've been reading other posts and I'm kind of lost
Code:
int bookId;
string empName;
protected void Page_Load(object sender, EventArgs e)
{
if(int.TryParse(Request.QueryString["id"], out bookId))
{
//This is where the value in the database comes into play. If its null Book.GetCopyOwner
// returns a string with length 0
empName = Book.GetCopyOwner(bookId, Request.QueryString["owner"]);
if (empName.Trim().Length > 0)
{
CreateReturnControls();
}
else
{
CreateCheckoutControls();
}
}
}
protected void ReturnButton_Click(object sender, EventArgs e)
{
}
protected void CheckOut_Click(object sender, EventArgs e)
{
int bookId;
if (int.TryParse(Request.QueryString["id"], out bookId))
{
TextBox userId = (TextBox)this.Page.FindControl("UserId");
//WHEN I TRY TO USE THE TEXTBOX userId HERE, I GET NULL REFERENCE EXCEPTION
BookCopyStatusNode.Controls.Clear();
CreateReturnControls();
}
}
protected void CopyUpdate_Click(object sender, EventArgs e)
{
}
private void CreateCheckoutControls()
{
TextBox userId = new TextBox();
//userId.Text = "Enter Employee Number";
//userId.Attributes.Add("onclick", "this.value=''; this.onclick=null");
userId.ID = "UserId";
Button checkOut = new Button();
checkOut.Text = "Check Out";
checkOut.Click += new EventHandler(CheckOut_Click);
TableCell firstCell = new TableCell();
firstCell.Controls.Add(userId);
TableCell secondCell = new TableCell();
secondCell.Controls.Add(checkOut);
BookCopyStatusNode.Controls.Add(firstCell);
BookCopyStatusNode.Controls.Add(secondCell);
}
private void CreateReturnControls()
{
Label userMessage = new Label();
userMessage.Text = empName + " has this book checked out.";
Button returnButton = new Button();
returnButton.Text = "Return it";
returnButton.Click += new EventHandler(ReturnButton_Click);
TableCell firstCell = new TableCell();
firstCell.Controls.Add(userMessage);
TableCell secondCell = new TableCell();
secondCell.Controls.Add(returnButton);
BookCopyStatusNode.Controls.Add(firstCell);
BookCopyStatusNode.Controls.Add(secondCell);
}
It looks like you're creating a static set of controls based on the database value. Why not simply have 2 Panels that contain the controls you want and simply set their visibility to true or false:
if (!Page.IsPostBack)
{
if (int.TryParse(Request.QueryString["id"], out bookId))
{
empName = Book.GetCopyOwner(bookId, Request.QueryString["owner"]);
var display = (empName.Trim().Length > 0);
panelReturnControls.Visible = display;
panelCheckoutControls.Visible = !display;
}
}

C# asp.net why does my manual __doPostBack only run once?

In my code I create the menu items dynamically:
string listClientID = BulletedList1.ClientID.Replace('_', '$');
int counter = 0;
foreach (DataRow dataRow in database.DataTable.Rows)
{
// Add Button
ListItem listItem = new ListItem();
listItem.Value = "buttonItem" + Convert.ToString(dataRow["rank"]);
listItem.Text = " " + Convert.ToString(dataRow["title"]);
listItem.Attributes.Add("onclick", "__doPostBack('" + listClientID + "', '"+ counter.ToString() +"')");
BulletedList1.Items.Add(listItem);
counter++;
}
This menu is inside a update panel:
<div id="MenuItemBox">
<asp:BulletedList
ID="BulletedList1"
runat="server"
OnClick="MenuItem_Click"
>
</asp:BulletedList>
</div>
What I want is when a listitem is clicked it performs a postback. But when I run this, the onclick event is only runned once.
For example. I have 4 listitems. When I click the first item the first time the onclick event is executed. Now I click the second item, the onclick event is also executed. But when I now click the first item again the onclick event is not fired.
When I check the error console in FireFox or Oprah I don't get any errors.
So my question is: how can I fix this and what am I doing wrong?
It seems you need to rebind it after postback.
Where do you add items to the menu and are you checking IsPostBack property?
Please compare html after first loading and postpack to see if _dopostback dissappear.
Then Try to remove IsPostBack check.
My code is working well.
Here is it.
public partial class _Default : System.Web.UI.Page {
protected void Page_Load (object sender, EventArgs e) { }
protected override void OnInit (EventArgs e) {
base.OnInit(e);
//if (!IsPostBack) {
string listClientID = BulletedList1.ClientID.Replace('_', '$');
int counter = 0;
List<SomeClass> items = new List<SomeClass>(){ new SomeClass() { Rank = 1, Title = "2"},
new SomeClass () {Rank = 2, Title = "Two"}};
foreach (var item in items) {
// Add Button
ListItem listItem = new ListItem();
listItem.Value = "buttonItem" + item.Rank;
listItem.Text = " " + item.Title;
listItem.Attributes.Add("onclick", "__doPostBack('" + listClientID + "', '" + counter.ToString() + "')");
BulletedList1.Items.Add(listItem);
counter++;
}
//}
}
protected void MenuItem_Click (object sender, BulletedListEventArgs e) {
Response.Write(e.Index);
}
class SomeClass {
public int Rank;
public string Title;
}
}
Probably UpdatePanel is causing the trouble. I would try pulling it out of UpdatePanel and then would see(which I believe it should) if that works?
Secondly, you can probably just populate the list items Values and Texts only, and then under mnuMainMenu_MenuItemClick(object sender, MenuEventArgs e) event; look for the specific item that has been clicked (e.Item.* public properties), and then probably would use Response.Redirect() to do the job; well, just thinking out loud...

Categories

Resources