2013-02-08 3 views
0

Я пытаюсь практиковать пример просмотра файлов. Поэтому основная идея - создать независимый поток, который контролирует любые события в наблюдаемой папке. Исходная программа основана на форме окна, и я пытаюсь преобразовать ее в работу фрейма 3.5, C# + WPF;Вызывать делегат() из другого CS-файла?

Функции делегата, что ответы на события, определенная в A.cs, и они выглядят как:

public class WatcherEx : IDisposable 
    { 
     #region Data Members 
     private bool   disposed = false; 
     private WatcherInfo watcherInfo = null; 
     private WatchersExList watchers = new WatchersExList(); 
     #endregion Data Members 

     #region Event Definitions 
     public event WatcherExEventHandler EventChangedAttribute  = delegate {}; 
     public event WatcherExEventHandler EventChangedCreationTime = delegate {}; 
     public event WatcherExEventHandler EventChangedDirectoryName = delegate {}; 
     public event WatcherExEventHandler EventChangedFileName  = delegate {}; 
     public event WatcherExEventHandler EventChangedLastAccess = delegate {}; 
     public event WatcherExEventHandler EventChangedLastWrite  = delegate {}; 
     public event WatcherExEventHandler EventChangedSecurity  = delegate {}; 
     public event WatcherExEventHandler EventChangedSize   = delegate {}; 
     public event WatcherExEventHandler EventCreated    = delegate {}; 
     public event WatcherExEventHandler EventDeleted    = delegate {}; 
     public event WatcherExEventHandler EventRenamed    = delegate {}; 
     public event WatcherExEventHandler EventError    = delegate {}; 
     public event WatcherExEventHandler EventDisposed    = delegate {}; 
     public event WatcherExEventHandler EventPathAvailability  = delegate {}; 
     #endregion Event Definitions 

     #region Constructors 
     //-------------------------------------------------------------------------------- 
     public WatcherEx(WatcherInfo info) 
     { 
      if (info == null) 
      { 
       throw new Exception("WatcherInfo object cannot be null"); 
      } 
      this.watcherInfo = info; 

      Initialize(); 
     } 
     #endregion Constructors 

     #region Dispose Methods 
     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Disposes all of the FileSystemWatcher objects, and disposes this object. 
     /// </summary> 
     public void Dispose() 
     { 
      Debug.WriteLine("WatcherEx.Dispose()"); 
      if (!this.disposed) 
      { 
       DisposeWatchers(); 
       this.disposed = true; 
       GC.Collect(); 
       GC.WaitForPendingFinalizers(); 
      } 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Disposes of all of our watchers (called from Dispose, or as a result of 
     /// loosing access to a folder) 
     /// </summary> 
     public void DisposeWatchers() 
     { 
      Debug.WriteLine("WatcherEx.DisposeWatchers()"); 
      for (int i = 0; i < this.watchers.Count; i++) 
      { 
       this.watchers[i].Dispose(); 
      } 
      this.watchers.Clear(); 
     } 
     #endregion Dispose Methods 

     #region Helper Methods 
     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Determines if the specified NotifyFilter item has been specified to be 
     /// handled by this object. 
     /// </summary> 
     /// <param name="filter"></param> 
     /// <returns></returns> 
     public bool HandleNotifyFilter(NotifyFilters filter) 
     { 
      return (((NotifyFilters)(this.watcherInfo.ChangesFilters & filter)) == filter); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Determines if the specified WatcherChangeType item has been specified to be 
     /// handled by this object. 
     /// </summary> 
     /// <param name="filter"></param> 
     /// <returns></returns> 
     public bool HandleWatchesFilter(WatcherChangeTypes filter) 
     { 
      return (((WatcherChangeTypes)(this.watcherInfo.WatchesFilters & filter)) == filter); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Initializes this oibject by creating all of the required internal 
     /// FileSystemWatcher objects necessary to mointor the folder/file for the 
     /// desired changes 
     /// </summary> 
     private void Initialize() 
     { 
      Debug.WriteLine("WatcherEx.Initialize()"); 
      // the buffer can be from 4 to 64 kbytes. Default is 8 
      this.watcherInfo.BufferKBytes = Math.Max(4, Math.Min(this.watcherInfo.BufferKBytes, 64)); 

      // create the main watcher (handles create/delete, rename, error, and dispose) 
      // can't pass a null enum type, so we just pass ta dummy one on the first call 
      CreateWatcher(false, this.watcherInfo.ChangesFilters); 
      // create a change watcher for each NotifyFilter item 
      CreateWatcher(true, NotifyFilters.Attributes); 
      CreateWatcher(true, NotifyFilters.CreationTime); 
      CreateWatcher(true, NotifyFilters.DirectoryName); 
      CreateWatcher(true, NotifyFilters.FileName); 
      CreateWatcher(true, NotifyFilters.LastAccess); 
      CreateWatcher(true, NotifyFilters.LastWrite); 
      CreateWatcher(true, NotifyFilters.Security); 
      CreateWatcher(true, NotifyFilters.Size); 

      Debug.WriteLine(string.Format("WatcherEx.Initialize() - {0} watchers created", this.watchers.Count)); 
     } 


     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Actually creates the necessary FileSystemWatcher objects, depending oin which 
     /// notify filters and change types the user specified. 
     /// </summary> 
     /// <param name="changeType"></param> 
     /// <param name="filter"></param> 
     private void CreateWatcher(bool changedWatcher, NotifyFilters filter) 
     { 
      Debug.WriteLine(string.Format("WatcherEx.CreateWatcher({0}, {1})", changedWatcher.ToString(), filter.ToString())); 

      FileSystemWatcherEx watcher = null; 
      int bufferSize = (int)this.watcherInfo.BufferKBytes * 1024; 
      // Each "Change" filter gets its own watcher so we can determine *what* 
      // actually changed. This will allow us to react only to the change events 
      // that we actually want. The reason I do this is because some programs 
      // fire TWO events for certain changes. For example, Notepad sends two 
      // events when a file is created. One for CreationTime, and one for 
      // Attributes. 
      if (changedWatcher) 
      { 
       // if we're not handling the currently specified filter, get out 
       if (HandleNotifyFilter(filter)) 
       { 
        watcher      = new FileSystemWatcherEx(this.watcherInfo.WatchPath); 
        watcher.IncludeSubdirectories = this.watcherInfo.IncludeSubFolders; 
        watcher.Filter    = this.watcherInfo.FileFilter; 
        watcher.NotifyFilter   = filter; 
        watcher.InternalBufferSize = bufferSize; 
        switch (filter) 
        { 
         case NotifyFilters.Attributes : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedAttribute); 
          break; 
         case NotifyFilters.CreationTime : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedCreationTime); 
          break; 
         case NotifyFilters.DirectoryName : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedDirectoryName); 
          break; 
         case NotifyFilters.FileName  : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedFileName); 
          break; 
         case NotifyFilters.LastAccess : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedLastAccess); 
          break; 
         case NotifyFilters.LastWrite  : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedLastWrite); 
          break; 
         case NotifyFilters.Security  : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedSecurity); 
          break; 
         case NotifyFilters.Size   : 
          watcher.Changed += new FileSystemEventHandler(watcher_ChangedSize); 
          break; 
        } 
       } 
      } 
      // All other FileSystemWatcher events are handled through a single "main" 
      // watcher. 
      else 
      { 
       if (HandleWatchesFilter(WatcherChangeTypes.Created) || 
        HandleWatchesFilter(WatcherChangeTypes.Deleted) || 
        HandleWatchesFilter(WatcherChangeTypes.Renamed) || 
        this.watcherInfo.WatchForError || 
        this.watcherInfo.WatchForDisposed) 
       { 
        watcher      = new FileSystemWatcherEx(this.watcherInfo.WatchPath, watcherInfo.MonitorPathInterval); 
        watcher.IncludeSubdirectories = this.watcherInfo.IncludeSubFolders; 
        watcher.Filter    = this.watcherInfo.FileFilter; 
        watcher.InternalBufferSize = bufferSize; 
       } 

       if (HandleWatchesFilter(WatcherChangeTypes.Created)) 
       { 
        watcher.Created += new FileSystemEventHandler(watcher_CreatedDeleted); 
       } 
       if (HandleWatchesFilter(WatcherChangeTypes.Deleted)) 
       { 
        watcher.Deleted += new FileSystemEventHandler(watcher_CreatedDeleted); 
       } 
       if (HandleWatchesFilter(WatcherChangeTypes.Renamed)) 
       { 
        watcher.Renamed += new RenamedEventHandler(watcher_Renamed); 
       } 
       if (watcherInfo.MonitorPathInterval > 0) 
       { 
        watcher.EventPathAvailability += new PathAvailabilityHandler(watcher_EventPathAvailability); 
       } 
      } 
      if (watcher != null) 
      { 
       if (this.watcherInfo.WatchForError) 
       { 
        watcher.Error += new ErrorEventHandler(watcher_Error); 
       } 
       if (this.watcherInfo.WatchForDisposed) 
       { 
        watcher.Disposed += new EventHandler(watcher_Disposed); 
       } 
       this.watchers.Add(watcher); 
      } 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Starts all of the internal FileSystemWatcher objects by setting their 
     /// EnableRaisingEvents property to true. 
     /// </summary> 
     public void Start() 
     { 
      Debug.WriteLine("WatcherEx.Start()"); 
      this.watchers[0].StartFolderMonitor(); 
      for (int i = 0; i < this.watchers.Count; i++) 
      { 
       this.watchers[i].EnableRaisingEvents = true; 
      } 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Stops all of the internal FileSystemWatcher objects by setting their 
     /// EnableRaisingEvents property to true. 
     /// </summary> 
     public void Stop() 
     { 
      Debug.WriteLine("WatcherEx.Stop()"); 
      this.watchers[0].StopFolderMonitor(); 
      for (int i = 0; i < this.watchers.Count; i++) 
      { 
       this.watchers[i].EnableRaisingEvents = false; 
      } 
     } 
     #endregion Helper Methods 

     #region Native Watcher Events 
     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring attribute changes is 
     /// triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedAttribute(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed Attribute"); 
      EventChangedAttribute(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.Attributes)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring creation time changes is 
     /// triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedCreationTime(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed CreationTime"); 
      EventChangedCreationTime(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.CreationTime)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring directory name changes is 
     /// triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedDirectoryName(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed DirectoryName"); 
      EventChangedDirectoryName(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.DirectoryName)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring file name changes is 
     /// triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedFileName(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed FileName"); 
      EventChangedFileName(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.FileName)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring last access date/time 
     /// changes is triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedLastAccess(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed LastAccess"); 
      EventChangedLastAccess(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.LastAccess)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring last write date/time 
     /// changes is triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedLastWrite(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed LastWrite"); 
      EventChangedLastWrite(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.LastWrite)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring security changes is 
     /// triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedSecurity(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed Security"); 
      EventChangedSecurity(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.Security)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the watcher responsible for monitoring size changes is 
     /// triggered. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_ChangedSize(object sender, FileSystemEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Changed Size"); 
      EventChangedSize(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem, NotifyFilters.Size)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when an internal watcher is disposed 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_Disposed(object sender, EventArgs e) 
     { 
      Debug.WriteLine("EVENT - Disposed"); 
      EventDisposed(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.StandardEvent)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the main watcher detects an error (the watcher that detected the 
     /// error is part of the event's arguments object) 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_Error(object sender, ErrorEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Error"); 
      EventError(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.Error)); 
     } 

     //-------------------------------------------------------------------------------- 
     /// <summary> 
     /// Fired when the main watcher detects a file rename. 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void watcher_Renamed(object sender, RenamedEventArgs e) 
     { 
      Debug.WriteLine("EVENT - Renamed"); 
      EventRenamed(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.Renamed)); 
     } 

     //-------------------------------------------------------------------------------- 
     private void watcher_CreatedDeleted(object sender, FileSystemEventArgs e) 
     { 
      switch (e.ChangeType) 
      { 
       case WatcherChangeTypes.Created : 
        Debug.WriteLine("EVENT - Created"); 
        EventCreated(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem)); 
        break; 
       case WatcherChangeTypes.Deleted : 
        Debug.WriteLine("EVENT - Changed Deleted"); 
        EventDeleted(this, new WatcherExEventArgs(sender as FileSystemWatcherEx, e, ArgumentType.FileSystem)); 
        break; 
      } 
     } 

...... 

В другом файле b.cs, основной пользовательский интерфейс, я пытаюсь вызвать эти функции отклика события определены в A.cs, используя что-то вроде этого:

void fileWatcher_EventCreated(object sender, WatcherExEventArgs e) 
     { 
      listView1.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, _fileWatcher.EventCreated()); 
    } 

Но я kép получаю ошибку, которая говорит _fileWatcher.EventCreated() может быть только на левой стороне + = или - = ...

Я пытался сделать все это в b.cs (CS файл пользовательского интерфейса), а что-то вроде этого:

void fileWatcher_EventDeleted(object sender, WatcherExEventArgs e) 
     { 
      Action EventDeleted = delegate() 
      { 
       _lvie.fileName = ((FileSystemEventArgs)(e.Arguments)).FullPath; 
       _lvie.fileEvent = "Deleted"; 
       _lvie.timeOfOccurance = DateTime.Now.ToString("HH:mm:ss.fff"); 
       listView1.Items.Add(_lvie); 
      }; 

      listView1.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, EventDeleted);    
     } 

но он не реагирует события изменения файла хорошо. Казалось, что он не выбрал какие-то события.

Мне просто интересно, как мне это сделать: В главном интерфейсе (A.cs), вызывающем функции ответа в фоновом потоке (B.cs)? Или я должен делать это другими способами? Любые предложения очень ценятся. Благодарю. Я очень новичок в CS, поэтому, пожалуйста, воздержитесь от моего невежества.

+0

Я пытался использовать –

ответ

2

Events может быть поднят только из класса, в котором они существуют.

класса B не может поднять событие, которое существует в классе А.

Ближайший обходной путь вы могли бы добиться того, чтобы создать новую функцию API внутри класса А, называется - например - «RaiseMyEvent», который поднимает вручную событие изнутри класса A; вызов этой функции из класса В.

public class A 
{ 
    public event EventHandler MyEvent = null; 

    public void RaiseMyEvent(EventArgs args) 
    { 
     var handler = MyEvent; 
     if(handler != null) 
     { 
      handler(this, args); 
     } 
    } 
} 

//Then, from inside class B: 
myInstanceOfA.RaiseMyEvent(); //This will cause A to raise its own event 
+0

ОК, так что означает, что я должен создать ряд функций делегата в А, который вызывает функцию B? Есть ли пример реализации? Очень простой поможет. Благодарю. –

+0

Обновлен с образцом кода. – BTownTKD

+0

Я использую что-то вроде: listView1.Dispatcher.Invoke (System.Windows.Threading.DispatcherPriority.Normal, EventDeleted); для вызова события, которое определяется вторым параметром «EventDeleted»; Я думаю, что это событие должно быть делегатом? Итак, как мне определить этот делегат в B? –

Смежные вопросы