|
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]
|
|
|
|
|
I've got a BackgroundWorker that's supposed to perform processing on a 1gb file, but the worker is completing immediately before it even gets to the processing code in the DoWork event handler.
When I put a breakpoint on the first line in the event handler, it tells me this:
Function evaluation disabled because a previous function evaluation timed out. You must continue execution to reenable function evaluation.<br />
What the hell does that mean?
I'm setting up the backgroundworker object like so:
encryptWorker = new BackgroundWorker();
encryptWorker.WorkerReportsProgress = true;
encryptWorker.WorkerSupportsCancellation = true;
encryptWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(encryptWorker_DoWork);
encryptWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(encryptWorker_RunWorkerCompleted);
encryptWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(encryptWorker_ProgressChanged);
I'm calling it like so. I've set a breakpoint on the last line in this block and have verified that the nextFile object is valid:
FileItem nextFile = m_filesToProcess[0];
this.m_fileBeingProcessed = nextFile;
while (this.encryptWorker.IsBusy)
{
Thread.Sleep(500);
}
this.progressBar.Value = 0;
this.encryptWorker.RunWorkerAsync(nextFile);
The DoWork function looks like this:
private void encryptWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker thisWorker = sender as BackgroundWorker;
FileItem fileItem = e.Argument as FileItem;
if (fileItem.Toggle == EncryptToggle.Encrypt)
{
switch (fileItem.EncryptType)
{
case "blah blah" :
{
FileEncryptor encryptor = new FileEncryptor(thisWorker, fileItem);
encryptor.EncryptFile();
}
break;
}
}
}
}
}
When I set a breakpoint on the first line of the function above, it takes a few seconds for the cursor to become available, and when I pressed F10 (or F11) to step over the line, none of the subsequent lines are executed, and the Completed event handler is called.
What have I done wrong?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
modified on Saturday, July 26, 2008 1:26 PM
|
|
|
|
|
Does your encryptWorker_RunWorkerCompleted ever get executed?
John Simmons / outlaw programmer wrote: encryptWorker.WorkerReportsProgress = true;
encryptWorker = new BackgroundWorker();
Did you mean to do that in that order?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: Does your encryptWorker_RunWorkerCompleted ever get executed?
Yes. It gets called and the code inside it executes. The progressChanged method never gets called though.
Mark Salsbery wrote: Did you mean to do that in that order?
Nah - cut/paste error (and I corrected the message).
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote: Yes. It gets called and the code inside it executes.
and AsyncCompletedEventArgs.Error == null there?
John Simmons / outlaw programmer wrote: The progressChanged method never gets called though.
I guess if ReportProgress is never getting called then it wouldn't...
Is it a debugger issue? I can't reproduce it here.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: and AsyncCompletedEventArgs.Error == null there?
Error, userState, and Result are all null.
Mark Salsbery wrote: Is it a debugger issue? I can't reproduce it here.
I don't know. If I let it run without the debugger, it doesn't crash. If I try to run it under the debugger, all hell breaks loose.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
John Simmons / outlaw programmer wrote: If I try to run it under the debugger, all hell breaks loose.
Hmm beats me - I'm on 2008.
FWIW here's my test code, stolen from the docs:
private System.ComponentModel.BackgroundWorker backgroundWorker1;
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 5; i++)
{
Thread.Sleep(1000);
this.backgroundWorker1.ReportProgress(i * 20);
}
e.Result = string.Format("**** Result String!");
this.backgroundWorker1.ReportProgress(100);
System.Diagnostics.Trace.WriteLine("**** End of DoWork");
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Diagnostics.Trace.WriteLine("**** RunWorkerCompleted");
if (e.Error != null)
{
System.Diagnostics.Trace.WriteLine(e.Error.Message);
}
else if (e.Cancelled)
{
System.Diagnostics.Trace.WriteLine("Canceled");
}
else
{
System.Diagnostics.Trace.WriteLine(e.Result.ToString());
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
System.Diagnostics.Trace.WriteLine(string.Format("**** ProgressChanged {0}%", e.ProgressPercentage));
}
...
this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
this.backgroundWorker1.WorkerReportsProgress = true;
this.backgroundWorker1.WorkerSupportsCancellation = false;
this.backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
this.backgroundWorker1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
this.backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
this.backgroundWorker1.RunWorkerAsync();
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
BTW, why do you have the "while (this.encryptWorker.IsBusy)"
loop before the RunWorkerAsync() call?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi John,
does this[^] help? The first hit seems to give a kind of workaround...
|
|
|
|
|
I presume this is a Windows.Forms application?
|
|
|
|