I have an UpdatePanel and in it a regular Panel. In the Panel I dynamically add simple UserControls. The Usercontrol has a Button and a Label. When I click on a button in a control it removes all controls in the Panel which I have added dynamically.
Can anyone help?
int controlID = 0;
List<Control> cc = new List<Control>();
if (Session["ControlsCompleted"] != null)
{
cc = Session["ControlsCompleted"] as List<Control>;
for (int i = 0; i < cc.Count; i++)
{
pnlCompletedEducation.Controls.Add(cc[i]);
}
controlID = cc.Count;
}
Controls_TestWebUserControl ct = LoadControl(#"Controls\TestWebUserControl.ascx") as Controls_TestWebUserControl;
ct.ID = controlID.ToString();
cc.Add(ct);
ct.EnableViewState = true;
pnlCompletedEducation.Controls.Add(ct);
txtInstitutionName.Text = controlID.ToString();
List<Control> lc = new List<Control>();
for (int i = 0; i < pnlCompletedEducation.Controls.Count; i++)
{
lc.Add(pnlCompletedEducation.Controls[i]);
}
Session["ControlsCompleted"] = lc;
This is how I add the controls to the panel. I had to keep them somewhere, and i couldn't do it with the ViewState, so i used a Session, which is a bad idea.
You say that you are adding the user control dynamically. Are you having code like this:
void Page_Load(...)
{
if (!IsPostback)
// AddUserControl here.
}
You need to add the user control during every request, also postbacks, because it will not be stored in the view state that you have modified the control tree.
You problem that you have not recreated (for example at Page_Load) dynamically added control.
Make sure that control is recreated on IsPostBack
Related
I have a following scenario , in which I am dynamically creating bunch of controls in the panel and I have also the feature of removing and adding controls in the panel later on.
Following controls , I want to remove from the panel using the selection of the checkbox that is inside the each of the subcontrol .
Removal Code
Using the Idea mentioned in Stackoverflow , I avoided foreach loop and came up with the following code.
for (int i = 0; i < panelDetection.Controls.Count; i++)
{
if (panelDetection.Controls[i] is ImageControl)
{
ImageControl imageControl = (ImageControl)panelDetection.Controls[i];
for(int j = 0; j < imageControl.Controls.Count; j++)
{
if (imageControl.Controls[j] is CheckBox)
{
CheckBox chkBox = (CheckBox)(imageControl.Controls[j]);
if (chkBox.Checked)
{
chkBox.Click -= CheckBox_Click;
panelDetection.Controls.Remove(imageControl);
imageControl.Dispose();
}
}
}
}
}
But the result is very strange as the controls are not getting removed of from the panel in an expected way. You can see that all selected controls are not getting removed from the panel.
Is there any way to achieve this functionality using some other idea?
I have a form that has TabControl with Dynamic TabPages in it. Each pages has usercontrol added using a loop. This is how I add the usercontrol in each pages.
for (var i = 0; i < tbl.Rows.Count; i++)
{
uctrTab = new XtraTabPagesUserCtrl();
xtab.TabPages[i].Text = "Table " + (i+1);
uctrTab.LayoutClicked += new MouseEventHandler(Layout_Click);
xtab.TabPages[i].Controls.Add(uctrTab);
xtab.TabPages[i].PageVisible = !xtab.TabPages[i].PageVisible;
}
The usercontrol I made has a DataGridView in it so i want to refresh the content of it but I dont know how to do that without removing and readding the control back.
right now my solution is
xtab.SelectedTabPage.Controls.Clear();
uctrTab = new XtraTabPagesUserCtrl();
uctrTab.LayoutClicked += new MouseEventHandler(Layout_Click);
xtab.SelectedTabPage.Controls.Add(uctrTab);
is there any better way of refreshing the content without having to do that?
I'm going to write my answer here (I did it in the comments section because question was on hold).
My suggestion.. first implement a method in your user control like..
public void RefreshGrid()
{
refresh datagridview data here
}
Second, itearate over selected tab page's controls and look for your usercontrol.. something like this..
foreach(Control ctrl in selectedTabPage.Controls)
{
if(ctrl is XtraTabPagesUserCtrl)
{
((XtraTabPagesUserCtrl)ctrl).RefreshGrid();
}
}
Some inits done earlier in the code...
private List<System.Windows.Forms.TabPage> tab_pages = new List<System.Windows.Forms.TabPage>();
int tab_increment = 0;
Somewhere in the code, I create a bunch of tab pages in real-time.
for (i=0; i<5; i++)
{
tab_pages.Add( new System.Windows.Forms.TabPage() );
tab_pages[tab_increment].Location = new System.Drawing.Point(4, 22);
tab_pages[tab_increment].Name = 1 + tab_increment.ToString();
tab_pages[tab_increment].Size = new System.Drawing.Size(501, 281);
tab_pages[tab_increment].Text = tab_increment.ToString();
this.tabControl.Controls.Add(tab_pages[tab_increment]);
tab_increment += 1;
}
Now I would like to access elements that are these tab pages. Also let's pretend that I created different elements on each page (example, tabPage[0] a button, tabPage[1] a checkbox, etc), how do I access them knowing that everything was added dynamically?
Check this approach:
void Walk(Control control)
{
foreach (Control c in control.Controls)
{
//just walking through controls...
//...do something
//but remember, it could contain containers itself (say, groupbox or panel, etc.)...so, do a recursion
if (c.Controls.Count > 0)
Walk(c);
}
//or
foreach (Button btn in control.Controls.OfType<Button>())
{
//an example of how to walk through controls sub array of certain type
//this loop won't have a single iteration if this page contains no Buttons
//..so you can replace Button
//and have some certain code for different types of controls
}
}
And launch it for tabcontrol:
foreach (TabPage page in tabControl1.TabPages)
Walk(page);
I guess there is no special need to have separate collection of tabpages for one tabcontrol, as soon as it has TabPages property.
In the code above I used Enumerable.OfType Method to get a subcollection of controls of certain type.
As for your code, try this:
for (int i = 0; i < 5; i++)
{
this.tabControl.Controls.Add(new System.Windows.Forms.TabPage());
this.tabControl.TabPages[i].Text = i.ToString();
//...do whatever you need
//...
//besdies, I think, ther's no need in tab_increment...loop index works well enough
}
In order to add pages, I think that using
tabControl.TabPages.Add(new TabPage("Name"));
or in your case
this.tabControl.TabPages.Add(tab_pages[tab_increment]);
is more suitable.
In order to access them you could use
TabPage tp = tabControl.TabPages[i]; //where i is the index of your TabPage
and you can use TabPage.Controls.Add of the Controls property to add any Control on the TabPage like:
Button btn = new Button();
btn.Name = "Button name";
tp.Controls.Add(btn);
You can use the Controls property on the TabPage object. Each control in the collection is given to you as a Control, and it is up to you to cast them to the type that you want.
I am trying to add Checkboxes dynamically to webpage
string[] words = masg.Split('~');
int size = words.Length;
CheckBox[] cbl = new CheckBox[size];
for (int i = 0; i < words.Length; i++)
{
cbl[i] = new CheckBox();
cbl[i].Text = words[i].ToString();
this.Controls.Add(cbl[i]);
// Response.Write("\n" + words[i]);
}
I am getting error
Control 'ctl01' of type 'CheckBox' must be placed inside a form tag with runat=server.
How should I proceed ? What changes to make on aspx page ? Please help.
You should change it to add in form, because this is referencing your Page. and any server control which you are creating programmatic or by adding on page with runat="server" should place inside a form tag.
like
this.Form.Controls.Add(cbl[i]);
or place a placeholder or panel on the form. and than you can add in it
like
placeholder1.Controls.Add(cbl[i]);
If your .aspx does not contain a form tag, then you should place a form tag there
like
<form runat="server" id="form1">
//Other mark up or server controls.
</form>
hi you need to add a parent control like Panel on your form and then add your check box controls to that panel
string[] words = masg.Split('~');
int size = words.Length;
CheckBox[] cbl = new CheckBox[size];
for (int i = 0; i < words.Length; i++)
{
cbl[i] = new CheckBox();
cbl[i].Text = words[i].ToString();
pnlControls.Controls.Add(cbl[i]);
// Response.Write("\n" + words[i]);
}
Add the a panle control in your aspx page :
<asp:Panel ID="pnlControls" runat="server" >
On one web user control
public void displayFindingSection(int sectionsid,string text,string head)
{
SectionHeading.Text = head;
DataSet totImgs;
totImgs = objGetBaseCase.GetFindingsNewerImages(sectionsid);
FindingViewerlist.DataSource = totImgs;
DataBind();
SectionText.Text = text;
}
On other web user control
public void DisplayFindingsViewer(CipCaseWorkflowItem2 item)
{
FindingViewerDisplay.Visible = true;
ImageAndSimpleViewer.Visible = false;
objGetBaseCase.GetFindingsImages((Convert.ToInt32(Session["CaseId"])), item.ItemId);
FindingsViewerNew = objGetBaseCase.GetFindingViewerNewElementDetails(item.ItemId);
for (int i = 0; i < FindingsViewerNew.Count; i++)
{
FindingViwerDisplay uc = (FindingViwerDisplay)LoadControl("FindingViwerDisplay.ascx");
FindingPlaceholder.Controls.Add(uc);
uc.displayFindingSection(Convert.ToInt32(FindingsViewerNew[i].Index), FindingsViewerNew[i].Text, FindingsViewerNew[i].Title);
}
}
I am adding the all the image in user control and displaying the image, but when i am using the above code, web user control is also adding every time and one image is showing in in control what i want is all images should show in only one user control.. sectionsid is getting the image id from the database. I think prob with for loop but i am unable to solve it.. help me it that
Might be it is happening u have defined it inside the loop
FindingViwerDisplay uc = (FindingViwerDisplay)LoadControl("FindingViwerDisplay.ascx");
FindingPlaceholder.Controls.Add(uc);
On Each loop you are adding uc and calling displayFindingSection whcich ofcouse add 1 image than loop go back add a new control again and than add one image it will go on till your loop completion so add control once before loop and call just displayFindingSection in loop..
Do this,
FindingViwerDisplay uc = (FindingViwerDisplay)LoadControl("FindingViwerDisplay.ascx");
FindingPlaceholder.Controls.Add(uc);
//define here a dataTabel with three columns let say u have datatable dt
for (int i = 0; i < FindingsViewerNew.Count; i++)
{
dt.Rows.Add(Convert.ToInt32(FindingsViewerNew[i].Index), FindingsViewerNew[i].Text, FindingsViewerNew[i].Title);
}
uc.displayFindingSection(dt);
Then work out on that dt in displayFindingSection
Sorry if i am wrong...