Monday, February 27, 2006
The ListView control has a flicker issue. The problem appears to be that the control's Update overload is improperly implemented such that it acts like a Refresh. An Update should cause the control to redraw only its invalid regions whereas a Refresh redraws the control’s entire client area. So if you were to change, say, the background color of one item in the list then only that particular item should need to be repainted. Unfortunately, the ListView control seems to be of a different opinion and wants to repaint its entire surface whenever you mess with a single item… even if the item is not currently being displayed. So, anyways, you can easily suppress the flicker by rolling your own as follows:
class
ListViewNF : System.Windows.Forms.ListView
{
public ListViewNF()
{
//Activate double buffering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
//Enable the OnNotifyMessage event so we get a chance to filter out
// Windows messages before they get to the form's WndProc
this.SetStyle(ControlStyles.EnableNotifyMessage, true);
}
protected override void OnNotifyMessage(Message m)
{
//Filter out the WM_ERASEBKGND message
if(m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
}
Easy but with a couple little catches. If you need to do this, I recommend reading the help on the various properties of ProcessStartInfo. This code runs a console window that is visible to the user. There is a way to run commands by cmd.exe without actually showing a window... and I'm sure you can figure that out if you're interested enough. This should getcha started.
//set up to show a console window and send input to it
string pathToCmdExe = Environment.GetEnvironmentVariable("COMSPEC");
ProcessStartInfo psi = new ProcessStartInfo(pathToCmdExe);
psi.RedirectStandardInput = true;
psi.UseShellExecute = false;
//open the console windown
Process console = Process.Start(psi);
//send it a command
console.StandardInput.WriteLine("dir");
//TODO: Send more commands, read the results, etc.
//close the console window
console.Close();