ConfirmButtonExtender not working when adding to control collection at runtime - c#

I am trying to add a ConfirmButtonExtender to my controls collection within a custom control at runtime but can not figure out why the extender will not wire to the button that is being added to the controls collection in the same CreateChildControls method. I did a simple test and added a button explicitly to an aspx page and then creating the extender dynamically in the PreRender of the the .cs file of that page and it still did not work. It seems that the only way to get this to work is to have the actual tags on the .aspx page.
Am I missing something?
protected virtual void CreateChildControls(System.Resources.ResourceManager rm)
{
valValidationSummary = new ValidationSummary();
valValidationSummary.ID = "valValidationSummary";
valValidationSummary.ShowSummary = true;
valValidationSummary.HeaderText = rm.GetString("ValidationSummary");
valValidationSummary.CssClass = "error";
btnGetRates = new LocalizedButton();
btnGetRates.ID = "btnGetStats";
btnGetRates.TextResource = rm.GetString("SubmitButton");
btnGetRates.Text = rm.GetString("SubmitButton");
btnGetRates.CssClass = "inputfield";
btnGetRates.Click += new System.EventHandler(OnSubmitButton_Click);
btnConfirmation = new ConfirmButtonExtender();
btnConfirmation.ID = "rfBtnSubmit_Confirm";
btnConfirmation.ConfirmText = rm.GetString("BAUConfrimation");
btnConfirmation.TargetControlID = "btnGetStats";
this.Controls.Add(btnConfirmation);
this.Controls.Add(valValidationSummary);
this.Controls.Add(btnGetRates);
}

Dumb mistake, I was not rendering the control.

Related

radiobuttonlist in updatepanel both dynamically created don't retain value on postback

I'm dynamically creating controls on my page (aspx) using the code below, but when the asynchronous postback triggers the radio button doesn't retain it's selection and the method uptheup doesn't get called. I'm guessing it's to do with the view state not returning the values, but I thought if the control ID was the same and it's created in Page_Init the in Page_Load the value should automatically be set from view state??
What I want is if someone selects No for the textbox to become visible. The control IDs are set from a database and are the same each time it loads as the code is used several times (I've replaced the IDs for easy reading below)
the following is called from Page_Init
RadioButtonList rbtnl = new RadioButtonList();
rbtnl.ID = "rbl_1";
rbtnl.Items.Add("Yes");
rbtnl.Items.Add("No");
rbtnl.AutoPostBack = true;
rbtnl.EnableViewState = true;
rbtnl.SelectedIndexChanged += new EventHandler(uptheup);
rbtnl.ClientIDMode = System.Web.UI.ClientIDMode.AutoID;
scriptmanager1.RegisterAsyncPostBackControl(rbtnl);
TextBox tbx = new TextBox();
tbx.ID = "tb-1";
tbx.CssClass = "form-control";
tbx.Visible = false;
UpdatePanel upx = new UpdatePanel();
upx.ID = "up-1";
upx.ContentTemplateContainer.Controls.Add(rbtnl);
upx.ContentTemplateContainer.Controls.Add(tbx);
upx.UpdateMode = UpdatePanelUpdateMode.Always;
upx.EnableViewState = true;
upx.ChildrenAsTriggers = true;
plcEvalBody.Controls.Add(upx);
OK so the code is fine and it works well, the issue was me assuming the IDs weren't the issue - they are - NEVER USE $ in control ID's. I'd used this to separate two sections of the ID and it is not valid.

find dynamically added controls from container

I am generating dynamic textbox controls on drop down selected index change event.
protected void ddlCategories_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (Attributes attribute in getAllAttributes(Convert.ToInt32(ddlCategories.SelectedValue)))
{
Panel div = new Panel();
div.Attributes.Add("class", "form-group");
HtmlGenericControl lbl = new HtmlGenericControl("label");
lbl.Attributes.Add("class", "col-lg-2 control-label");
lbl.InnerText = attribute.Name;
Panel innerdiv = new Panel();
innerdiv.Attributes.Add("class", "col-lg-10");
TextBox txt = new TextBox();
txt.ID = attribute.ID.ToString();
txt.Attributes.Add("class", "form-control");
innerdiv.Controls.Add(txt);
div.Controls.Add(lbl);
div.Controls.Add(innerdiv);
CustomAttributes.Controls.Add(div);
}
}
Now after the user fill up the values in the form i want to get the values of the dynamically generated controls. But CustomAttributes.findControls("") doesn't work for me. it gives null all the time.
I also tried
var textBoxesInContainer = CustomAttributes.Controls.OfType<TextBox>();
but it also doesnt work.
Can any one please tell me what is going wrong here.
Thanks
Finally i found the reason after googling the issue. The issue in this question is a view state.
In asp.net when the page post back it loses the viewstate for the dynamically generated controls. So to get over this issue i recreated the controls in the page load event when it is post back. in that way controls will be added back to the current page and i can find those controls in the button on click event.
thanks all for your time and guidence.
Panel div = new Panel();
Panel innerdiv = new Panel();
TextBox txt = new TextBox();
innerdiv.Controls.Add(txt);
div.Controls.Add(innerdiv);
CustomAttributes.Controls.Add(div);
Your CustomAttributes holds Panel.
Try this :
var textboxes = CustomAttributes.Controls.OfType<Panel>()
.Select(p => p.Controls.OfType<Panel>().First())
.Select(p => p.Controls.OfType<TextBox>().First())

Dynamic control click event not firing properly

I'm creating a next/previous function for my repeater using pageddatasource. I added the link button control dynamically in my oninit using the following code.
LinkButton lnkNext = new LinkButton();
lnkNext.Text = "Next";
lnkNext.Click += new EventHandler(NextPage);
if (currentPage != objPagedDataSource.PageCount)
{
pnlMain.Controls.Add(lnkNext);
}
So in my initial page_load, the next link comes up fine. There are 5 pages in my objPagedDataSource. currentPage variable is 1.
The "NextPage" event handler looks like this
public void NextPage(object sender, EventArgs e)
{
if (HttpContext.Current.Request.Cookies["PageNum"] == null)
{
HttpCookie cookie = new HttpCookie("PageNum");
cookie.Value = "1";
}
else
{
HttpCookie cookie = HttpContext.Current.Request.Cookies["PageNum"];
cookie.Value = (Convert.ToInt32(cookie.Value) + 1).ToString();
}
this.BindRepeater();
}
So I am incrementing the cookie I am using to track the page number and then rebinding the repeater.
Here is the main issue. The first time I click Next, it works, it goes to Page 2 without any problems. When on Page 2, I click Next, it goes back to Page 1. Seems like the Next event is not wiring up properly. Not sure why, any ideas?
You need to ensure you're adding your dynamic control to the Page every postback. Dynamic controls often cause much pain - in this case it would probably be much easier to declare the "Next" LinkButton in the markup in the normal way, and just set Visible = false when it isn't required.
While you are loading user controls dynamically you must set ID property without ID property Events will not fire.This is My sample code to call user controls dynamically
private void LoadUserControl()
{
string controlPath = LastLoadedControl;
if (!string.IsNullOrEmpty(controlPath))
{
PlaceHolder1.Controls.Clear();
UserControl uc = (UserControl)LoadControl(controlPath);
uc.ID = "uc"; //Set ID Property here
PlaceHolder1.Controls.Add(uc);
}
}

Events not firing for dynamic columns in SharePoint DataGrid

In a Web Part for Sharepoint, I'm trying to add a variable number/ordering of ButtonColumns to a DataGrid dynamically based on an option the user has selected. The problem is that the dynamic columns aren't firing off the events I set up on the DataGrid (such as SelectedIndexChanged). When the table originally constained a static set of columns, they were created in CreateChildControls() and everything worked peachy. However, since they are now dynamic, I have to delay adding them until after a search button's click event fires. I was wondering if there was some place I needed to move the column creation to that still allowed it to be dynamic but also allowed it to register/fire events.
outputDG creation in CreateChildControls():
outputDG = new System.Web.UI.WebControls.DataGrid();
outputDG.CellPadding = 4;
outputDG.HeaderStyle.Font.Bold = false;
outputDG.HeaderStyle.Font.Name = "Verdana";
outputDG.HeaderStyle.BackColor = Color.FromArgb(242,242,242);
outputDG.HeaderStyle.ForeColor = Color.FromArgb(128,128,128);
outputDG.HeaderStyle.Wrap = false;
//outputDG.ItemStyle.BorderColor = Color.Navy;
outputDG.HorizontalAlign = HorizontalAlign.Left;
//outputDG.BorderWidth = 1;
outputDG.GridLines = GridLines.Horizontal;
outputDG.Width = propsMgr.SearchGridWidth;
outputDG.PageSize = 10;
outputDG.AllowPaging = true;
outputDG.PagerStyle.Mode = PagerMode.NumericPages;
outputDG.PagerStyle.PageButtonCount = 5;
outputDG.PagerStyle.NextPageText = "Next Page";
outputDG.PagerStyle.PrevPageText = "Previous Page";
outputDG.PagerStyle.Visible = true;
outputDG.PageIndexChanged += new DataGridPageChangedEventHandler(this.outputDG_PageIndexChanged);
outputDG.AllowSorting = false;
outputDG.SortCommand += new DataGridSortCommandEventHandler(this.outputDG_SortCommand);
outputDG.SelectedItemStyle.BackColor = Color.FromArgb(255,244,206);
outputDG.SelectedIndexChanged += new EventHandler(this.outputDG_SelectedIndexChanged);
outputDG.ItemCreated += new DataGridItemEventHandler(this.outputDG_ItemCreated);
outputDG.AutoGenerateColumns = false;
outputDG.ItemCommand += new DataGridCommandEventHandler(outputDG_ItemCommand);
Controls.Add(outputDG);
During the search button's click event:
ButtonColumn buttonColumnSelect = new ButtonColumn();
buttonColumnSelect.ButtonType = ButtonColumnType.LinkButton;
buttonColumnSelect.CommandName = "Select";
buttonColumnSelect.HeaderText = "Column";
buttonColumnSelect.DataTextField = "columnField";
outputDG.Columns.Add(buttonColumnSelect);
And then later on it that same event I go through the result set and add in my data rows. Like I mentioned, this all worked back when the ButtomColumn code was up in CreateChildControls(), but it stopped working as soon as it was moved into an event. My best guess is that the event for the column doesn't have a chance to register in order to fire since it's happening from a different event. If I need to tackle this problem by building up the DataGrid differently, I'm definitely willing; I just need to be able to dynamically specify different columns to use.
maybe u need to set the ID-Attribute on the DataGrid.
otherwise it would be difficult for asp to find your control.
The fix for my case was to move the adding of the columns to the page's load event and the adding of the DataGrid to the controls after all of the columns are added.

Custom Header in GridView

I've already got my custom header drawing in my GridView using SetRenderMethodDelegate on the header row within the OnRowCreated method. I'm having problems trying to add LinkButtons to the new header row though.
This is what the RenderMethod looks like:
private void RenderSelectionMode(HtmlTextWriter output, Control container)
{
TableHeaderCell cell = new TableHeaderCell();
cell.Attributes["colspan"] = container.Controls.Count.ToString();
AddSelectionModeContents(cell);
cell.RenderControl(output);
output.WriteEndTag("tr");
HeaderStyle.AddAttributesToRender(output);
output.WriteBeginTag("tr");
for(int i = 0; i < container.Controls.Count; i++)
{
DataControlFieldHeaderCell cell = (DataControlFieldHeaderCell)container.Controls[i];
cell.RenderControl(output);
}
}
private void AddSelectionModeContents(Control parent)
{
// TODO: should add css classes
HtmlGenericControl label = new HtmlGenericControl("label");
label.InnerText = "Select:";
selectNoneLK = new LinkButton();
selectNoneLK.ID = "SelectNoneLK";
selectNoneLK.Text = "None";
//selectNoneLK.Attributes["href"] = Page.ClientScript.GetPostBackClientHyperlink(selectNoneLK, "");
//selectNoneLK.Click += SelectNoneLK_Click;
selectNoneLK.Command += SelectNoneLK_Click;
selectAllLK = new LinkButton();
selectAllLK.ID = "SelectAllLK";
selectAllLK.Text = "All";
//selectAllLK.Attributes["href"] = Page.ClientScript.GetPostBackClientHyperlink(selectAllLK, "");
//selectAllLK.Click += SelectAllLK_Click;
selectAllLK.Command += SelectAllLK_Click;
parent.Controls.Add(label);
parent.Controls.Add(selectNoneLK);
parent.Controls.Add(selectAllLK);
}
As you can see, I have tried different ways to get my LinkButtons working (none have worked though). The LinkButtons are rendered as plain anchor tags, like this: <a id="SelectNoneLK">None</a>
I know there is something wrong with the fact that the ID looks like that, since I am using a Master page for this and the ID should be something much longer.
Any help would be appreciated!
Nick
I'd guess that since cell is not part of the control hierarchy (you never add it to the table), the LinkButton's never find an IContainer parent to rewrite their ID's.
I tend to solve these types of issues using the excellent RenderPipe control that allows me to declare my controls in one place, but render them somewhere else.

Categories