|
I have windows form where I am adding control at run time but I couldn't remove them all. Some of them get removed but some stays there. I have spent already 4 hours nothing making sense why I couldn't simply remove controls from the form.
this.Controls(btn);---> this is how iam adding Controls
foreach (Control c in this.Controls)---> this is how am removing-->no achievement
{
this.Controls.Remove(c);
}
=========
but if copy all the controls to an arraylist and then it works. What a nosense is this is C#
ArrayList a = new ArrayList();
foreach (Control c in this.Controls )
{
a.Add(c);
}
foreach (Control cc in a)
{
this.Controls.Remove(cc);
}
modified on Saturday, July 26, 2008 4:01 PM
|
|
|
|
|
Every iteration of your foreach loop is incrementing an index,
but you're removing a control so all the other controls are shifted
up one in the collection. That means you'll miss every other control I
suppose
Maybe something like this:
for (int i = this.Controls.Count - 1; i >= 0; i--)
{
this.Controls.RemoveAt(i);
}
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote:
for (int i = this.Controls.Count - 1; i >= 0; i--)
{
this.Controls.RemoveAt(i);
}
...or...
foreach (Control c in Controls)
c.Dispose();
Controls.Clear();
Greetings - Gajatko
Portable.NET is part of DotGNU, a project to build a complete Free Software replacement for .NET - a system that truly belongs to the developers.
|
|
|
|
|
Much better
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
A honeyed cute version of yours I'd say.
Greetings - Gajatko
Portable.NET is part of DotGNU, a project to build a complete Free Software replacement for .NET - a system that truly belongs to the developers.
|
|
|
|
|
Hi,
Control.Controls is a collection with normal functionality.
As Mark said, you can't (reliably) modify a collection with a foreach loop.
However, isn't this.Controls.Clear() what you want?
|
|
|
|
|
How do I dispose the control before or after removeAt?
What i think about Controls.Clear() is that it doesn't remove resources taken by the object. It stays alive in the memory but Controls.Remove remove the object and it's resources. Corrrect me what you think of that
|
|
|
|
|
Neither of them remove the resources taken by the object.
Only the reference is removed from the collection. If there's
no more outstanding references, the objects will eventually
get cleaned up. You should iterate through and dispose any
disposable objects, however, to prevent leaks.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
netJP12L wrote: Controls.Remove remove the object and it's resources
I don't think so. The documentation clearly says:
ControlCollection.Remove Method "Removes the specified control from the control collection."
No more, no less.
The way I read this the Control is not modified, it just is removed from its parents Control list.
The Control remains intact, you can continue to use it, either as a hidden Control,
or you can add it to some other Container/Form/whatever.
The only method that clears resources is Dispose(); once called, the Control should not be used
any longer.
Besides, for Clear the documentation says: "Removes all controls from the collection."
Same verb, only difference is "all".
QED
|
|
|
|
|
Hi,
I investigated this a bit more, by experimenting and using Reflector.
These are my findings:
- a MenuItem holds a reference to the parent it is in, hence:
- a MenuItem is expected to be in no more than one MenuItemCollection, so it would be bad practice
to programmatically create a MenuItem then add it to two or more Menus or MenuItems.
- MenuItem.Dispose() does remove the menu item from its parents list by calling Remove().
- Remove() calls RemoveAt() based on the index kept in MenuItem;
- RemoveAt() modifies the collection, and for the last remaining item also calls Clear() which does
some extra stuff, e.g. repainting the main menu if that was the parent.
So instead of removing menu items and possibly worry about their disposal, one should
dispose of the menu items, and not worry about their removal!
This may be good then:
public static void ClearMenuItems(Menu menu) {
if (menu!=null) {
int count=menu.MenuItems.Count;
for (int i=count-1; i>=0; i--) {
MenuItem mi=menu.MenuItems[i];
if (mi!=null) mi.Dispose();
}
}
}
|
|
|
|
|
Hi,
I have a datagridview with a column that displays a number that comes from a database. I have a data table that has the numbers that show up in said column, and also text that corresponds to that number. I would like to set up a databinding scenario where I can make another column in that datagridview that will display the text that corresponds to the number one column over in that row.
Thanks
|
|
|
|
|
Is there something that you can use to count duplicate entries in an ArrayList?
I have a table that tells if a person is available and adds it to one arraylist. Then I have another table that contains tickets and who the ticket is assigned to. Now what I want to do is search the tickets for the Assigned field if that person is in the available ArrayList:
<br />
ArrayList admins = new ArrayList();<br />
ArrayList available = new ArrayList();<br />
<br />
SqlDataSource sa = new SqlDataSource(ConfigurationManager.ConnectionStrings["HelpDeskConnectionString"].ConnectionString, "SELECT [Admins] FROM [Admin_Table] WHERE ([Area] = 'System Administrator') AND ([Available] = 'True')");<br />
<br />
SqlDataSource count = new SqlDataSource(ConfigurationManager.ConnectionStrings["HelpDeskConnectionString"].ConnectionString, "SELECT [Assigned] FROM [User_Submit] WHERE ([Type] = 'System Administrator')");<br />
<br />
GridView gvAvail = new GridView();<br />
gvAvail.DataSource = sa;<br />
gvAvail.Visible = false;<br />
gvAvail.DataBind();<br />
this.Controls.Add(gvAvail);<br />
<br />
GridView gvCount = new GridView();<br />
gvCount.DataSource = count;<br />
gvCount.Visible = false;<br />
gvCount.DataBind();<br />
this.Controls.Add(gvCount);<br />
<br />
foreach (GridViewRow row in gvAvail.Rows)<br />
{<br />
available.Add(row.Cells[0].Text);<br />
}<br />
for (int i = 0; i < gvCount.Rows.Count; i++)<br />
{<br />
if (available.Contains(gvCount.Rows[i].Cells[0].Text))<br />
{<br />
admins.Add(gvCount.Rows[i].Cells[0].Text);<br />
}<br />
}<br />
<br />
Ok so now I have been racking my brain on this.. So as of right now I know who is available and I have the information of how many Tickets each System Administrator has at the current moment (that is the information in the admins ArrayList.
So I will have duplicate names. Lets say Jane Smith and John Doe are listed in the admins ArrayList. Jane Smith is listed 10 times and John Doe is listed 12 times. So the next ticket that comes in needs to be assigned to Jane Smith. BUT I do not know the names of the System Administrators.
So I need a way to count the duplicate entries and return whose name is listed the LEAST amount of time..
Any help would be greatful! I'm at a stand still.

|
|
|
|
|
Hi,
here is a simple way to get a list of unique names with their multiplicity; it may not be exact code,
and I will use 1.x terminology:
Hashtable multiplicity=new Hashtable();
foreach (string s in arrayList) {
if (multiplicity.Keys.Contains(s)) multiplicity[s].Value++;
else multiplicity.Add(s,1);
}
so basically it assigns a multiplicity counter as the Value in a new Hashtable, starting a new name at 1
and incrementing it whenever it appears again.
Using generics would be nicer, with a Dictionary<string, int>
BTW: maybe you don't need to first construct your ArrayList, then the multiplicity table;
you could try and skip the list and go for the table right away.
|
|
|
|
|
In a database, right?
If you have a table of Admins (with ID)
and a table of Tickets (with AssignedTo (foreign key to Admin.ID))
then you might do well with something like this to get the list of admins and how many tickets they have:
SELECT Admin.ID
,HowMany=COUNT(Ticket.ID)
FROM Admin
LEFT OUTER JOIN Ticket
ON Admin.ID=Ticket.AssignedTo
GROUP BY Admin.ID
ORDER BY COUNT(Ticket.ID)
You may choose to get only the TOP 1 record.
And you may choose to only query for the ID and not the number of tickets. In which case an ExecuteScalar can be used.
You will need to decide what to do when more than one admin tie for fewest tickets.
|
|
|
|
|
Ok that sounds better and I figured there was a way to do it wiht SQL but I wasnt sure how.. HEre is my tables:
Admin_Table
--> ID
--> Admins (Ex. John Doe, Jane Doe, John Smith)
--> Available (Ex. True, False)
--> Area --> (Ex. System Administrator, Telecommunications)
User_Submit
--> ID
--> Users_Name (Ex. John Doe, Jane Doe, John Smith)
--> Email
--> Started (Date Time)
--> Problem (varchar(MAX))
--> Assigned (Ex. John Doe, Jane Doe, John Smith)
--> Type (Ex. System Administrator, Telecommunications)
--> Viewed (Ex. True, False)
How does this exactly work? So:
SELECT [Admin_Table].ID, HowMany=COUNT(User_Submit.ID) FROM [Admin_Table] LEFT OUTER JOIN
[User_Submit] ON [Admin_Table.ID] = [User_Submit.Assigned] GROUP BY [Admin_Table.ID] ORDER
BY COUNT(User_Submit.ID)
Ok you have officially gone over my head. So how does this exactly tell if the Admin is HERE (Available from Admin_Table .. True False) and go through and count the Assigned from USer_Submit? Excluding the ones from Admin_Table that are False?
|
|
|
|
|
Assuming Available is of type BIT, add:
WHERE [Admin_Table.Available]=1
Likewise to match Area to Type if needed.
|
|
|
|
|
Assigned To is varchar and list the name of the system administrator. Also Available is True or False.
|
|
|
|
|
Well, I find that to be rather poor design on both counts.
AssignedTo should have the ID of the Admin and Available should be BIT. (Assuming BIT is supported by your choice of database.)
The code I provided should be adaptable to your situation with minimal effort.
|
|
|
|
|
PIEBALDconsult wrote: WHERE [Admin_Table.Available]=1
Where is all this leading? It started out as a question on ArrayList in a C# forum...
|
|
|
|
|
Well the SQL "seemed" easier and less coding but I don't understand it at all.
All I am trying to get is a list of System Administrators from one SQL Table that has tickets assigned to them. I am trying to get which System Administrator has the least amount of tickets assigned to him/her from that table (User_Submit Table)
Now when I have that information I need to determine if that user is here today from the Admin_Table under Available (which is True or False (varchar) )
|
|
|
|
|
I felt he was doing it the wrong way around; that all he needed was some SQL, and it seems that I was correct.
|
|
|
|
|
Yeah, I understood that much.
I must admit you far exceeded my limited SQL knowledge.
And you went way beyond the actual question, but rightly so.
Regards,
|
|
|
|
|
|
LOL.. ok but I still can't seem to get the SQL to work.. Could you take a look at my two tables from the previous post and what I need it to do and see whats wrong? Its not getting the right information.. I tried changing it many different ways
|
|
|
|
|
The problem might be this:
ON [Admin_Table.ID] = [User_Submit.Assigned]
|
|
|
|