为什么这个C ++ / CLI代码没有将文件添加到列表框中

时间:2013-04-02 23:17:33

标签: winforms file listbox c++-cli

我有这个c ++代码,可以检测文件在目录中被修改的时间,并将文件名添加到列表框中。

这是文件观察者部分,它位于启动监控过程的按钮内

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
    array<String^>^ args = Environment::GetCommandLineArgs();

    FileSystemWatcher^ fsWatcher = gcnew FileSystemWatcher( );
    fsWatcher->Path = "C:\\users\\patchvista2";
    fsWatcher->IncludeSubdirectories = true;
    fsWatcher->NotifyFilter = static_cast<NotifyFilters> 
              (NotifyFilters::FileName | 
               NotifyFilters::Attributes | 
               NotifyFilters::LastAccess | 
               NotifyFilters::LastWrite | 
               NotifyFilters::Security | 
               NotifyFilters::Size );

    Form1^ handler = gcnew Form1(); 
    fsWatcher->Changed += gcnew FileSystemEventHandler(handler, &Form1::OnChanged);
    fsWatcher->Created += gcnew FileSystemEventHandler(handler, &Form1::OnChanged);

    fsWatcher->EnableRaisingEvents = true;
}

然后对于onchange部分我有这个代码

void OnChanged (Object^ source, FileSystemEventArgs^ e)
{
    // Here is the problem
    MessageBox::Show(e->FullPath);
    listBox1->Items->Add(e->FullPath);
    // End problem

    System::Security::Cryptography::MD5 ^ md5offile = MD5CryptoServiceProvider::Create();
    array<Byte>^ hashValue;
    FileStream^ fs = File::Open(e->FullPath, IO::FileMode::Open, IO::FileAccess::Read, IO::FileShare::ReadWrite);
    fs->Position = 0;
    hashValue = md5offile->ComputeHash(fs);
    PrintByteArray(hashValue);
    fs->Close();
    Application::DoEvents();
}

它会向我发送文件名,但不会将其添加到列表框中。我试着让它将文件名显示为标签,但这也不起作用。一旦启动此代码循环,似乎屏幕不会刷新。我在vb.net中有这个代码,它确实将文件名添加到列表框中。有人可以告诉我为什么文件名没有被添加到列表框中。

1 个答案:

答案 0 :(得分:1)

两件事:

  1. 您需要保持FileSystemWatcher的活动状态。你现在得到它可能会被垃圾收集。 (创建一个类字段并将其粘贴在那里。)
  2. 每当您对UI组件执行任何操作时,都需要Invoke到UI线程。
  3. 这是#2的近似语法(我现在远离编译器,这可能不准确。)

    void Form1::AddToListBox(String^ filename)
    {
        listBox1->Items->Add(filename);
    }
    
    void Form1::OnChanged(Object^ source, FileSystemEventArgs^ e)
    {
        Action<String^>^ addDelegate = gcnew Action<String^>(this, &Form1::AddToListBox);
        this->Invoke(addDelegate, e->FullPath);
        ...
    }