|
I have a listview control which gets updated every 3 seconds with all the processes running on my Machine . I want my control to behave just like the Process Tab on Windows Task manager . I Am able to prevent the listview control from fickering by using the BeginUpdate and EndUpdate Method. but the problem is, it is not behaving like the windows task Manager. if I use the vertical bar and scrolls down, it get back to the begining when the listview gets updated. Again if I Select a process it unselects the moment the listview gets updated. Can someone save me from this. Please again I want it to behave just like the Process Tab on windows Task Manager . - Moved byTaylorMichaelLMVP20 hours 56 minutes agoWinForms related (From:Visual C# General)
-
|
| edwardkorankyi Wednesday, October 07, 2009 8:12 PM |
Don't clear the Items collection. Add and remove items only as necessary to fill the list. For example: public static void SetListItem(ListView list, ListViewItem item, int index) { while (list.Items.Count < index - 1) list.Items.Add(""); list.Items[index] = item; } public static void TruncateList(ListView list, int items) { while (list.Items.Count > items) list.Items.RemoveAt(list.Items.Count - 1); } Call SetListItem while you iterate the process collection, TruncateList when you're done. Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Wednesday, October 07, 2009 9:48 PM |
The native ListView control has excellent flicker suppression with double-buffering, .NET supports it. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form. You'll still want to use Begin/EndUpdate(), it makes updating the list a lot quicker. using System; using System.Windows.Forms; public class MyListView : ListView { public MyListView() { this.DoubleBuffered = true; } }
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Thursday, October 08, 2009 2:47 AM |
There is a complication, you can't let the ListView do the sorting. That shuffles the items internally and prevent a proper update. Disabling the sorting, then enabling it again after the update causes the scrollbar to reset. This worked well: private void LoadProccessList() { System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses(); Array.Sort(processes, new Comparison<System.Diagnostics.Process>( (p1, p2) => string.Compare(p1.ProcessName, p2.ProcessName)) ); lstProcesses.BeginUpdate(); int count = 0; foreach (System.Diagnostics.Process proc in processes) { try { ListViewItem item = new ListViewItem(); item.Text = proc.ProcessName; item.SubItems.Add(proc.Id.ToString()); //... if (lstProcesses.Items.Count > count) lstProcesses.Items[count] = item; else lstProcesses.Items.Add(item); ++count; } catch { } } while (lstProcesses.Items.Count > count) lstProcesses.Items.RemoveAt(lstProcesses.Items.Count - 1); lstProcesses.EndUpdate(); }
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Thursday, October 08, 2009 3:48 AM |
I'm guessing that you still use lstProcesses.Sort(). Yes, you'll have to restore the selection after the update, it might have moved.
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Thursday, October 08, 2009 4:11 AM |
Don't clear the Items collection. Add and remove items only as necessary to fill the list. For example: public static void SetListItem(ListView list, ListViewItem item, int index) { while (list.Items.Count < index - 1) list.Items.Add(""); list.Items[index] = item; } public static void TruncateList(ListView list, int items) { while (list.Items.Count > items) list.Items.RemoveAt(list.Items.Count - 1); } Call SetListItem while you iterate the process collection, TruncateList when you're done. Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Wednesday, October 07, 2009 9:48 PM |
Thanks though but I don't get it. This is my method that Populate my list view. Can you please help me using that? Where lstProcesses is the name of my list view private void LoadProccessList() { //Get All the curent Process of the System// System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses(); lstProcesses.BeginUpdate(); lstProcesses.Items.Clear(); //Prevents lstProcess from repainting //Load all the cureent processors Running// //Loop throug and grap all the need processes// foreach (System.Diagnostics.Process proc in processes) { ListViewItem newItems = new ListViewItem(); newItems.Text = proc.ProcessName; newItems.SubItems.Add(proc.Id.ToString()); newItems.SubItems.Add(proc.Responding.ToString()); newItems.SubItems.Add(string.Format("{0:###,###,###} K", proc.PeakWorkingSet64 / 1024)); newItems.SubItems.Add(proc.HandleCount.ToString()); newItems.SubItems.Add(proc.Threads.Count.ToString()); lstProcesses.Items.Add(newItems); } lstProcesses.Sort(); lstProcesses.EndUpdate(); } |
| edwardkorankyi Thursday, October 08, 2009 2:21 AM |
Hi, I believe this is what NoBugz is suggesting;
private void LoadProccessList()
{
//Get All the curent Process of the System//
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses();
lstProcesses.BeginUpdate();
//Prevents lstProcess from repainting
//Load all the cureent processors Running//
//Loop throug and grap all the need processes//
foreach (System.Diagnostics.Process proc in processes)
{
ListViewItem item = lstProcesses.Items[proc.Id.ToString()];
if (item == null)
item = lstProcesses.Items.Add(proc.Id.ToString(), proc.ProcessName, 0);
item.Text = proc.ProcessName;
item.SubItems.Add(proc.Id.ToString());
item.SubItems.Add(proc.Responding.ToString());
item.SubItems.Add(string.Format("{0:###,###,###} K", proc.PeakWorkingSet64 / 1024));
item.SubItems.Add(proc.HandleCount.ToString());
item.SubItems.Add(proc.Threads.Count.ToString());
}
lstProcesses.Sort();
lstProcesses.EndUpdate();
}<br /><br />
Note the item is added with the process id as it's key, before we add the item we check to see if an item with that id (key) already exists in the list and if so we update it instead of adding it again, and we remove the code that clears the entire list. There are two problems with this code; 1. It still flickers on my PC, even with double buffering turned on in the form properties, the sort removed, and the begin/end update removed. It flickers less than your original solution however, and it won't reset the selected item whenever the list loads etc. You could perhaps reduce the flicker somewhat by only updating columns where the new value was actually different from the old one, but I'm not sure even that will eliminate the flicker entirely. 2. It doesn't clear out processes that have died... extra logic would be needed to make that work. You would have to look for items in the list view that aren't in the process list and remove them from the list view, which would also probably cause some more flicker when processes were removed. |
| Yort Thursday, October 08, 2009 2:34 AM |
The native ListView control has excellent flicker suppression with double-buffering, .NET supports it. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form. You'll still want to use Begin/EndUpdate(), it makes updating the list a lot quicker. using System; using System.Windows.Forms; public class MyListView : ListView { public MyListView() { this.DoubleBuffered = true; } }
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Thursday, October 08, 2009 2:47 AM |
I am getting confuse. Can you please give me an example base on my code. I tried the above but still don't work. Please help me.
|
| edwardkorankyi Thursday, October 08, 2009 3:16 AM |
I tried what you typed it didn't work.
- Edited byedwardkorankyi Thursday, October 08, 2009 3:47 AM
-
|
| edwardkorankyi Thursday, October 08, 2009 3:39 AM |
Sorry I meant I tried what you typed it didn't work. |
| edwardkorankyi Thursday, October 08, 2009 3:47 AM |
There is a complication, you can't let the ListView do the sorting. That shuffles the items internally and prevent a proper update. Disabling the sorting, then enabling it again after the update causes the scrollbar to reset. This worked well: private void LoadProccessList() { System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcesses(); Array.Sort(processes, new Comparison<System.Diagnostics.Process>( (p1, p2) => string.Compare(p1.ProcessName, p2.ProcessName)) ); lstProcesses.BeginUpdate(); int count = 0; foreach (System.Diagnostics.Process proc in processes) { try { ListViewItem item = new ListViewItem(); item.Text = proc.ProcessName; item.SubItems.Add(proc.Id.ToString()); //... if (lstProcesses.Items.Count > count) lstProcesses.Items[count] = item; else lstProcesses.Items.Add(item); ++count; } catch { } } while (lstProcesses.Items.Count > count) lstProcesses.Items.RemoveAt(lstProcesses.Items.Count - 1); lstProcesses.EndUpdate(); }
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Thursday, October 08, 2009 3:48 AM |
I tried it, it seems adding the process names twice.the scroll bar doesn't reset that works fine but the problem is when I select a row of process, it unselects again. I wanted it to behave like the Windows task Manager.
|
| edwardkorankyi Thursday, October 08, 2009 4:07 AM |
I'm guessing that you still use lstProcesses.Sort(). Yes, you'll have to restore the selection after the update, it might have moved.
Hans Passant.- Marked As Answer byAland LiMSFT, Moderator2 hours 41 minutes ago
-
|
| nobugz Thursday, October 08, 2009 4:11 AM |
my bad it works. you are right. But the Select doesn't work. each time I select a process, it Unselects. can you please help me with that. That though.
|
| edwardkorankyi Thursday, October 08, 2009 4:13 AM |
is there any trick i would use to maintain the selection from not reseting
|
| edwardkorankyi 21 hours 23 minutes ago |
Hi edwardkorankyi,
You need to store the selected process names in some varialbes and select them again after the ListView is refreshed.
Regards, Aland Li Please mark the replies as answers if they help and unmark if they don't. This can be beneficial to other community members reading the thread. |
| Aland Li 2 hours 42 minutes ago |