Dynamically create multiple ImageButton controls and wire-up Click event - asp.net

I'm pretty new to ASP.NET. Please forgive me for my knowledge :) Assuming I want to create 4 imagebuttons. If I click on any imagebutton, it will move me to another page with different STT (<- just a name).
Here's my code:
for (int i= 0; i< 4; i++)
{
ImageButton image = new ImageButton();
image.Click += (s, args) =>
{
Response.Redirect("~/Showroom.aspx?STT=" + (i));
};
//other things to do
}
Now the problem is that when I click on any imagebutton. I'll be redirected to Showroom.aspx with STT = 4 (which is i after the loop). How can I be redirected to the page with desired STT.
EDIT:
Just to clarify. What I want is Clicking on imagebutton 1 will move me to Showroom.aspx with STT = 0. Imagebutton 2 will move me to the page with STT=1 and so on.

Problem
"~/Showroom.aspx?STT=" + (i) means it captures the variable i rather than its value at the time of delegates creation.
Solution
Create url outside of delegate.
for (int i = 0; i < 3; i++)
{
string url = string.Format("~/Showroom.aspx?STT={0}", i);
var image = new ImageButton();
image.Click += (s, args) => Response.Redirect(url);
}

You need to copy i to a local variable. Or as the other Answer suggests, build your URL before its used in your lambda expression.
int x = i;
image.Click += (s, args) =>
{
Response.Redirect("~/Showroom.aspx?STT=" + (x));
};

Related

Using a dropdown list to get image names from a folder and applying them to an image url

I'm trying to apply the name of the image but the images are not loading.
if (!IsPostBack)
{
string[] str = new string[] { "Select", "Anniversary", "Birthday",
"Graduation", "Sympathy" };
for (int i = 0; i < str.Length; i++)
{
DDl1.Items.Add(str[i]);
} // this Loop creates the items in the drop down list
{
string str = DDl1.Text;
Image1.ImageUrl="~/Media"+str+".png";
} // This is how i was trying to call the images from the Media folder in my project
change this
Image1.ImageUrl="~/Media"+str+".png";
to
Image1.ImageUrl="~/Media/"+str+".png";
Create an event OnSelectedIndexChanged on your <asp:DropDownList> and add AutoPostBack="True".
In Code behind event OnSelectedIndexChanged put the code as below:
string str = DDl1.Text; or string str = DDl1.SelectedText;
Image1.ImageUrl="~/Media/"+str+".png";
I hope this would help you.

How to save Array in View State? And Retrieve That in ASP.NET?

I am using Asp.Net With JqueryMobile (C#). I declare string[] roomno = new string[100]; in my Class.
In Page_load Event:-
if (!Page.IsPostBack)
{
Some Code...
for (int j = 0; j <= vallen; j++)
{
roomno[j] = "A" + Convert.ToString(j + 1);
}
Some Code,..
}
When I Click The Button The Array values is clear.
So I wanna know How to save Array in View State? And Retrieve That in ASP.NET?
ViewState["some_key"] = roomno;
roomno = ViewState["some_key"] as string[];
or words to that effect :)
ViewState["SomeKey"] = (string[])roomno;
roomno = (string[])ViewState["SomeKey"];
Or to initialize
string[] roomno = string[0];
ViewState.Add("SomeKey", roomno);

Flex: assigning events to dynamically created buttons

Thanks to wezzy and the others who helped me out the past couple of days. I've been taking their advice and trying to figure the rest out on my own but I'm stuck again.
I have a txt file structured like this:
button1_label
button2_label
button3_label
My program creates these 3 buttons at runtime and places them in a group.
protected function onLoaded(e:Event):void {
var myArrayOfLines:Array = e.target.data.split(/\n/);
var tempBtn:Button;
for(var i:Number = 0;i < myArrayOfLines.length;i++){
var j:Number = i+1;
tempBtn = new Button();
tempBtn.id = "btn" + i;
tempBtn.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
var index:uint = parseInt(evt.currentTarget.id.replace("btn", ""));
//TextArea code will go here
trace(text); // Traces null
});
tempBtn.label = myArrayOfLines[i];
btnArray.push(tempBtn);
group.addElement(btnArray[i]);
}
}
Now what you can see from my code is that I'm attempting to make each button print a string to a textarea. I've structured my new buttons.txt like this:
button1_label
"Hello"
button2_label
"Goodbye"
button3_label
"Come again"
So what I want to do is have button1 print "Hello". All the lines of the .txt file are pushed into myArrayOfLines. Thanks in advance for any help.
EDIT
Full explanation
Sorry I was trying to simplify my question, guess I made it harder to understand. I made a text editor than runs client side, no server. I have a set of buttons that insert predefined phrases into the TextArea Each button has a listener that does myTextArea.insert("sometext"); (but different text for each button. Users have requested the ability to create their own buttons to insert there own strings. I figured I would have a couple og textinputs where a user could define a label, and a String that would be inserted into the textarea on button click. I would write the label to one line, then the String to the next line. Right now I created a buttons.txt file with this format to see if it would work.
FINAL EDIT: WORKING CODE
public function setupBtns(e:Event):void{
var file:File = File.documentsDirectory.resolvePath("buttons.txt");
var stream:FileStreamWithLineReader = new FileStreamWithLineReader();
stream.open(file, FileMode.READ);
while(stream.bytesAvailable) {
// this line contains the headers like button1_label etc.
var label:String;
// this line contains the string
if(stream.bytesAvailable) {
// this line contains the actual label like "Hello";
label = stream.readUTFLine();
line = stream.readUTFLine();
// strip off the first and last character as they are double quotes
line = line.substring(1, line.length-1);
var tempBtn:Button = new Button();
tempBtn.addEventListener(MouseEvent.CLICK, btnListener);
tempBtn.label = label;
tempBtn.name = line;
btnArray.push(tempBtn);
for(var i:Number = 0;i<btnArray.length;i++){
group.addElement(btnArray[i]);
}
}
}
}
protected function btnListener(e:MouseEvent):void{
mainTextField.insertText(e.target.name);
trace(e.target.name);
}
Try this out and let me know how it works out...
EDIT: (try new code below)
protected function onLoaded(e:Event):void {
var myArrayOfLines:Array = e.target.data.split(/\n/);
var tempBtn:Button;
for(var i:Number = 0;i < myArrayOfLines.length;i=i+1){
var j:Number = i+1;
tempBtn = new Button();
tempBtn.id = "btn" + i;
tempBtn.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
myTextArea.text += '\n' + myArrayOfLines[j];
});
tempBtn.label = myArrayOfLines[i];
btnArray.push(tempBtn);
group.addElement(btnArray[btnArray.length-1]);
}
}
first: don't use anonymous functions as listeners in actionscript - if you yo, you can't remove them later on.
instead use a class method like this:
tempBtn.addEventListener(MouseEvent.CLICK, onMouseClick);
private function onMouseClick(evt:MouseEvent):void
{
if (evt.currentTarget == button1_label)
{
// do sth for btn1
}
else if (evt.currentTarget == button2_label)
{
// do sth for btn2
}
// ...
}
edit
just saw, that you are using IDs, then just change the above code to sth like this:
if (evt.currentTarget.id == "btn1")

ASP.net problem with changing table row visibility

i have a table array dynamically generated from a data query and stored in a session variable. Now i wanna add a textbox to limit how many rows at a time i will display. To test this, i wrote two button methods, one will set some rows to be visible = false, and the second button method will set the same rows back to visible = true.
protected void limit_btn_Click(object sender, EventArgs e)
{
for (int i = 0; i < traceTables.Length; i++)
for (int j = 2; j < traceTables[i].Rows.Count; j++)
traceTables[i].Rows[j].Visible = false;
Session["Tables"] = traceTables;
table_C();
}//end limit_btn_Click()
protected void obo_btn_Click(object sender, EventArgs e)
{
for (int i = 0; i < traceTables.Length; i++)
for (int j = 2; j < traceTables[i].Rows.Count; j++)
traceTables[i].Rows[j].Visible = true;
Session["Tables"] = traceTables;
table_C();
}//end obo_btn_Click()
protected void table_C()
{
String changeTo = log_locations.SelectedValue;
for (int i = 0; i < sshLoc.Length; i++)
{
if (sshLoc[i].CompareTo(changeTo) == 0)
{
table_panel.ContentTemplateContainer.Controls.Remove(traceTables[currentTable]);
System.Diagnostics.Debug.WriteLine("Removing " + sshLoc[currentTable]);
table_panel.ContentTemplateContainer.Controls.Add(traceTables[i]);
System.Diagnostics.Debug.WriteLine("Adding " + sshLoc[i]);
currentTable = i;
Session["CurrentTable"] = currentTable;
break;
}//end if
}//end for
}//end table_C()
table_C() basically removes and adds the table from the panel - i use it when i want to switch between tables from a dropdown list (which works) and in this case it simply removes and adds the same table from the panel content container.
The problem is that setting the rows to be not visible works fine. Setting the rows back to visible never does, and i'm not sure why
Try using display:none and display:visible rather than .visible in ASP
traceTables[i].Rows[j].Add("style","display:none");
Visible removes it completely from the HTML, so you can only show it again by recreating the page.
You need to store data in a list rather than in a table.
When you set the rows to not visible they are being removed from the html table. That is why you cannot set them to visible again.
If you store the data in a seperate object and bind it to the list, you will be able to turn visibility on and off.

Dynamic Template Controls

On !PostBack dynamic templates are created based on the number of rows needed for check boxes. The control id's are chkbox_id. I am unable to retrieve the dynamic check boxes via the following code and NullReferenceException is always thrown.
The code before loops through the gridview rows, then datatable dt references the possible number of dynamic columns.
for (int i = 0; i < dt.Rows.Count; i++)
{
string id = dt.Rows[i]["id"].ToString();
CheckBox cb = (CheckBox)row.FindControl("ckbox_" + id);
if (cb.Checked)
{ // do things }
}
Checkboxes defined here within page load:
if (!Page.IsPostBack)
{
foreach (DataRow dRow in dt.Rows)
{
TemplateField ckhColumn = new TemplateField();
ckhColumn.HeaderTemplate = new GridViewTemplate(ListItemType.Header, dRow["name"].ToString());
ckhColumn.ItemTemplate = new GridViewTemplate(ListItemType.Item, "ckbox_" + dRow["id"].ToString());
gvProductPriceList.Columns.Add(ckhColumn);
}
}
Let me know if I need to clarify anything else.
I'm not positive on this, and I don't have a minute to try it, but it might work if you do a row.Parent.FindControl(...). Also, if you use the as operator instead of a direct cast, you won't have the null reference exception (i.e. you can check for it):
CheckBox cb = row.Parent.FindControl("ckbox_" + id) as CheckBox;
if (cb != null)
{
// ...
}

Resources