In my sharepoint web-part application. I am dynamically generating LinkButtons as below. and this works fine
foreach (var pName in productTypesNames[productType] )
{
var subLi = new HtmlGenericControl("li");
var linkButton = new LinkButton{ Text = pName };
linkButton.Click += new EventHandler(linkButton_Click);
subLi.Controls.Add(linkButton);
ul.Controls.Add(subLi);
}
However, when I click on one of the links in UI, my debugger never hits the breakpoint that is set at very first line of
void linkButton_Click(object sender, EventArgs e)
{
}
More Code
protected void StateClicked(object sender, CommandEventArgs e)
{
//Generate a dictionary of type Dictionary<string, List<string>>
//Display the dictionary
foreach (var productType in productTypesNames.Keys)
{
var li = new HtmlGenericControl("li");
nav.Controls.Add(li);
var ul = new HtmlGenericControl("ul");
var anchor = new HtmlGenericControl("a");
anchor.Attributes.Add("href", "#");
foreach (var pName in productTypesNames[productType] )
{
var subLi = new HtmlGenericControl("li");
var linkButton = new LinkButton{ Text = pName };
linkButton.Click += new EventHandler(linkButton_Click);
subLi.Controls.Add(linkButton);
ul.Controls.Add(subLi);
}
anchor.InnerHtml = productType;
li.Controls.Add(anchor);
li.Controls.Add(ul);
}
}
Where stateClicked is called by a click on the image map of USA.
You probably aren't recreating the dynamically generated links on every postback.
If you have a if (!IsPostback) wrapped around your foreach, try removing it.
i had the same problem here ....
i was creating an HtmlTable after firing an event...
this table has (n) HtmlTableRows (calculated in the event handler)
now each row contains 2 LinkButtons that are generated from the code behind .. after an event is handled...
and each LinkButton is assigned a new event handler:
lnkbtnEdit.CommandArgument = b.BookID.ToString();
lnkbtnEdit.Click += new EventHandler(lnkbtnEdit_Click);
where lnkbtnEdit_Click signature is as follows:
protected void lnkbtnEdit_Click(object sender, EventArgs e)
the weird thing is that .. there is a postback when i click the generated LinkButton... but the event was not firing...
i don't know exactly what the problem was ... but i found the solution: ..
it appears as if these generated controls disappear on the postback (tried to assign an id and used Page.FindControl() witch returned with null !!)
so i had to re-link the buttons.... on the Page_Load i re-generated the LinkButtons, with same ID... and linked them to their respective EventHandlers
Related
I have a dynamic data that has to be populated on UI from .cs file.
Currently I am doing it this way:
File.aspx
<div id="divLinks" class="w3-content w3-display-container" style="max-width:100%;" runat="server">
</div>
File.aspx.cs
StringBuilder str = new StringBuilder();
str.Append("<a target=\"_blank\"><img class=\"mySlides\" src=\"" + imageLink + "\" style=\"width:100%; height:350px;\" runat=\"server\" onServerClick=\"MyFuncion_Click("+link+")\" ></a>");
divLinks.InnerHtml = str.ToString();
protected void LinkButton_Click(object sender, EventArgs e)
{
//Do something when clicked a link with parameter from that link as identifier
}
After doing this, I am not able to reach LinkButton_Click function from onServerClick.
Can someone help me with this siince I want a link with unique value to be passed to function for further processing.
You are trying to add aspnet Controls to the page as a string. That is not gonna Work. You need to add "real" Controls to the page.
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
//do not add dynamic controls here
}
//create a new ImageButton instance on every page load
ImageButton ib = new ImageButton();
//set some properties
ib.CssClass = "mySlides";
ib.ImageUrl = "~/myImage.png";
//add the click method
ib.Click += LinkButton_Click;
//add the button to an existing control
PlaceHolder1.Controls.Add(ib);
}
Note that you need to add dynamic controls on every Page Load, and that includes a PostBack.
Ok so I've been working on this for like... I don't know, 5 hours? I'm pulling my hair out starting to think it's just not possible with asp.net! ugh! I've looked at all kinds of resources (I even tried implementing DynamicControlsPlaceholder that was created by someone else years ago - which failed miserably). So here's the issue in hopes someone here has a solution!
I'm trying to have a page where the user can dynamically add DropDownLists without forgetting the values they set in the previous lists. So for example, let's say the user is given 1 DropDownList and chooses index 2. There will be a button below that says "Add" and that will add another DropDownList. When doing this, however, the page does a postback and the previous DropDownList loses the value of index 2 and resets back to index 0 instead. I can't figure out how to save the state of the DropDownList before the postback is made. The point of this is so that when the user is complete, they can click "Submit" with all the values made in the DropDownLists. Here's the code I currently have (that's important) which simply regenerates the same number of DropDownLists as there's supposed to be (based on the ViewState["layoutCount"]). Naturally, I should be able to "restore" the index that was selected before a reload of the page...
aspx file:
<table style="text-align:center; width:60%;">
<asp:Panel ID="layoutAreaPanel" runat="server" CssClass="paragraphStyle" />
</table>
<asp:Button ID="cmdLayout1AddPage" runat="server" OnClick="cmdLayout1AddPage_Click" />
C#:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
CreatePanelInfo();
}
....
protected void CreatePanelInfo()
{
int layoutCount = 0;
if (ViewState["layoutCount"] != null)
layoutCount = (int)(ViewState["layoutCount"]);
for (int i = 0; i < layoutCount; i++)
{
TableRow mainRow = new TableRow();
TableCell labelCell = new TableCell();
TableCell dropDownListCell = new TableCell();
Label cellLabel = new Label();
cellLabel.Text = Language.GetLanguageText("ADDPAGE_PAGE", this.Page);
cellLabel.CssClass = "paragraphStyle";
labelCell.HorizontalAlign = HorizontalAlign.Right;
labelCell.Controls.Add(cellLabel);
DropDownList pnlDropDownList = new DropDownList();
pnlDropDownList.ID = "pnlDropDownList" + (i + 1);
pnlDropDownList.BorderWidth = 1;
pnlDropDownList.Width = new Unit("100%");
FillPageList(ref pnlDropDownList); //adds items to the list
dropDownListCell.Controls.Add(pnlDropDownList);
mainRow.Controls.Add(labelCell);
mainRow.Controls.Add(dropDownListCell);
layoutAreaPanel.Controls.Add(mainRow);
}
ViewState["layoutCount"] = layoutCount + 1;
}
....
protected void cmdLayout1AddPage_Click(object sender, EventArgs e)
{
CreatePanelInfo();
}
Hopefully that's enough information to get a good answer... :S
Only make your dropdown lists making a postback when their selected index changes.
In the code behind, store selections in Session variable.
public void AddDDL()
{
var tmp = new DropDownList();
tmp.SelectedIndexChanged += ddl_SelectedIndexChanged;
Page.Controls.Add(tmp);
}
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
{
var ddl = sender as DropDownList;
var lists = Session["dropdownlists"] as Dictionary<DropDownList, int>;
lists[ddl] = ddl.SelectedIndex;
}
and finally in postback event set the selected indices again:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostback)
{
var lists = Session["dropdownlists"] as Dictionary<DropDownList, int>;
foreach (var item in lists)
item.Key.SelectedIndex = item.Value;
}
else Session["dropdownlists"] = new Dictionary<DropDownList, int>();
}
Postback is not recommended because it is not user friendly. You should use an UpdatePanel.
I am retrieving data from table column where I have saved tags for the article, for example: "animals dogs cats" and showing this string text in linkbutton. If I click it, then page is redirected to "Tags.aspx?name=animals dogs cats".
Is it possible to redirect page to "Tags.aspx?name=cats"
if I have clicked on "cats", or maybe to split the string and show each word in own linkbutton (without using something like listview)?
Thanks, Oak
If you don't want to use a web-databound control like Repeater you can create the LinkButtons dynamically. Remember to recreate them on postbacks with the same ID as before in Page_Load at the latest:
protected void Page_Init(object sender, EventArgs e)
{
createTagButtons();
}
private void createTagButtons()
{
var tblTags = new DataTable();
using (var con = new SqlConnection(connectionString))
using (var da = new SqlDataAdapter("SELECT TagID, TagName FROM dbo.Tags ORDER BY TagName", con))
{
da.Fill(tblTags);
}
foreach (DataRow row in tblTags.Rows)
{
int tagID = row.Field<int>("TagID");
string tagName = row.Field<string>("TagName");
LinkButton tagButton = new LinkButton();
tagButton.ID = "tagButton_" + tagID;
tagButton.CommandArgument = tagName;
tagButton.Click += TagLinkClicked;
this.TagPanel.Controls.Add(tagButton);
}
}
private void TagLinkClicked(Object sender, EventArgs e)
{
LinkButton tagLink = (LinkButton)sender;
string url = string.Format("Tags.aspx?name={0}", tagLink.CommandArgument);
Response.Redirect(url);
}
On the aspx you could use a Panel:
<asp:Panel ID="TagPanel" runat="server"></asp:Panel>
You can use string[] words = your_string.Split(); and then create buttons using loop
A link will show only one view called from the controller.
That is, if you have a tag "cat" and this tag is related with some view then this tag calls that view which is written in the controller.
I create some dynamic textbox's and a button in a placeholder and would like to save info in textbox's when button is clicked but not sure how to retrieve data from the textbox
LiteralControl spacediv3 = new LiteralControl("  ");
Label lblComText = new Label();
lblComTitle.Text = "Comment";
TextBox txtComment = new TextBox();
txtComment.Width = 200;
txtComment.TextMode = TextBoxMode.MultiLine;
phBlog.Controls.Add(lblComText);
phBlog.Controls.Add(spacediv3);
phBlog.Controls.Add(txtComment);
Button btnCommentSave = new Button();
btnCommentSave.ID = "mySavebtnComments" ;
btnCommentSave.Text = "Save ";
phBlog.Controls.Add(btnCommentSave);
btnCommentSave.CommandArgument = row["ID"].ToString();
btnCommentSave.Command += new CommandEventHandler(btnSave_Click);
protected void btnSave_Click(object sender, CommandEventArgs e)
{
firstelement.InnerText = txtComment.text // this gives error on txtComment.text
}
You need to get a reference to your control in btnSave_Click. Something like:
protected void btnSave_Click(object sender, CommandEventArgs e)
{
var btn = (Button)sender;
var container = btn.NamingContainer;
var txtBox = (TextBox)container.FindControl("txtComment");
firstelement.InnerText = txtBox.text // this gives error on txtComment.text
}
You also need to set the ID on txtComment and recreate any dynamically created controls at postback.
You will need some mechanism to create a relation between the Button and the TextBox obviously. In winforms this would be easy, where each control has a Tag property, which can contain a reference to pretty much anything. The web controls don't have such a property (that I know of), but it is still easy to maintain such relations. One approach would be to have Dictionary in the page storing button/textbox relations:
private Dictionary<Button, TextBox> _buttonTextBoxRelations = new Dictionary<Button, TextBox>();
When you create the button and textbox controls, you insert them in the dictionary:
TextBox txtComment = new TextBox();
// ...
Button btnCommentSave = new Button();
// ...
_buttonTextBoxRelations.Add(btnCommentSave, txtComment);
...and then you can look up the text box in the button's click event:
protected void btnSave_Click(object sender, CommandEventArgs e)
{
TextBox commentTextBox = _buttonTextBoxRelations[(Button)sender];
firstelement.InnerText = txtComment.text // this gives error on txtComment.text
}
Try during postback to load txtComment (with the same ID) in overridden LoadViewState method after calling base.LoadViewState. In this case you do load it before postback data are handled and txtComment control comes loaded.
Add an 'ID' to the textbox
txtComment.ID = "txtComment"
Request the information from the submitted form (provided you have a form on the page)
comment = Request.Form("txtComment")
I have a search button on my page that runs a query on a DB, pulls out and displays some entries in a table, and for each entry I create a button. It looks something like this:
List<Friend> friends = SearchFriend(searchStr);
foreach (Friend f in friends)
{
TableCell addCell = new TableCell(), nameCell = new TableCell();
addCell.Text = "";
if (!f.IsMyFriend)
{
LinkButton addFriendBtn = new LinkButton();
addFriendBtn.Text = "Add as Friend";
addFriendBtn.Click += new EventHandler(addFriendBtn_Click);
addFriendBtn.ID = "add_" + f.ID.ToString();
addCell.Controls.Add(addFriendBtn);
}
nameCell.Text = f.Name;
TableRow row = new TableRow();
row.Cells.Add(addCell);
row.Cells.Add(nameCell);
SearchFriendTable.Rows.Add(row);
}
Problem is that the LinkButton event does not fire when it is pressed (changing LinkButton to a simple Button does not fix this either).
This is the html that I get in this portion:
<td><a id="ctl00_contentPH_add_2" href="javascript:__doPostBack('ctl00$contentPH$add_2','')">Add as Friend</a></td>
Also - when I put a breakpoint on Page_Load I do see the __EVENTTARGET with this control's id in it - however the event never starts running.
Any clues?
Thanks.
Adding to Himadri's answer:
Dynamically added controls need to be rewired in page init. Then the event will fire. I had a very similar issue Dynamically loaded Controls in a wizard
Where and when did you created that button?
If you dynamically create Buttons and want to listen to a event you have to create that button in the PageInit event. Always! So do not use if(!IsPostback)
Try with this.
<td><a id="ctl00_contentPH_add_2" href="javascript:__doPostBack('<%=ct100_contentPH_add_2.ClientId %>','')">Add as Friend</a></td>
Add event handler for the link buttons and handle those events.
if (!f.IsMyFriend)
{
LinkButton addFriendBtn = new LinkButton();
addFriendBtn.Text = "Add as Friend";
addFriendBtn.Click += new EventHandler(addFriendBtn_Click);
addFriendBtn.ID = "add_" + f.ID.ToString();
addFriendBtn.Click += new EventHandler(addFriendBtn_Click);
addCell.Controls.Add(addFriendBtn);
}
the event:
protected void addFriendBtn_Click(object sender, EventArgs e)
{
LinkButton lnk = (LinkButton)sender;
// do your coding
}