如何实时添加到listView搜索结果?

时间:2016-02-05 04:52:07

标签: c# .net winforms

我的程序搜索文件内的文本。 但我想要做的是实时查看搜索进度。 我想将当前文件名搜索添加到listView中,并将显示到progressBar的百分比从0到100%。

我添加了一个后台工作者,但我使用ReportProgress的方式效果不佳。我需要等待它在FindLines方法中完成foreach,然后只在最后我看到listView中的项目,甚至那些项目都是一团糟。

这是报告的行:

backgroundWorker1.ReportProgress(0, fi.Name);

这是foreach结束时listView中项目的屏幕截图: 我想要做的是实时显示添加到listView的项目,而无需先等待操作结束,并将每个项目添加到一行,如果一行太长,那么稍后我会添加一个提示气球或其他东西。但现在listView看起来像一团糟。

listView

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace Search_Text_In_Files
{
    public partial class Form1 : Form
    {
        StreamWriter w = new StreamWriter(@"e:\textresults.txt");

        public Form1()
        {
            InitializeComponent();

            backgroundWorker1.RunWorkerAsync();           
        }

        public List<string> FindLines(string DirName, string TextToSearch)
        {
            int counter = 0;
            List<string> findLines = new List<string>();
            DirectoryInfo di = new DirectoryInfo(DirName);
            if (di != null && di.Exists)
            {
                if (CheckFileForAccess(DirName) == true)
                {
                    foreach (FileInfo fi in di.EnumerateFiles("*", SearchOption.AllDirectories))
                    {
                        if (string.Compare(fi.Extension, ".cs", true) == 0)
                        {
                            backgroundWorker1.ReportProgress(0, fi.Name);
                            using (StreamReader sr = fi.OpenText())
                            {
                                string s = "";
                                while ((s = sr.ReadLine()) != null)
                                {
                                    if (s.Contains(TextToSearch))
                                    {
                                        counter++;
                                        findLines.Add(s);
                                    }
                                }
                            }
                        }
                    }
                }
                w.Close();
            }
            return findLines;
        }

        private bool CheckForAccess(string PathName)
        {
            // Determine if the path is a file or a directory

            if (File.Exists(PathName) == true)
                return CheckFileForAccess(PathName);

            if (Directory.Exists(PathName) == true)
                return CheckFolderForAccess(PathName);

            return false;
        }


        private bool CheckFileForAccess(string FileName)
        {
            FileSecurity fs = new FileSecurity(FileName, AccessControlSections.Access);
            if (fs == null)
                return false;

            AuthorizationRuleCollection TheseRules = fs.GetAccessRules(true, true, typeof(NTAccount));
            if (TheseRules == null)
                return false;

            return CheckACL(TheseRules);
        }

        private bool CheckFolderForAccess(string FolderName)
        {
            DirectoryInfo di = new DirectoryInfo(FolderName);
            if (di == null)
                return false;

            DirectorySecurity acl = di.GetAccessControl(AccessControlSections.Access);
            if (acl == null)
                return false;

            AuthorizationRuleCollection TheseRules = acl.GetAccessRules(true, true, typeof(NTAccount));
            if (TheseRules == null)
                return false;

            return CheckACL(TheseRules);
        }

        private bool CheckACL(AuthorizationRuleCollection TheseRules)
        {
            foreach (FileSystemAccessRule ThisRule in TheseRules)
            {
                if ((ThisRule.FileSystemRights & FileSystemRights.Read) == FileSystemRights.Read)
                {
                    if (ThisRule.AccessControlType == AccessControlType.Deny)
                        return false;
                }
                // Run as many other checks as you like
            }

            return true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            FindLines(@"d:\c-sharp", "string s1 = treeView1.SelectedNode.Tag as string;");
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            listView1.Items.Add(e.UserState.ToString());
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
    }
}

2 个答案:

答案 0 :(得分:0)

  

这是foreach所在的listView中的项目的屏幕截图   结束:我想要做的是显示添加到listView的项目   实时无需先等待操作,也可以   将每个项目添加到一行,如果一行太长,那么稍后我会   添加尖端气球或其他东西。但是现在listView看起来很像   混乱。

您是否尝试将Listview的视图属性设置为&#34; List&#34; ?这应该在各行显示文件名。

答案 1 :(得分:-1)

我认为你应该研究ObservableCollection(T)。当项目添加到项目时,集合会触发事件,UI元素应自动检测这些更改并更新视图。

至少这是它在WPF中的工作方式,但我认为它在WinForms中应该也能正常工作。