I have an event set up to fire when an item in a ListView is checked. The event calls a function which updates various controls inside my form. Among other things, I need to enable or disable buttons based on how many items are checked. This function is quite expensive.
Example:
private void listView_ItemCheck(object sender, ItemCheckEventArgs e)
{
UpdateForm();
}
Now the problem arises when a user wants to check many items at once. This causes the application to be unresponsive for a little while.
So, I would like to call UpdateForm()
once after all the items were checked, instead of every time a single item is checked.
EDIT:
Here's a part of UpdateForm()
:
private void UpdateForm()
{
// Puts all files in the mod list in a new list
List<string> modListFiles = new List<string>(lvFiles.Items.Count);
foreach (ListViewItem lvi in lvFiles.Items)
{
modListFiles.Add(lvi.Text);
}
// Adds found files to the file list
foreach (string file in Files)
{
lvFiles.Items.Add(new ListViewItem(file));
}
// Removes files from mod list that no longer exist
List<string> deleteQue = new List<string>(lvFiles.Items.Count);
foreach (string file in modListFiles)
{
// If a file in the list doesn't exist anymore, que it to delete
if (!Files.Contains(file))
{
deleteQue.Add(file);
}
}
// Remove queued files
foreach (string file in deleteQue)
{
foreach (ListViewItem lvi in lvFiles.Items)
{
if (lvi.Text == file)
{
lvFiles.Items.Remove(lvi);
break;
}
}
}
// Grays out mod list if a profile is installed
if (InstalledProfile == null)
{
lvFiles.BackColor = SystemColors.Window;
lvFiles.ForeColor = SystemColors.WindowText;
}
else
{
lvFiles.BackColor = SystemColors.Control;
lvFiles.ForeColor = SystemColors.ControlDark;
}
// Fills out the game path if it exists
if (Directory.Exists(GamePath))
{
txtGamePath.Text = GamePath;
}
else
{
txtGamePath.Text = "Game directory does not exist!";
}
// Makes sure that the cbxProfiles_SelectedIndexChanged doesn't run UpdateForm() again
handleProfileChanged = false;
// Adds profiles to the combobox
foreach (string profile in Profiles)
{
if (!cbxProfiles.Items.Contains(profile))
{
cbxProfiles.Items.Add(profile);
}
}
// Removes nonexistant profiles from the combobox
foreach (string profile in cbxProfiles.Items)
{
if (!Profiles.Contains(profile))
{
cbxProfiles.Items.Remove(profile);
}
}
if (InstalledProfile == null)
{
btnInstallUninstall.Text = "Install";
}
else
{
btnInstallUninstall.Text = "Uninstall";
}
if (Directory.Exists(GamePath) && lvFiles.CheckedItems.Count > 0)
{
btnInstallUninstall.Enabled = true;
}
else
{
btnInstallUninstall.Enabled = false;
}
}
I've had to simplify some things so please excuse any errors I have probably made.
Some context:
I'm trying to make a program that copies files from a set directory \mods to a user specified directory GamePath
. It shows all files found in \mods, then allows the user to check some of them. Clicking btnInstall
will copy these files to GamePath
. After this so called installing, the copied files can be removed by clicking btnInstall
again.
All of the properties I made (Profiles
, GamePath
) get and set their values using an XML file on disk. The main ListView is called lvFiles
, sometimes called mod list or file list in comments.