I'm working on a project in ASP.net (C#) and I have some trouble in concern with the asp:Panel.
Basically, I have an asp:UpdatePanel in which I have a asp:Panel;
I Also have asp:TextBox and a button.
What I want to do is that : when the user enters text in the asp:TextBox, and then hit the button, the text in the TextBox should Appear in the asp:Panel as a Linkbutton. The Method looks like this :
protected void AddExchange_Click(object sender, EventArgs e)
{
LinkButton link2 = new LinkButton();
link2.Text = AddAdditionalTxt.Text;
// link2.Command += new CommandEventHandler(LinkButton_Command);
ExchangePanel.Controls.Add(link2);
}
It works, and it adds the text as a linkButton to the panel, BUT, when i want to add more, the linkButton which has been added before get overwritten. I want to hold some LIST<string> Variable that'll hold all the strings, But whenever the page PostBack it gets deleted.
I would really appreciate if someone could tell me how to solve it - How do i keep a variable (List<>) in a page with UpdatePanel so every PageLoad I can add all the strings in the list inside the asp:Panel.
Thanks in advance.
this code works for me, the ViewState will keep the List<string> the time the user stays in the page
protected void AddExchange_Click(object sender, EventArgs e)
{
List<string> stringList;
if (ViewState["stringList"] == null)
stringList = new List<string>();
else
stringList = ViewState["stringList"] as List<string>;
stringList.Add(AddAdditionalTxt.Text);
foreach (string myStr in stringList)
{
LinkButton link2 = new LinkButton();
link2.Text = myStr;
// link2.Command += new CommandEventHandler(LinkButton_Command);
ExchangePanel.Controls.Add(link2);
}
ViewState["stringList"] = stringList;
}
Related
I have an asp:Table that is populated in the code behind with TableCells.
I started at this Q&A and was able to set up hyperlinks to the desired page. However, I need to set a C# Property as the link is being clicked.
The first column of the Table has names, my goal was to make the names clickable links that would open a new window or tab (different URL) and pass a Property like described here (In the section : Getting Public Property Values from the Source Page) for the next page to use.
I made the property but for the life of me can't figure out how to set the property as the link is being clicked. I've tried using Hyperlink, Linkbutton, and Button as well as having an HTML a href string placed in the cell.
I think LinkButton came the closest but it did not have a UseSubmitBehavior option to set to false so the link would not process.
I thought that this would be a simple process, set the property and then follow the link.
EDIT
Currently, have the code below, When I click the buttons nothing happens, it never enters the link_Click event, p.ID is what I am going to set the property to, I think I can get it from sender or e parameters somehow.
foreach (Person p in people)
{
DivDetail.Visible = true;
TableRow tRow = new TableRow();
Table2.Rows.Add(tRow);
TableCell tCell = new TableCell();
Button link = new Button();
link.Text = p.FullName;
link.ToolTip = p.ID;
link.UseSubmitBehavior = false;
link.Attributes.Add("OnClick", "link_Click");
tCell.Controls.Add(link);
tCell.Font.Bold = true;
tRow.Cells.Add(tCell);
//other cells of row populated
}
void link_Click(object sender, EventArgs e)
{
Response.Redirect("/Orig.aspx");
}
I think you are looking for a QueryString item. You can put a variable in the url that is being clicked and read that variable on the other page.
Lets say in page 1 you create the hyperlink with the url, and you want to send a variable called myVariable to the next page. You can add it to the link
HyperLink link = new HyperLink();
link.NavigateUrl = "/Page2.aspx?myVariable=" + myVariable;
link.Text = "My Link";
Now on Page 2 you can read that query string item again into a variable for use in code behind
if (Request.QueryString["myVariable"] != null)
{
string myVariable = Request.QueryString["myVariable"];
}
But you can also do a form post to another page, so all the form field items can be read on the other page. So you would add a LinkButton to page 1 and set it's PostBackUrl to page 2.
LinkButton linkbutton = new LinkButton();
linkbutton.PostBackUrl = "/Page2.aspx";
linkbutton.Text = "My LinkButton";
Now when the button is clicked you can get the posted items in code behind of page 2.
foreach (string key in Request.Form.Keys)
{
Response.Write(key + ": " + Request.Form[key] + "<br>");
}
A third option would be to do a normal PostBack on Page 1 and then set a Session and redirect to Page 2 and read the Session there.
LinkButton linkbutton = new LinkButton();
linkbutton.Click += Linkbutton_Click;
linkbutton.Text = "My LinkButton";
private void Linkbutton_Click(object sender, EventArgs e)
{
Session["myVariable"] = myVariable;
Response.Redirect("/Page2.aspx");
}
Assuming you need to set SomeProperty to someValue and then send the browser to someUrl, use a LinkButton and set its Click even handler up like this:
void MyLinkButton_Click(object sender, EventArgs e)
{
SomeProperty = someValue;
Response.Redirect(someUrl);
}
If the property value isn't available server-side, you can pass it in a hidden form variable:
void MyLinkButton_Click(object sender, EventArgs e)
{
SomeProperty = Request.Form["SomeField"];
Response.Redirect(someUrl);
}
Or, if it's a problem to set a form variable, you can set the value up using the OnCommand Method. Set it this way as you bind the table:
protected void Table_ItemDataBound(object sender, EventArgs e)
{
LinkButton lb = e.Item.FindControl("MyLinkID") as LinkButton;
lb.CommandArgument = someValue;
}
and read it this way:
void MyLinkButton_Click(object sender, EventArgs e)
{
SomeProperty = e.CommandArgument;
Response.Redirect(someUrl);
}
If you need to set a property on the destination page (which would make a little more sense) you'll have to temporarily store it in session...
void MyLinkButton_Click(object sender, EventArgs e)
{
Session["Temp"] = Request.Form["SomeField"];
Response.Redirect(someUrl);
}
...and then set it:
//This is the load event handler for the second page
public void Page_Load()
{
this.SomeProperty = Session["Temp"];
Session.Remove("Temp");
}
I working with ASP.NET WebForms with C#. I have a button when clicking on it creates a dropdownlist. This list is created in the "createlist" method with parameters such as id and items. I also add a SelectedIndexChanged event handler.
The list is created successfully, but when I switch between the 3 options the handler is not firing, because the console never prints the message "CHANGE".
Here's my code:
namespace web
{
public partial class Default : System.Web.UI.Page
{
List<string> lstDivs = new List<string>();
protected void btn_Click(object sender, EventArgs e)
{
Control results = FindControl("results");
lstDivs.Add("One");
lstDivs.Add("Two");
lstDivs.Add("Three");
DropDownList lstTipo = createList("lstTipos", lstDivs);
results.Controls.Add(lstTipo);
}
public DropDownList createList(string id, List<string> lstStr)
{
DropDownList lst = new DropDownList();
lst.Attributes.Add("runat", "server");
lst.ID = id + "" + Variables.numDiv;
lst.SelectedIndexChanged += new EventHandler(change);
lst.AutoPostBack = true;
lst.Items.Add(new ListItem("Select...", "Select..."));
for (int i = 0; i < lstStr.Count; i++)
{
lst.Items.Add(new ListItem(lstStr[i], lstStr[i]));
lst.Items[i].Attributes.Add("id", lst.ID + "" + i.ToString());
}
return lst;
}
protected void change(object sender, EventArgs e)
{
Debug.Write("CHANGE\r\n");
}
}
}
Once a dynamic control is created and displayed to the user, it has to be recreated on a postback for its events to fire. Execution of events is triggered by the control itself, hence, if there is no control - there is nobody to detect the change and call your change method.
You have to persist the fact that the dropdown has been created (hidden field, ViewState, Session, database, ...) and create it again in Page_Load.
I'm not sure your control exists on the postback since it is dynamically created. I found this post which might be helpful:
Dynamically Added DropDownlists Are Not Firing SelectedIndexChanged Event
Also, I don't think you need to add the runat as an attribute. This should be done automatically.
I have created few textbox dynamically while coding in the flow I have provided unique id for each and I have hard coded some values to all the text boxes using C#.
Now on click of button am trying to retrieve the values from the textbox for which I have used the below code, but its throwing an exception as OBJECT REFERENCE NOT SET TO INSTANCE OF AN OBJECT.
Please look at the below code, I have tried both the things but still am not getting. Please help me out.
Thanks
protected void btnPltGrap_onclick(object sender, EventArgs e)
{
//spny is my stack panel and txtX0 is my of the text box id
//Below is the 1st Try
TextBox tb = new TextBox();
tb= (TextBox)Master.FindControl("spnY").FindControl("txtX0");
string strx = tb.Text;
//Below is the 2nd Try
string strx = (spnY.FindControl("txtX0") as TextBox).Text;
}
Thanks
Am trying to use view state as per you told that i shlould recreate the controls ones again but am getting exception as Invalid Arguments. please go have a look.
protected void btnSet_onClick(object sender, EventArgs e)
{
Table tblMainY = new Table();
TableRow tblRow = new TableRow();
tblMainY.Controls.Add(tblRow);
TableCell tblCel = new TableCell();
TextBox txtdyn = new TextBox();
txtdyn.Text = "1";
txtdyn.ID = "txtY01";
txtdyn.Width = 50;
tblCel.Controls.Add(txtdyn);
tblRow.Controls.Add(tblCel);
splY.Controls.Add(tblMainY);
ViewState["temptbl"] = tblMainY
}
protected void btnPltGrap_onclick(object sender, EventArgs e)
{
splY.Controls.Add(ViewState["Temptbl"]);
}
Please help me out
I've had the same problem in the past.
What I did was give the dynamically-added control an ID, and made sure it retained that ID also on postback.
Once the postbacked control has the same ID as as before, Microsoft did magic and refilled the controls with the pre-postback values.
Read out this code once
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
this.NumberOfControls = 0; //very first time when page is loaded, value will be 0
else
this.createControls(); //if it is postback it will recreate the controls according to number of control has been created
}
//this is the base of this, it will hold the number of controls has been created, called properties
protected int NumberOfControls
{
get { return (int)ViewState["NumControls"]; }
set { ViewState["NumControls"] = value; }
}
//it will create the controls
protected void createControls()
{
int count = this.NumberOfControls;
for (int i = 0; i < count; i++) //loop for the total number of control.
{
TextBox tx = new TextBox(); //creating new control
tx.ID = "ControlID_" + i.ToString(); //in your solution you are giving static id, don't do that, assign id number dynamically, it will help you further, if you want to manipulate the controls for some other use
//Add the Controls to the container of your choice
form1.Controls.Add(tx);
}
}
//add new control
protected void addSomeControl()
{
TextBox tx = new TextBox();
tx.ID = "ControlID_" + NumberOfControls.ToString();
form1.Controls.Add(tx);
this.NumberOfControls++; //increment the number of control
}
protected void AddBtn_Click(object sender, EventArgs e)
{
addSomeControl();
}
Default.aspx
take placeholder tag in aspx file
< asp:PlaceHolder ID="PlaceHolder1" runat="server">
Default.aspx.cs
// adding/creating dynamic text box
TextBox txt = new TextBox();
txt.ID = "New_txt";
txt.TextMode = TextBoxMode.MultiLine;
txt.Text = dt.Rows[0]["message"].ToString();
txt.Width = 802;
txt.Height = 450;
txt.ReadOnly = true;
PlaceHolder1.Controls.Add(txt);
Retrive value from text box
string str = txt.Text;
some sample code in bellow link as my blog
Its explain for how to put and get textboxe's with values and validations in dynamicaly using panel control .
Let's go this url . and you can get good solutions
get and Create dynamic Textbox and dropdownlist with Validation
simple line for get textbox values in
TextBox objTextBox = (TextBox)PlaceHolder.FindControl("CorrecttextBoxName");
string value=objTextBox .Text;
You must recreate your controls on init to get it's value.
Here are some links
Get text from dynamically created textbox in asp.net
Edit 1
TextBox tb=(TextBox)ViewState["Temptbl"];
splY.Controls.Add(tb);
I am trying to create a UI that creates rows that can be dynamically populated.
I am at the point where I can add a Panel to my list that contains a DropDownList and has an associated Remove Button.
The Remove Button has an OnClick event bound that allows me to remove that specific panel.
I am having an issue when trying to bind a SelectedIndexChanged EventHandler to my DropDownList it does not.
I suspect this had something to do with how I am recreating my controls after every Postback.
I am not asking for or expecting a straightforward "Add this or Change this in the code." I really want to have a understand where I am going wrong, sorry for asking so much! :s
protected void Page_Load(object sender, EventArgs e)
{
//Showing this for the the poster that asked.
if (!IsPostBack)
{
GetClustersFromDB(user);
BindGrid();
BindState();
}
if (Session["persistControls"] != null)
{
persistControls = (List<Panel>)Session["persistControls"];
int count = 0;
foreach (Panel dynamicControl in persistControls)
{
DropDownList list = new DropDownList();
list.ID = "list" + count;
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
list.AutoPostBack = true;
list.Items.Add(new ListItem("", "0"));
list.Items.Add(new ListItem("Title", "1"));
dynamicControl.ID = "panel" + count;
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = count.ToString();
myPlaceholder.Controls.Add(dynamicControl);
myPlaceholder.Controls.Add(btnRemove);
count++;
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
try
{
DropDownList list = new DropDownList();
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
list.AutoPostBack = true;
list.Items.Add(new ListItem("", "0"));
list.Items.Add(new ListItem("Title", "1"));
Panel panelContainer = new Panel();
panelContainer.ID = "panel" + persistControls.Count;
panelContainer.Controls.Add(list);
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = persistControls.Count.ToString();
myPlaceholder.Controls.Add(panelContainer); // Pushes the Panel to the page.
persistControls.Add(panelContainer);// Adds our Panel to the Control list
myPlaceholder.Controls.Add(btnRemove); // Pushes our Button to the page.
Session["persistControls"] = persistControls; // put it in the session
}
catch
{
throw;
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
int deleteThisOne = int.Parse(((Button)sender).CommandArgument);
persistControls.Remove(persistControls[deleteThisOne]);
Session["persistControls"] = persistControls;
Response.Redirect(Request.Url.ToString());
}
catch
{
throw;
}
}
protected void list_SelectedIndexChanged(object sender, EventArgs e)
{
throw new NotImplementedException();
}
//aspx File Snippets
<asp:Button ID="btnAdd" runat="server" Text="Add Control" onclick="btnAdd_Click" />
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click"/>
<asp:PlaceHolder ID="myPlaceholder" runat="server"></asp:PlaceHolder>
Maintaining controls like this is a real pain. You could try an alternative approach:
Create a (small) class that encapsulates the data you want to display in each Panel.
Maintain a List of these objects in Session.
Use an <asp:Repeater> to display the items by data-binding it to your list.
In the repeater's ItemTemplate, you can write out your <asp:Panel> that can contain a <asp:DropDownList>. Use the ItemCommand property of the drop-down list to bind it to a server-side event handler. Similarly you can put an <asp:Button> in the template and bind the ItemCommand property of this to another server-side event handler.
When you click Add, you'll postback to the server, add to your list, save it in session, re-bind the repeater.
When you click a Remove, you'll postback to the server, remove the item from your list, save it in session, re-bind the repeater.
This way lets ASP.Net handle all the control creation for you. However, if you really want to do all that yourself, then this Infinities Loop blog post is required reading.
I don't think this will work. If you create the dropdownlists in the PageLoad event, the viewstate will never get bound to it, and you will never see the option selected by the user.
You should create the controls OnInit, then when the PostBack occurs the ViewState data will get bound to the control and you will be able to access it.
i have a alphabetic filter consist of 26 dynamically created link button on selecting any link button it is filtering the name of user's on the basis of alphabet and changing its color to orange to make it different from other linkbuttons it is working fine but if there are more number of user associated with a particular alphabet and on applying filter it is filtering the user on the basis of that alphabet and showing them in a list view on clicking the data pager next page or any other page number the link button changes its color to default color but i want to keep that highlighted until and unless other link button is selected
my code
protected void Page_Init(object sender, EventArgs e)
{
// Adding Dynamically linkbuttons for all alphabets(i.e. A-Z)
for (char asciiValue = 'A'; asciiValue <= 'Z'; asciiValue++)
{
LinkButton lbtnCharacter = new LinkButton();
lbtnCharacter.ID = "lbtnCharacter" + asciiValue;
divAlphabets.Controls.Add(lbtnCharacter);
// Setting the properties of dynamically created Linkbutton.
lbtnCharacter.Text = Convert.ToString(asciiValue);
lbtnCharacter.CssClass = "firstCharacter";
lbtnCharacter.ToolTip = "Show Tags starting with '" + Convert.ToString(asciiValue) + "'";
lbtnCharacter.CommandArgument = Convert.ToString(asciiValue);
lbtnCharacter.Command += new CommandEventHandler(lbtnCharacter_Command);
}
}
// For assigning default color to linkbutton text in page load
foreach (var ctrl in divAlphabets.Controls)
{
if (ctrl is LinkButton)
((LinkButton)ctrl).CssClass = "firstCharacter";
}
void lbtnCharacter_Command(object sender, CommandEventArgs e)
{
// Storing the values of pressed alphabet in viewstate.
ViewState["Selected_Character"] = e.CommandArgument;
LinkButton lbtnSelected = (LinkButton)divAlphabets.FindControl("lbtnCharacter" + e.CommandArgument);
lbtnSelected.CssClass = "firstCharacter highlighted";
txtTagFilter.Text = string.Empty;
BindTagList();
}
I hope I understood your question.
You are setting your Selected_Character item in the command handler and then setting the class of the button to highlight it. This only gets fired when the button is clicked, not when you move to the next page. Why not separate these two operations. Set the class of the link button on prerender if the Selected_Character matches. That way even when you page the link button will stay highlighted.
I would also set your selected character as a query string parameter, if someone copies and pastes a link to your page the button would not highlight and the correct data would not display.
Hope this helps.
Edit: Haven't tested the below but maybe it will get you started.
void lbtnCharacter_Command(object sender, CommandEventArgs e)
{
// redirect to self with tag as qs parameter
Response.Redirect(string.Format("{0}?tag={1}", Request.Url.GetLeftPart(UriPartial.Path), e.CommandArgument));
}
protected void Page_PreRender(object sender, EventArgs e)
{
if (Request.QueryString["tag"] != null) {
LinkButton lbtnSelected = (LinkButton)divAlphabets.FindControl("lbtnCharacter" + Request.QueryString["tag"]);
lbtnSelected.CssClass = "firstCharacter highlighted";
}
}
N.B You will also need to change your BindTagList to use the query string also. I'm assuming you call this in the page load event.