Dynamically create a ASP.net Submit LinkButton using a Panel - c#

I am trying to implement an application which will dynamically create a list with a button next to each item on that list. I am partially able to do this using the Panel control in the aspx page and adding html dynamically in the code behind. I am having problems adding the LinkButton dynamically which will do database work based on which ID it is. Is this even possible with what I have?:
aspx:
<asp:Panel ID="ItemPanel" runat="server">
</asp:Panel>
code behind:
...
StringBuilder sb = new StringBuilder();
string UserID;
while (dr.Read())
{
UserID = Convert.ToInt32(dr["UserID"]);
sb.Append("<div><b class='template'></b>");
//Create LinkButton with event and code behind function
}
ItemPanel.Controls.Add(new LiteralControl(sb.ToString()));

You may want to take a look at this very recent question and if you have additional queries, then edit your question.
Edit (after OP's comment)
The purpose of posting that link was to give you an idea how to create the control dynamically. Since you ask, here's a simple bare-bones ASPX page that creates a LinkButton and attaches an eventhandler for the Click event. Not sure what you mean by "handle changes on the server", though.
<%# Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
LinkButton lnk1 = new LinkButton();
lnk1.Text = "Click me!";
//lnk1.PostBackUrl = "SomeOtherPage.aspx";
// Use the eventhandler to perform redirection,
// instead of the PostBackUrl to show it works.
lnk1.Click += new EventHandler(lnk1_Click);
// Add control to container:
pnl1.Controls.Add(lnk1);
}
void lnk1_Click(object sender, EventArgs e)
{
Response.Redirect("SomeOtherPage.aspx");
}
</script>
<html>
<head>
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:Panel ID="pnl1" runat="server">
</asp:Panel>
</form>
</body>
</html>

Related

ASPX Postback selectedIndexChanged

I am using an combobox with some values and AutoPostBack = true, the page does not refresh.
I have a selectedIndexChanged event as well.
I managed to get the selectedValue and I would like to show this in a TextBox.
In the selectedIndexChanged event I did:
textBox1.Text = selectedValue.ToString();
When I inspect this textbox element with Google Chrome I can see the value is set in the TextBox.
But in the browser the value isn't shown, still an empty TextBox.
Do you guys have any clue why this could happen?
Thanks!
How do you populate items for ComboBox? If dynamically via On-Load event then make sure that method that adds items does not run on PostBack.
Here is your working code buddy.
Don't forget ToString method.
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Test2.aspx.cs" Inherits="Test2" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server"></asp:ToolkitScriptManager>
<asp:ComboBox ID="ComboBox1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ComboBox1_SelectedIndexChanged">
<asp:ListItem>Item1</asp:ListItem>
<asp:ListItem>Item2</asp:ListItem>
<asp:ListItem>Item3</asp:ListItem>
</asp:ComboBox>
<asp:TextBox runat="server" ID="textBox1"/>
</div>
</form>
</body>
</html>
and code
public partial class Test2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBox1.Text = ComboBox1.SelectedValue.ToString();
}
}

Client script in Timer is not working

I was just trying to learn some Asp.net Ajax stuff and calling javascript from my C# script.
I have a timer that triggers a method that calls a super simple javascript alert function.
It also updates the time every 10 seconds. Now it looks like my code should work. There are no build errors, no exceptions just it doesn't work. The C# part that updates the time. The javascript does not make the alert.
<%# Page Language="C#" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
<script runat="server">
protected void Page_load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Label1.Text = DateTime.Now.ToString();
}
}
protected void Timer1_Tick(object sender, EventArgs e)
{
const string someScript = "alertMe";
Label1.Text = DateTime.Now.ToString();
ClientScript.RegisterStartupScript(this.GetType(),someScript, "alert('I was called from Content page!')", true);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server"> </asp:ScriptManager>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Label runat="server" ID="Label1"></asp:Label>
<asp:Timer ID="Timer1" runat="server" Interval="10000" OnTick ="Timer1_Tick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
You need to use ScriptManager instead of ClientScript when you are putting the element that triggers the postback inside an UpdatePanel.
Change your code to:
ScriptManager.RegisterStartupScript(this,this.GetType(), someScript, #"alert('I was called from Content page!');", true);
You forgot a ;
ClientScript.RegisterStartupScript(this.GetType(),someScript, "alert('I was called from Content page!');", true);
Most browsers have an error console of some type that you can see these issues as they occur.

How to get the ID of button contained in parent page from User Control?

I have a user control contained within a page that has a button.
I want to use FindControl() to see if the button exists in the parent page, but the button doesn't have an ID.
I have tried the following code:
Page.Master.FindControl("ButtonName/Text on button here?")
Is there any way I can do this?
I want to use FindControl() to see if the button exists in the parent
page, but the button doesn't have an ID.
You won't be able to find it using FindControl since this requires that the element has an ID and that this button is a server control (ie runat="server" is set in the markup)
The only thing you can do in a scenario like this is to use client-side scripting to find the element, using plain javascript or jQuery.
If it's created dynamically? How do you find out what the ID is?
If the button was created dynamically then YOU should manually assign it an ID.
Example:
protected void Page_Load(object sender, EventArgs e)
{
Button btnFound = (Button)this.FindControl("myButton");
if (btnFound != null)
{
Response.Write("Found It!");
}
}
protected void Page_Init(object sender, EventArgs e)
{
Button btn = new Button()
{
ID = "myButton",
Text = "Click Me"
};
this.Controls.Add(btn);
}
Good luck!
Assuming that you're talking about an asp:Button, you could do a recursive find if you wanted to search by the text.
Master Page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title></title>
</head>
<body>
<form runat="server">
<div>
<asp:Button runat="server" ID="btnTest" Text="Test Button" />
<asp:ContentPlaceHolder ID="MainContent" runat="server"/>
</form>
</body>
</html>
And a snipet of code to do a recursive find
protected List<Control> FindButton(ControlCollection controls, string buttonText)
{
List<Control> foundControls = (from c in controls.Cast<Control>() where c is Button && ((Button)c).Text == "Test Button" select c).ToList();
if (foundControls.Count > 0)
return foundControls;
else
{
foreach (Control ctrl in controls)
{
if (foundControls.Count == 0)
foundControls = FindButton(ctrl.Controls, buttonText);
if (foundControls.Count > 0)
break;
}
return foundControls;
}
}
And then use:
List<Control> buttons = FindButton(Page.Master.Controls, "Test Button");
if (buttons.Count > 0)
{
((Button)buttons[0]).Text = "I found it";
}
This code could be modified in several ways, like instead of stopping after find any buttons, continue the loop finding ALL buttons. It could also be changed to find only a single button and return it instead of a List of controls. You could also modify your query to find controls of a different type.

Ext.Net Button Event not firing

I am using Ext.Net and I have a problem.
I am creating dynamic buttons. It is working but if i click, the button event is not working.:(
How can I fix it?
My code:
foreach (var events in eventsInformation)
{
Ext.Net.Button btn = new Ext.Net.Button();
btn.ID = events.EvtId.ToString();
btn.Text = events.EvtName;
btn.Click += new EventHandler(Tickets_click);
ViewPort1.Controls.Add(btn);
}
There are a couple things that require correction in the original sample:
By default, Ext.NET Button Components do not AutoPostBack (ie, reload the entire page). It is encouraged to use DirectEvents (Ajax call) if you want to communicate with the server and avoid a complete page reload.
Ext.NET Components should be added to the parent .Items Collection, instead of the .Controls Collection.
Here's a complete demo with both these corrections.
Example
<%# Page Language="C#" %>
<%# Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>
<script runat="server">
protected override void OnInit(EventArgs e)
{
Ext.Net.Button btn = new Ext.Net.Button();
btn.Text = "Submit (AutoPostBack)";
btn.Click += Button1_Click;
// 1. Set to AutoPostBack, default is "false"
btn.AutoPostBack = true;
// 2. Add Button to .Items Collection
this.ViewPort1.Items.Add(btn);
base.OnInit(e);
}
protected void Button1_Click(object sender, EventArgs e)
{
X.Msg.Notify("Server Time", DateTime.Now.ToLongTimeString()).Show();
}
</script>
<!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>Ext.NET Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />
<ext:Viewport ID="ViewPort1" runat="server" />
</form>
</body>
</html>
Now, I'd recommend changing your AutoPostBack Button Click event to a DirectEvent Click. That would require making the following three revisions to the code-behind.
Example
<script runat="server">
protected override void OnInit(EventArgs e)
{
Ext.Net.Button btn = new Ext.Net.Button();
btn.Text = "Submit (DirectEvent)";
// 2. CHANGE to .DirectClick
btn.DirectClick += Button1_Click;
// 3. REMOVE btn.AutoPostBack = true;
this.ViewPort1.Items.Add(btn);
base.OnInit(e);
}
// 3. CHANGE "EventArgs" to "DirectEventArgs"
protected void Button1_Click(object sender, DirectEventArgs e)
{
X.Msg.Notify("Server Time", DateTime.Now.ToLongTimeString()).Show();
}
</script>
Hope this helps.
Use Ext.net DirectMethod instead of ASP.NET postback event handler.
<ext:Button ID="Button1" runat="server" Text="Click Me" Icon="Lightning">
<Listeners>
<Click Handler="Ext.net.DirectMethods.SetTimeStamp();" />
</Listeners>
</ext:Button>
<script runat="server">
[DirectMethod]
public void SetTimeStamp()
{
this.Label1.Text = string.Concat("Server Time: ", DateTime.Now.ToLongTimeString());
}
The place to start is the ASP.NET Page Life Cycle Overview. If you're programatically adding controls to an asp.net page then you should familiarise yourself with it, if you're not already =)
Now work your way down this checklist:
Are you always adding the components (buttons in this instance) to the page? If you don't add them *always, then on post-back they won't be there for the EventHandler to be wired up to, for the handler to fire. (This may not apply to an Ext.Net button triggered by a DirectEvent, but it can't hurt).
Do you have the "usual" Ext.Net handler/module registrations in your web.config file to enable the direct events to be handled?
Have you verified that you're not receiving any javascript client-side errors that are inhibiting the event handler?
Use something like Fiddler to verify that the event is actually triggering a DirectEvent back to the server.
<ext:Button ID="extBtn1" runat="server" Text="Cancel">
<DirectEvents>
<Click OnEvent="extBtn1Click">
<EventMask ShowMask="true" />
</Click>
</DirectEvents>
</ext:Button>
This extBtn1Click event will fire in server-side.
The button is not present when Event is fired. That is why it doesnt work. If you construct some testing button in aspx file, it would work just fine.
Solution: You must construct the button during OnInit event so it will be present, and bound to EventHandler, during the new page cycle after clicking the button.

Programmatically Adding User Controls Inside An UpdatePanel

I'm having trouble dynamically adding controls inside an update panel with partial postbacks. I've read many articles on dynamic controls and I understand how to add and maintain them with postbacks but most of that information doesn't apply and won't work for partial postbacks. I can't find any useful information about adding and maintaining them with UpdatePanels. I'd like to do this without creating a web service if it's possible. Does anyone have any ideas or references to some helpful information?
This is, I think, one of the common pitfalls for asp.net programmers but isn't actually that hard to get it right when you know what is going on (always remember your viewstate!).
the following piece of code explains how things can be done. It's a simple page where a user can click on a menu which will trigger an action that will add a user control to the page inside the updatepanel.
(This code is borrowed from here, and has lots more of information concerning this topic)
<%# Page Language="C#" AutoEventWireup="true" CodeFile="SampleMenu1.aspx.cs" Inherits="SampleMenuPage1" %>
<!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>Sample Menu</title>
</head>
<body>
<form id="form1" runat="server">
<asp:Menu ID="Menu1" runat="server" OnMenuItemClick="Menu1_MenuItemClick">
<Items>
<asp:MenuItem Text="File">
<asp:MenuItem Text="Load Control1"></asp:MenuItem>
<asp:MenuItem Text="Load Control2"></asp:MenuItem>
<asp:MenuItem Text="Load Control3"></asp:MenuItem>
</asp:MenuItem>
</Items>
</asp:Menu>
<br />
<br />
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Menu1" />
</Triggers>
</asp:UpdatePanel>
</form>
</body>
</html>
and
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class PlainSampleMenuPage : System.Web.UI.Page
{
private const string BASE_PATH = "~/DynamicControlLoading/";
private string LastLoadedControl
{
get
{
return ViewState["LastLoaded"] as string;
}
set
{
ViewState["LastLoaded"] = value;
}
}
private void LoadUserControl()
{
string controlPath = LastLoadedControl;
if (!string.IsNullOrEmpty(controlPath))
{
PlaceHolder1.Controls.Clear();
UserControl uc = (UserControl)LoadControl(controlPath);
PlaceHolder1.Controls.Add(uc);
}
}
protected void Page_Load(object sender, EventArgs e)
{
LoadUserControl();
}
protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)
{
MenuItem menu = e.Item;
string controlPath = string.Empty;
switch (menu.Text)
{
case "Load Control2":
controlPath = BASE_PATH + "SampleControl2.ascx";
break;
case "Load Control3":
controlPath = BASE_PATH + "SampleControl3.ascx";
break;
default:
controlPath = BASE_PATH + "SampleControl1.ascx";
break;
}
LastLoadedControl = controlPath;
LoadUserControl();
}
}
for the code behind.
That's basically it. You can clearly see that the viewstate is being kept with LastLoadedControl while the controls themselves are dynamically added to the page (inside the updatePanel (actually inside the placeHolder inside the updatePanel) when the user clicks on a menu item, which will send an asynchronous postback to the server.
More information can also be found here:
http://aspnet.4guysfromrolla.com/articles/081402-1.aspx
http://aspnet.4guysfromrolla.com/articles/082102-1.aspx
and of course on the website that holds the example code I used here.
I encountered the problem that using the method mentioned above, LoadUserControl() is called twice when handling an event. I've read through some other articles and would like to show you my modification:
1) Use LoadViewstate instead of Page_Load to load the user control:
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (!string.IsNullOrEmpty(CurrentUserControl))
LoadDataTypeEditorControl(CurrentUserControl, panelFVE);
}
2) Don't forget to set the control id when loading the usercontrol:
private void LoadDataTypeEditorControl(string userControlName, Control containerControl)
{
using (UserControl myControl = (UserControl) LoadControl(userControlName))
{
containerControl.Controls.Clear();
string userControlID = userControlName.Split('.')[0];
myControl.ID = userControlID.Replace("/", "").Replace("~", "");
containerControl.Controls.Add(myControl);
}
this.CurrentUserControl = userControlName;
}
Try this:
Literal literal = new Literal();
literal.Text = "<script type='text/javascript' src='http://www.googleadservices.com/pagead/conversion.js'>";
UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
You can replace the content of literal with any HTML content you want...

Categories