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?
Related
I'm making a program that has to count how many CheckBox controls are checked, only in a GroupBox.
I've tried a lot of different ways but I can't get it work.
How can this be made?
// This is one of the many things I tried...
public CheckBox rNum;
//This method is used on FormLoad.
public void CreateBoxes()
{
for (int i = 0; i < 36; i++)
{
rNum = new CheckBox();
rNum.Text = i.ToString();
//CheckBoxes added to flowLayoutPanel.
flw.Controls.Add(rNum);
}
}
public int count;
//This method is used on Button Click
public void CountIt()
{
foreach (CheckBox box in groupBox.Controls.OfType<CheckBox>())
{
if (box.Checked)
{
count++;
}
}
MessageBox.Show(count.ToString());
}
You can use a linq query like this:
var count = flw.Controls.OfType<CheckBox>().Count(x=>x.Checked);
It returns count of CheckBox controls in flw which are checked.
Based on your comments and the edits to your question, you need to be looking for your CheckBoxes in the FlowLayoutPanel to which you added them, not groupBox. Given that your FlowLayoutPanel is called flw, do the following:
public void CountIt()
{
foreach (CheckBox box in flw.Controls.OfType<CheckBox>())
{
if (box.Checked)
{
count++;
}
}
MessageBox.Show(count.ToString());
}
Note that I'm increasing the count only when the CheckBox is checked, which is now reflected in your question. Failing to do that check was a bug in your original code.
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();
}
}
I'm trying to select all items in ListBox and made this extension method for this purpose:
public static void SetSelectedAllItems(this ListBox ctl)
{
for (int i = 0; i < ctl.Items.Count; i++)
{
ctl.SetSelected(i, true);
}
}
Problem is that if I have lots of items in the ListBox, it takes a long time to accomplish this task and I can watch how the ListBox is automatically scrolling down and selecting items.
Is there a way to temporary pause the update of a control, so that the task would finish faster? I tried using:
ctl.SuspendLayout();
for (int i = 0; i < ctl.Items.Count; i++)
...
ctl.ResumeLayout();
But that doesn't seem to do anything.
Call the BeginUpdate and EndUpdate methods to prevent the drawing/rendering of the control while properties on that control are being set.
Here is the revised code:
public static void SetSelectedAllItems(this ListBox ctl)
{
ctl.BeginUpdate();
for (int i = 0; i < ctl.Items.Count; i++)
{
ctl.SetSelected(i, true);
}
ctl.EndUpdate();
}
You said that you've tried calling SuspendLayout and ResumeLayout, but that only affects the control's layout events. This pair of methods is used when you want to change a control's position relative to other controls, like when you set the Size, Location, Anchor, or Dock properties.
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...
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