Can't access GridView event at usercontrol by codebehind - c#

IpInterfaceUC UserControl
<div id="dvChannel" runat="server">
<asp:GridView ID="gvChannelUC"
OnRowCommand="gvChannelUC_RowCommand"
OnSelectedIndexChanged="gvChannel_SelectedIndexChanged"
/>
</div>
IPServices page CodeBehind
if (!IsPostBack){
}else
{
string str_btn = Request.Form.Keys[Request.Form.Keys.Count - 1].ToString();
handleClick(str_btn);
}
Question
It always show str_btn is null.If I click Button,It'll show button's id.But when I click Select at GridView,It show str_btn is null.It should be show GridView's id when we click select.
Thanks for any explain.

Try giving name attribute to your gridview,ie name="yourGridName".
<div id="dvChannel" runat="server" name="yourGridName">
<asp:GridView ID="gvChannelUC" name="yourGridName"
OnRowCommand="gvChannelUC_RowCommand"
OnSelectedIndexChanged="gvChannel_SelectedIndexChanged"
/>
</div>

As per my understanding you need grid event handing (.ascx) on page/codebehind (.aspx).
declare eventhandler in userControl
public event EventHandler<EventArgs> RaiseSelectedIndexChanged=delegate {};
handle userControl selectedindexchanged event in userControl.cs
protected void gvChannel_SelectedIndexChanged(object sender, EventArgs e)
{
var raiseSelectedIndexChanged = RaiseSelectedIndexChanged ;
if(raiseSelectedIndexChanged!=null)
{
raiseSelectedIndexChanged(sender, e);
}
}
register and use your userControl in aspx (which I hope you already did) this code will go in aspx page
<uc:userControl OnRaiseSelectedIndexChanged="OnRaiseSelectedIndexChanged"/>
handle the event in aspx code behind
protected void OnRaiseSelectedIndexChanged(object sender, EventArgs e)
{
//handle your event and put logic
}
I hope i make it clear , let me know if it confuses you.

Related

Which link is clicked in asp.net gridview row

I am adding two links and some plain text in same cell of gridview, I also have gridview_SelectedIndexChanged function which is called when any of the link is clicked and based of the value from grid I am running my db queries. gridview is also created dynamically so can have different number of rows.
Is there a way to know Link1 or Link2 is clicked in gridview_SelectedIndexChanged function?
protected void gridview_SelectedIndexChanged(object sender, EventArgs e)
{
if (Link1.Clicked)
{do this}
elseif (Link2.Clicked)
{do this}
}
You would want to track which link is clicked by using an ASP.NET control
<asp:LinkButton ID="Link1" runat="server" Click="Link1_Click" />
in your html
Then add an event handler in your backend like
public void Link1_Click(object sender, EventArgs e)
{
//add variable marking this link was clicked
link1_clicked = true;
Response.Redirect("Link1Destination.aspx");
}
and do the same for link2
<asp:LinkButton ID="Link2" runat="server" Click="Link2_Click" />
public void Link2_Click(object sender, EventArgs e)
{
//add variable marking this link was clicked
link2_clicked = true;
Response.Redirect("Link2Destination.aspx");
}
Add the boolean variables link1_clicked and link2_clicked to the top of you backend code. Then when you need to check what has been clicked you can filter though your boolean variables to see what is marked true as clicked with a for-loop.
Basically the Event handlers are your if clicked statements.

Click Event of Dynamically generated Anchor Not Firing

I have an anchor on Lable Text.I am creating anchor with runat="server" dynamically on click of a button, It gets created as expected. I want to use its click event but it does not fire.
My code :
lblEmail.Text = email + " <a href='#' runat='server' class='crossicon' onclick='removebtn_Click'></a> ";
protected void removebtn_Click(object sender, EventArgs e)
{
}
How Can I create event for this button?I don't want to use JS, as in that case I will have to use a hidden field for new value
Adding markup/text to the label in that way wouldn't add the linkbutton or register the event to the control tree at the server. For that behavior of dynamically adding controls along with the server events to be achieved, you need to register the controls and events (as shown below)
aspx:
<asp:Panel runat="server" id="pnlEmail">
<asp:Label runat="server" id="lblEmail"/>
</asp:Panel>
aspx.cs:
In whichever event, you want to set the label text (along with the link)
lblEmail.Text = email;
LinkButton lnkbtnEmail = new LinkButton();
lnkbtn.Click += lnkbtn_Click;
lnkbtn.Text = "Dynamic Link";
pnlEmail.Controls.Add(lnkbtnEmail);
And the Handler would be
void lnkbtn_Click(object sender, EventArgs e)
{
// code for your dynamically generated link
}
By default, controls use __doPostBack to do the postback to the server. __doPostBack takes the UniqueID of the control (or in HTML, the name property of the HTML element). The second parameter is the name of the command to fire.
<a href='#' runat='server' class='crossicon' href="javascript:void(0);" onclick="__doPostBack('someuniqueid', '');></a>
System.Web.UI.Page already implements the IPostBackEventHandler interface by default, so you don't need to implement it on every page - it's already there.
You can override the RaisePostBackEvent method on the page like this:
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (source == SomeControl)
{
//do something
}
}
I hope it will help you.
I don't think so it is created dynamically. Where is ID of that control. You have to Create Server side control and add it into some placeholder/panel e.t.c

Change the value of a textbox in a template field from event outside of GridView

I need to be able to change the value of a TextBox(s) in a GridView template field from a TextChanged event. So the user can enter some text in a TextBox outside of the Gridview and then the TextBox(s) in the GridView gets updated to what the user entered.
This is what I need to do:
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
template_text_box1.Text( in template field ) = TextBox1.Text << (TextBox1)( outside of gridview )
}
I have tried FindControl. This needs to happen without using any of the GridView events. I am just stumped. Could someone point me in the right direction? Maybe some JavaScript?
I believe that you would want to define a separate TextBox for the display and do something like the following:
double value1;
private void template textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
if textBox1.Text (Double.TryParse(textBox1.Text, out value1))
{
textBox15 = value1.ToString();
}
}
This way you can make your other TextBox outside the grid and be able to call it and set to the value that is inputted.
On the .Aspx page, in the GridView column template TextBox add a CSS class.
<asp:TextBox ID="TextBox1" runat="server" CssClass="box-to-change" Text=""></asp:TextBox>
Also on the .Aspx page add a JavaScript function that uses jQuery:
<script type="text/javascript">
function updateAllTextboxes(value)
{
$('input.box-to-change').val(value);
}
</script>
In the code-behind add the JavaScript function as a client OnChange event (will not require PostBack).
otherTextBox.Attributes["onchange"] = "updateAllTextboxes(this.value)";

Dropdownlist SelectedIndexChanged firing on every postback

I am dynamically adding a custom user control to an update panel. My user control contains two dropdownlists and a textbox. When a control outside of the update panel triggers a postsback, I am re-adding the user control to the update panel.
The problem is...on postback when I re-add the user controls, it's firing the "SelectedIndexChanged" event of the dropdownlists inside the user control. Even if the selectedindex did not change since the last postback.
Any ideas?
I can post the code if necessary, but there's quite a bit in this particular scenario.
Thanks in advance!
EDIT...CODE ADDED BELOW
*.ASCX
<asp:DropDownList ID="ddlColumns" OnSelectedIndexChanged="ddlColumns_SelectedChanged" AppendDataBoundItems="true" AutoPostBack="true" runat="server">
*.ASCX.CS
List<dataColumnSpecs> dataColumns = new List<dataColumnSpecs>();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
fillDDLColumns();
}
}
public void fillDataColumnsList()
{
dataColumns.Clear();
//COMMON GETDATATABLE RETURNS A DATA TABLE POPULATED WITH THE RESULTS FROM THE STORED PROC COMMAND
DataTable dt = common.getDataTable(storedProcs.SELECT_COLUMNS, new List<SqlParameter>());
foreach (DataRow dr in dt.Rows)
{
dataColumns.Add(new dataColumnSpecs(dr["columnName"].ToString(), dr["friendlyName"].ToString(), dr["dataType"].ToString(), (int)dr["dataSize"]));
}
}
public void fillDDLColumns()
{
fillDataColumnsList();
ddlColumns.Items.Clear();
foreach (dataColumnSpecs dcs in dataColumns)
{
ListItem li = new ListItem();
li.Text = dcs.friendlyName;
li.Value = dcs.columnName;
ddlColumns.Items.Add(li);
}
ddlColumns.Items.Insert(0, new ListItem(" -SELECT A COLUMN- ", ""));
ddlColumns.DataBind();
}
protected void ddlColumns_SelectedChanged(object sender, EventArgs e)
{
//THIS CODE IS BEING FIRED WHEN A BUTTON ON THE PARENT *.ASPX IS CLICKED
}
*.ASPX
<asp:UpdatePanel ID="upControls" runat="server">
<ContentTemplate>
<asp:Button ID="btnAddControl" runat="server" Text="+" OnClick="btnAddControl_Click" />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnGo" runat="server" Text="Go" OnClick="btnGo_Click" ValidationGroup="vgGo" />
<asp:GridView...
*.ASPX.CS
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
uc_Counter = 0;
addControl();
gridview_DataBind();
}
else
{
reloadControls();
}
}
protected void btnGo_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
//THIS BUTTON CLICK IS WHAT'S TRIGGERING THE
//SELECTEDINDEXCHANGED EVENT TO FIRE ON MY *.ASCX
gridview_DataBind();
}
}
private void reloadControls()
{
int count = this.uc_Counter;
for (int i = 0; i < count; i++)
{
Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
myUserControl.ID = "scID_" + i;
upControls.ContentTemplateContainer.Controls.AddAt(i, myUserControl);
((customUserControl)myUserControl).fillDDLColumns();
}
}
private void addControl()
{
Control myUserControl = Page.LoadControl("~/Controls/myUserControl.ascx");
myUserControl.ID = "scID_" + uc_Counter.ToString();
upControls.ContentTemplateContainer.Controls.AddAt(upControls.ContentTemplateContainer.Controls.IndexOf(btnAddControl), myUserControl);
//((customUserControl)myUserControl).fillDDLColumns();
this.uc_Counter++;
}
protected int uc_Counter
{
get { return (int)ViewState["uc_Counter"]; }
set { ViewState["uc_Counter"] = value; }
}
Even though this is already answered I want to put an answer here since I've recently tangled with this problem and I couldn't find an answer anywhere that helped me but I did find a solution after a lot of digging into the code.
For me, the reason why this was happening was due to someone overwriting PageStatePersister to change how the viewstate hidden field is rendered. Why do that? I found my answer here.
One of the greatest problems when trying to optimize an ASP.NET page to be more search engine friendly is the view state hidden field. Most search engines give more score to the content of the firsts[sic] thousands of bytes of the document so if your first 2 KB are view state junk your pages are penalized. So the goal here is to move the view state data as down as possible.
What the code I encountered did was blank out the __VIEWSTATE hidden fields and create a view_state hidden field towards the bottom of the page. The problem with this is that it totally mucked up the viewstate and I was getting dropdownlists reported as being changed when they weren't, as well as having all dropdownlists going through the same handler on submit. It was a mess. My solution was to turn off this custom persister on this page only so I wouldn't have to compensate for all this weirdness.
protected override PageStatePersister PageStatePersister
{
get
{
if (LoginRedirectUrl == "/the_page_in_question.aspx")
{
return new HiddenFieldPageStatePersister(Page);
}
return new CustomPageStatePersister(this);
}
}
This allowed me to have my proper viewstate for the page I needed it on but kept the SEO code for the rest of the site. Hope this helps someone.
I found my answer in this post .net DropDownList gets cleared after postback
I changed my counter that I was storing in the viewstate to a session variable.
Then I moved my reloadControls() function from the Page_Load of the *.ASPX to the Page_Init.
The key was dynamically adding my user control in the Page_Init so it would be a member of the page before the Viewstate was applied to controls on the page.

Disable Postback on button ASP.NET c#

here is an example of what I am doing
Page Load
{
//Adds items to a panel (not an updatepanel just a normal panel control)
}
protected void btnNexMod_Click(object sender, EventArgs e)
{
// Calls DoWork() and Appends more items to the same panel
}
My problem is that the asp:button is doing a postback as well as calling DoWork()
Therefore, re-calling my page load, re-initializing my panel :(
I want my items that I have added to the panel to stay there!
All help appreciated, not looking for a hand you the answer kind-of deal. Any steps are appreciated thanks!
Here is an exact example of my problem.
protected void Page_Load(object sender, EventArgs e)
{
CheckBox chkbox = new CheckBox();
chkbox.Text = "hey";
chkbox.ID = "chk" + "hey";
// Add our checkbox to the panel
Panel1.Controls.Add(chkbox);
}
protected void Button1_Click(object sender, EventArgs e)
{
CheckBox chkbox = new CheckBox();
chkbox.Text = "hey";
chkbox.ID = "chk" + "hey";
// Add our checkbox to the panel
Panel1.Controls.Add(chkbox);
}
Only thing on the page is a empty panel and a button with this click even handler.
I have also tried this and it still doesn't work. Now its clearing the initial item appended to the panel.
if (!Page.IsPostBack) // to avoid reloading your control on postback
{
CheckBox chkbox = new CheckBox();
chkbox.Text = "Initial";
chkbox.ID = "chk" + "Initial";
// Add our checkbox to the panel
Panel1.Controls.Add(chkbox);
}
If you're adding controls to the Panel dynamically, then you'll have to recreate the controls at every postback, and make sure to assign the same IDs to the controls so that ViewState can populate the values. It's usually best to recreate dynamic content during OnInit, but this can be difficult in some situations.
One of my favorite tools is the DynamicControlsPlaceHolder, because you can add dynamic controls to it and it will persist them automagically, without any additional coding required on the page. Just add controls to it, and it will do the rest.
Here's the link:
http://www.denisbauer.com/Home/DynamicControlsPlaceholder
As for preventing your button from performing a postback, use OnClientClick and return false.
OnClientClick="return false;"
You could use
<asp:LinkButton OnClientClick="javascript:addItemsToPanel();return false;"
thus using a javascript function to add them. That's how I've got around that problem.
You can also try this:
Page Load
{
if (!this.IsPostBack) // to avoid reloading your control on postback
{
//Adds items to a panel (not an updatepanel just a normal panel control)
}
}
you can do like this...
ASPX code:
<asp:LinkButton ID="someID" runat="server" Text="clicky"></asp:LinkButton>
Code behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
someID.Attributes.Add("onClick", "return false;");
}
}
What renders as HTML is:
<a onclick="return false;" id="someID" href="javascript:__doPostBack('someID','')">clicky</a>
You are correct, you will have to add the new items to the Panel after a PostBack. That is the nature of the .NET pipeline.
If you use a data bound control, like a Repeater, to display the panel contents, then the button click handler just needs to rebind the control and it will all work out correctly.
Changing the asp:Button to a asp:LinkButton solved my issue.
I think, it is better use the Ajax Update panel. And put your button in to that.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button1" />
</ContentTemplate>
</asp:UpdatePanel>

Categories

Resources