private void Row_DoubleClick(object sender, MouseButtonEventArgs e)
        {
            //Ask the user if the process should be terminated in a popup window.

            refreshTimer.Stop();
            DataGridRow row         = sender as DataGridRow;
            ProcessRow  processRow  = row.Item as ProcessRow;
            string      messageText =
                "Should Memory Warden kill this process?\n" +
                "Name:\t" + processRow.nameText + "\n" +
                "PID:\t" + processRow.PIDText + "\n" +
                "Memory Usage: " + processRow.ramPercentText + "%";
            MessageBoxResult queryUser = MessageBox.Show(this, messageText, "Kill Process", MessageBoxButton.YesNo, MessageBoxImage.Hand, MessageBoxResult.No);

            if (queryUser == MessageBoxResult.Yes)
            {
                int processIndex = processesSorted.FindIndex(x => x.Id == processRow.PID);
                if (processIndex == -1)
                {
                    messageText = "Cannot kill process. \nBad internal index.";
                    DisplayErrorMessage(messageText, "Kill Process Failed");
                    Console.WriteLine(messageText);
                    return;
                }
                try { processesSorted[processIndex].Kill(); }
                catch (Win32Exception exception)
                {
                    messageText = "This process could not be killed.\n" + exception.Message;
                    DisplayErrorMessage(messageText, "Kill Process Failed");
                }
                catch (NotSupportedException exception)
                {
                    messageText = "This is a remote process and cannot be killed.\n" + exception.Message;
                    DisplayErrorMessage(messageText, "Kill Process Failed");
                }
                catch (InvalidOperationException exception)
                {
                    messageText = "This process does not exist anymore.\n" + exception.Message;
                    DisplayErrorMessage(messageText, "Kill Process Failed");
                }
            }
            refreshTimer.Start();
        }
        private void RefreshProcessTable(uint minProcessCount, uint maxProcessCount, uint minMemoryPercent)
        {
            //Do all the work of rebuilding the processTable, attempting efficiency.

            RefreshProcessLists();
            CalculateTotalProcessMemory();
            ObservableCollection <ProcessRow> processTableTemp = new ObservableCollection <ProcessRow>();
            double cumulativeMemorySum = 0.0;

            for (int n = 0; n < processes.Length; ++n)
            {
                //Don't care after these limits are reached
                if (((cumulativeMemorySum > minMemoryPercent) && (n >= minProcessCount)) ||
                    (n >= maxProcessCount))
                {
                    break;
                }

                ProcessRow temp = new ProcessRow(processes[n], totalProcessesMemory);
                cumulativeMemorySum += temp.ramPercent;
                processTableTemp.Add(temp);
            }

            if (processTable == null)
            {
                //First run, simply assign
                processTable = processTableTemp;
            }
            else
            {
                //Now merge the temp table with the original
                //Performance should be fine because these lists are kept small
                foreach (ProcessRow tempRow in processTableTemp)
                {
                    bool matchFound = false;
                    foreach (ProcessRow originalRow in processTable)
                    {
                        if (originalRow.PID == tempRow.PID)
                        {
                            originalRow.ramPercent = tempRow.ramPercent;
                            matchFound             = true;
                            break;
                        }
                    }
                    if (!matchFound)
                    {
                        //Add the tempRow instead
                        processTable.Add(tempRow);
                    }
                }

                //Cleanup removed processes
                ObservableCollection <ProcessRow> processesToRemove = new ObservableCollection <ProcessRow>();
                foreach (ProcessRow originalRow in processTable)
                {
                    bool matchFound = false;
                    foreach (ProcessRow tempRow in processTableTemp)
                    {
                        if (originalRow.PID == tempRow.PID)
                        {
                            matchFound = true;
                            break;
                        }
                    }
                    if (!matchFound)
                    {
                        //Old process not in new table
                        processesToRemove.Add(originalRow);
                    }
                }
                foreach (ProcessRow processToRemove in processesToRemove)
                {
                    processTable.Remove(processToRemove);
                }
            }
        }