Creating dynamic button and its event handler - asp.net

I am trying to use dynamics buttons and events. When I clicked static button and I showed dynamic button. But When I clicked dynamic button I didn't work dinamikButon_Click event. What is my wrong? Sorry my language. Thx in advance.
Default.aspx.cs is below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestWebApplication
{
public partial class _Default : Page
{
int i = 1;
Button dinamikButon;
protected void Page_Load( object sender, EventArgs e )
{
}
protected void btnStatik_Click( object sender, EventArgs e )
{
dinamikButon = new Button
{
Text = "Dinamik" + i,
ID = "btnDinamik" + i,
CommandArgument = "commandArgument",
CommandName = "commandName"
};
dinamikButon.Click += dinamikButon_Click;
panel1.Controls.Add( dinamikButon );
i++;
}
void dinamikButon_Click( object sender, EventArgs e )
{
Label1.Text = "Merhaba dinamik butondan geliyorum.";
}
}
}

that's because when the page posts back the button doesn't exist. You have to create the buttons on page Load or PreInit. Microsoft suggests PreInit You can dynamically set a master page or a theme for the requested page, and create dynamic controls.
int i = 1;
Button dinamikButon;
private void Page_PreInit(object sender, EventArgs e)
{
if(Page.IsPostBack)
{
CreateButton();
}
}
protected void btnStatik_Click( object sender, EventArgs e )
{
CreateButton();
}
private void CreateButton()
{
dinamikButon = new Button
{
Text = "Dinamik" + i,
ID = "btnDinamik" + i,
CommandArgument = "commandArgument",
CommandName = "commandName"
};
dinamikButon.Click += dinamikButon_Click;
panel1.Controls.Add( dinamikButon );
i++;
}
Update:
Do do what you've asked now we have to specify that the button has been created using either viewstate, querystring or session.
In this example I'll use a session:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (Page.IsPostBack)
{
if (Session["Created"] != null)
{
CreateButton();
}
}
}
private void CreateButton()
{
dinamikButon = new Button
{
Text = "Dinamik" + i,
ID = "btnDinamik" + i,
CommandArgument = "commandArgument",
CommandName = "commandName"
};
Panel1.Controls.Add(dinamikButon);
dinamikButon.Click += dinamikButon_Click;
i++;
Session["Created"] = "true";
}
private void dinamikButon_Click(object sender, EventArgs e)
{
//your action here
}

To fill value in "Label1" control using dynamic button
Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DynamicCtrl._Default" %>
<!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></title>
<script type="text/javascript" language="javascript">
function dynamicevnt() {
document.getElementById("Label1").innerHTML = "Merhaba dinamik butondan geliyorum.";
return false;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnStatik" runat="server" Text="Click" OnClick="btnStatik_Click" />
<asp:Label ID="Label1" runat="server"></asp:Label>
<asp:Panel ID="panel1" runat="server">
</asp:Panel>
</div>
</form>
</body>
</html>
Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DynamicCtrl
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnStatik_Click(object sender, EventArgs e)
{
CreateButton();
}
private void CreateButton()
{
int i = 1;
Button dinamikButon = new Button();
dinamikButon.Text = "Dinamik" + i;
dinamikButon.ID = "btnDinamik" + i;
dinamikButon.OnClientClick = "return dynamicevnt();";
dinamikButon.Click += new EventHandler(dinamikButon_Click);
panel1.Controls.Add(dinamikButon);
i++;
}
protected void dinamikButon_Click(object sender, EventArgs e)
{
Label1.Text = "Merhaba dinamik butondan geliyorum.";
}
}
}

Related

Asp.net form links

How can I use a link in asp.net as a button. What's the right way to do this? For example with a label I'm doing it like this:
<a class="navbar-brand" href="#">Welkom<asp:Label ID="txtWelkom" runat="server" Text=""></asp:Label></a>
And then I set the label to a value that I received from the server for example:
txt.Welkom = name;
So how can I do this with a link (without seeing the button).
Is this the right way to do it (in asp.net forms)?
You want the LinkButton Control:
On .aspx side
<asp:LinkButton ID="lnkWelkom" runat="server" OnClick="lnkWelkom_OnClick" />
Code behind (aspx.cs)
using System;
using System.Web.Security.AntiXss;
using System.Web.UI;
namespace StackOverflowExamples.WebForms
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
var name = "";
lnkWelkom.Text = AntiXssEncoder.HtmlEncode(name, true);
}
protected void lnkWelkom_OnClick(object sender, EventArgs e)
{
//Do stuff
}
}
}

Viewstate and Tab container

I have the following code for a tab container and i am able to create a tab dynamically but as soon as i try to click to add another tab the previous tab disappears, i can't figure out how to keep viewstate, can someone please help me with this.
test5.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="test5.aspx.cs" Inherits="test5" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<cc1:tabcontainer id="TabContainer1" visible="true" runat="server" Height="150px">
<cc1:TabPanel ID="Tab0" runat="server" HeaderText="Step 1">
<ContentTemplate>
Test
<asp:Button ID="add" Text="Add" OnClick="add_Click" runat="server" />
</ContentTemplate>
</cc1:TabPanel>
</cc1:tabcontainer>
</div>
</form>
</body>
</html>
test5.aspx.cs
using AjaxControlToolkit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class test5 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void add_Click(object sender, EventArgs e)
{
int currentTab = TabContainer1.ActiveTabIndex;
int nextTab = currentTab + 1;
Button btn = new Button();
btn.ID = "Add" + nextTab.ToString();
btn.Text = "Add";
btn.Click += new EventHandler(add_Click);
TabPanel t = new TabPanel();
t.ID = "Tab" + nextTab;
t.HeaderText = "Tab:" + nextTab;
t.Controls.Add(btn);
TabContainer1.Tabs.Add(t);
}
}
Here's what I'd do:
Wrap the following code:
Button btn = new Button();
btn.ID = "Add" + nextTab.ToString();
btn.Text = "Add";
btn.Click += new EventHandler(add_Click);
TabPanel t = new TabPanel();
t.ID = "Tab" + nextTab;
t.HeaderText = "Tab:" + nextTab;
t.Controls.Add(btn);
TabContainer1.Tabs.Add(t);
Into its own method called RenderDynamicTabs(int nextTab)
At the end of add_Click, add this code:
if(null == ViewState["NumDynamicControls"])
{
ViewState["NumDynamicControls"] = 0;
}
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"]);
dynamicControlCount++;
In Page_Load, add the following:
if(null != ViewState["NumDynamicControls"])
{
// There are controls that need to be re-generated
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"]);
for(int i = 1; i <= dynamicControlCount; i++)
{
RenderDynamicTabs(i);
}
}
That should both store and re-render your controls after each PostBack.
Finally, to avoid duplication of code, in add_Click, replace the code you copy-pasted into RenderDynamicTabs with just a call to RenderDynamicTabs(nextTab);.
i removed the additions i added before, but here is what i got so far
using AjaxControlToolkit;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class test5 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (null != ViewState["NumDynamicControls"])
{
// There are controls that need to be re-generated
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"].ToString());
for (int i = 1; i <= dynamicControlCount; i++)
{
RenderDynamicTabs(i);
}
}
}
public void RenderDynamicTabs(int nextTab)
{
Button btn = new Button();
btn.ID = "Add" + nextTab.ToString();
btn.Text = "Add";
btn.Click += new EventHandler(add_Click);
TabPanel t = new TabPanel();
t.ID = "Tab" + nextTab;
t.HeaderText = "Tab:" + nextTab;
t.Controls.Add(btn);
TabContainer1.Tabs.Add(t);
}
protected void add_Click(object sender, EventArgs e)
{
int currentTab = TabContainer1.ActiveTabIndex;
int nextTab = currentTab + 1;
RenderDynamicTabs(nextTab);
if (null == ViewState["NumDynamicControls"])
{
ViewState["NumDynamicControls"] = 0;
}
var dynamicControlCount = int.Parse(ViewState["NumDynamicControls"].ToString());
dynamicControlCount = dynamicControlCount + 1;
}
}

SelectedIndexChanged not firing in ascx?

I use masterpage.In ascx page my selectedindexchange event not firing.
This is my code:
My ascx :
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="FilterList.ascx.cs"
Inherits="F8.B2B.WEB.UserControls.Common.FilterList.FilterList" %>
<asp:UpdatePanel UpdateMode="Always" runat="server">
<ContentTemplate>
<div id="filterList" runat="server">
</div>
</ContentTemplate>
</asp:UpdatePanel>
My ascx.cs:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
createFilterLists();
}
}
private void createFilterLists()
{
ListBox dpList = new ListBox()
{
ID = ControlID
};
dpList.Items.Clear();
if (lst_ListItem != null)
{
foreach (ListItem item_ in lst_ListItem)
{
dpList.Items.Add(item_);
}
dpList.Items[0].Selected = true;
dpList.AutoPostBack = true;
dpList.EnableViewState = true;
dpList.SelectedIndexChanged += new EventHandler(myListBox_SelectedIndexChanged);
filterList.Controls.Add(dpList);
}
}
protected void myListBox_SelectedIndexChanged(object sender, EventArgs e)
{
// might be entered on change
}
Because your list box is dynamically generated by code, you need to add it in every page load even if it is a postback.
Create dynamic controls and add event handlers in the OnInit event
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
CreateControls();
myDataGrid.SomeEventHandler += new ...
}
Bind data and fill controls in the OnLoad event
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
FillControls();
myDataGrid.DataSource = somedatasource;
myDataGrid.DataBind();
}
}
private void CreateControls()
{
ListBox dpList = new ListBox()
{
ID = ControlID
};
dpList.AutoPostBack = true;
dpList.EnableViewState = true;
dpList.SelectedIndexChanged += new EventHandler(myListBox_SelectedIndexChanged);
filterList.Controls.Add(dpList);
}
private void FillControls()
{
dpList.Items.Clear();
if (lst_ListItem != null && lst_ListItem.Count > 0)
{
foreach (ListItem item_ in lst_ListItem)
{
dpList.Items.Add(item_);
}
dpList.Items[0].Selected = true;
}
}

Why does GridView not render the header row as thead after postback?

Setting TableSection = TableRowSection.TableHeader after the grid is bound works initially, putting the header row in thead. After a postback (where the grid is not re-bound) the header row reverts to the table body. I expect the header row to stay in thead; can someone explain why this is not the case or what I am doing wrong?
Sample:
Click the button to cause a postback. The header is not orange after the postback since it's not in thead anymore.
aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="gridtest.aspx.cs" Inherits="ffff.gridtest" %>
<!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">
<style type="text/css">
thead th { background-color:Orange;}
</style>
</head>
<body>
<form id="form1" runat="server">
<div><asp:Button ID="Button1" runat="server" Text="Button" />
this button is here just to trigger a postback</div>
<asp:GridView ID="gv1" runat="server"></asp:GridView>
</form>
</body>
</html>
code
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace ffff
{
public partial class gridtest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
gv1.DataBound += new EventHandler(gv1_DataBound);
if (!IsPostBack) { BindGrid(); }
}
void Page_PreRender(object sender, EventArgs e)
{
if (gv1.HeaderRow != null)
System.Diagnostics.Debug.WriteLine(gv1.HeaderRow.TableSection); // still TableHeader after postback
}
void gv1_DataBound(object sender, EventArgs e)
{
if (gv1.HeaderRow != null)
{
gv1.HeaderRow.TableSection = TableRowSection.TableHeader;
}
}
private void BindGrid()
{
gv1.DataSource = this.Page.Controls;
gv1.DataBind();
}
}
}
Use the Pre_Render_Complete event instead to add the table section. This will ensure the thead section is always added. As you are currently doing it on DataBound the section will only be added when the data is bound.
protected override void OnPreRenderComplete(EventArgs e)
{
if (gv1.Rows.Count > 0)
{
gv1.HeaderRow.TableSection = TableRowSection.TableHeader;
}
}
Feel free to change the row check I use to checking the Header Row exists as you currently do.
You must set TableSection after DataBind method.
gv1.DataSource = this.Page.Controls;
gv1.DataBind();
gv1.HeaderRow.TableSection = TableRowSection.TableHeader;
Just put the below code in prerender event of gridview
protected void gv_PreRender(object sender, EventArgs e)
{
if (gv.Rows.Count > 0)
{
gv.UseAccessibleHeader = true;
gv.HeaderRow.TableSection = TableRowSection.TableHeader;
}
}

Updatepanel Repeater LinkButton OnClick Bind ListView

I get full postbacks - I have a linkbutton in a repeater and onclick I want to bind a listview.
Both are in the same updatepanel.
This is a usercontrol not an aspx page.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using umbraco.Linq.Core;
using System.Web.UI.HtmlControls;
using TechReady;
public partial class usercontrols_VideoGallery : System.Web.UI.UserControl
{
public TechReadyDataContextDataContext techDataContext;
protected void Page_Load(object sender, EventArgs e)
{
Bind_Tracks();
}
protected void Bind_Tracks()
{
techDataContext = new TechReadyDataContextDataContext();
var tracks = from t in techDataContext.Tracks
orderby t.Title
select t;
TracksListRepeater.DataSource = tracks;
TracksListRepeater.DataBind();
techDataContext.Dispose();
}
protected void Bind_VideoGallery(string tracktitle)
{
techDataContext = new TechReadyDataContextDataContext();
var sessions = (from s in techDataContext.Sessions
where s.SessionTrack == tracktitle
orderby s.SessionTrack
select s);
VidGalListView.DataSource = sessions;
VidGalListView.DataBind();
techDataContext.Dispose();
}
protected void TabLink_Click(Object sender, EventArgs e)
{
LinkButton lb = (LinkButton)sender;
RepeaterItem ri = (RepeaterItem)lb.NamingContainer;
HtmlGenericControl litostyle2 = (HtmlGenericControl)ri.FindControl("tablinkli");
litostyle2.Attributes.Add("Class", "ui-tabs-selected");
Bind_VideoGallery(lb.CommandArgument);
}
protected void TracksListRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
LinkButton lb = (LinkButton)e.Item.FindControl("tablink");
ScriptManager1.RegisterAsyncPostBackControl(lb);
}
}
protected void TracksListRepeater_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "TabClicked")
{
}
}
}
I recently came across this same issue: a linkbutton inside of a repeater inside of an update panel. I found two solutions for performing an asynchronous post back when then linkbutton is clicked.
1. Add the following attribute to the page directive containing the repeater & linkbutton:
<%# page ClientIDMode="AutoID" %>
2. Use the ScriptManager on the databind event for the repeater:
LinkButton linkButton = e.Item.FindControl("button") as LinkButton;
ScriptManager.RegisterAsyncPostBackControl(linkButton)
I had 2 scriptmanagers running - one on a master page...

Resources