Listbox 上的 C# FileWatch 写入事件
C# FileWatch write event on Listbox
我有一个监视文件夹的 WPF 程序,我想在列表框中写下发生的每个事件。
我的问题是我有一个 class FileWatcher,但我无法将事件(创建、更改和删除)传递到列表框。
有人可以帮忙吗?
谢谢
主窗口
public MainWindow()
{
InitializeComponent();
string Location = string.Empty; //variavel que vai definir a localização da monitorização
}
private void btMon_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog browseFolder = new FolderBrowserDialog();
browseFolder.Description = "Selecione a pasta que deseja monitorizar. Todas as subpastas serão monitorizadas.";
if (browseFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Location = browseFolder.SelectedPath;
System.Windows.MessageBox.Show(Location);
}
} // Definição da localização que passa para o Filewatcher
private void btInMon_Click(object sender, RoutedEventArgs e)
{
monitoriza = new FileWatcher(Location);
} // Inicio da monitorização com a class FileWatcher
Class 文件观察器
public class FileWatcher
{
public MainWindow main;
private FileSystemWatcher _fileWatcher;
public FileWatcher(string Location)
{
_fileWatcher = new FileSystemWatcher(PathLocation(Location));
_fileWatcher.IncludeSubdirectories = true;
_fileWatcher.Created += new FileSystemEventHandler(_fileWatcher_Created);
_fileWatcher.EnableRaisingEvents = true;
}
private string PathLocation(string Location)
{
string value = String.Empty;
try
{
value = Location;
if (value != string.Empty)
{
return value;
}
}
catch (Exception ex)
{
//Implement logging on future version
}
return value;
}
void _fileWatcher_Created(object sender, FileSystemEventArgs e)
{
Logging.Log(String.Format("Evento criado por " + Environment.UserName + " Em " + DateTime.Now + " File Created: Patch:{0}, Name:{1}", e.FullPath, e.Name));
}
}
由于您正在实施 WPF 应用程序,因此请利用其数据绑定功能。也就是说,您不需要在 FileWatcher
class.
中引用 MainWindow
class
您需要的是 FileWatcher
class 中所有触发事件的字符串集合,它绑定到您的 ListBox。
在您的 MainWindow.xaml 中,添加以下行:
<ListBox Grid.Row="3" ItemsSource="{Binding FileWatcher.EventsFired}"/>
将您的 MainWindow.xaml.cs 更改为以下内容:
public partial class MainWindow : Window, INotifyPropertyChanged //Notify the UI when changes occur
{
private string _location;
private FileWatcher _fileWachter;
public FileWatcher FileWatcher
{
get
{
return _fileWachter;
}
set
{
// this makes your FileWatcher observable by the ui
_fileWachter = value;
OnPropertyChanged();
}
}
public string Location
{
get
{
return _location;
}
set
{
_location = value;
OnPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
Location = string.Empty; //variavel que vai definir a localização da monitorização
// DO NOT FORGET ABOUT THIS ONE
// REGISTER FOR NotifyPropertyChanged
DataContext = this;
}
private void btMon_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog browseFolder = new FolderBrowserDialog();
browseFolder.Description = "Selecione a pasta que deseja monitorizar. Todas as subpastas serão monitorizadas.";
if (browseFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Location = browseFolder.SelectedPath;
System.Windows.MessageBox.Show(Location);
}
} // Definição da localização que passa para o Filewatcher
private void btInMon_Click(object sender, RoutedEventArgs e)
{
FileWatcher = new FileWatcher(Location);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// it is good practice to check the handler for null before calling it
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
最后修改你的 FileWatcher
class:
public class FileWatcher : DispatcherObject, INotifyPropertyChanged //Dispatcher object is necessary to call the right dispatcher from the background thread
{
//collect all events from the filewatcher
public ObservableCollection<string> EventsFired
{
get
{
return _eventsFired;
}
set
{
_eventsFired = value;
OnPropertyChanged();
}
}
private FileSystemWatcher _fileWatcher;
private ObservableCollection<string> _eventsFired;
public FileWatcher(string Location)
{
//save all fired events
_eventsFired = new ObservableCollection<string>();
_fileWatcher = new FileSystemWatcher(PathLocation(Location));
_fileWatcher.IncludeSubdirectories = true;
_fileWatcher.Created += _fileWatcher_Created;
_fileWatcher.EnableRaisingEvents = true;
}
private string PathLocation(string Location)
{
string value = String.Empty;
try
{
value = Location;
if (value != string.Empty)
{
return value;
}
}
catch (Exception ex)
{
//Implement logging on future version
}
return value;
}
void _fileWatcher_Created(object sender, FileSystemEventArgs e)
{
//necessary to refresh collection from background thread
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
{
EventsFired.Add(String.Format("Evento criado por " + Environment.UserName + " Em " + DateTime.Now + " File Created: Patch:{0}, Name:{1}", e.FullPath, e.Name));
}));
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在 MainWindow.xaml 中,您告诉 ListBox 显示文件观察器触发的所有事件(现在只有您创建的文件)。这些保存在 ObservableCollection - 一个集合中,当对集合进行更改时通知 UI,例如添加或删除项目。
必须在 OnCreated 事件上调用 Dispatcher,因为该事件是从非 ui 线程触发的。您无法修改从后台线程绑定 ui 的集合。通过使用 Dispatcher.Invoke,您将新添加的字符串发送到主线程以刷新集合。
希望对您有所帮助!
我有一个监视文件夹的 WPF 程序,我想在列表框中写下发生的每个事件。
我的问题是我有一个 class FileWatcher,但我无法将事件(创建、更改和删除)传递到列表框。
有人可以帮忙吗?
谢谢
主窗口
public MainWindow()
{
InitializeComponent();
string Location = string.Empty; //variavel que vai definir a localização da monitorização
}
private void btMon_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog browseFolder = new FolderBrowserDialog();
browseFolder.Description = "Selecione a pasta que deseja monitorizar. Todas as subpastas serão monitorizadas.";
if (browseFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Location = browseFolder.SelectedPath;
System.Windows.MessageBox.Show(Location);
}
} // Definição da localização que passa para o Filewatcher
private void btInMon_Click(object sender, RoutedEventArgs e)
{
monitoriza = new FileWatcher(Location);
} // Inicio da monitorização com a class FileWatcher
Class 文件观察器
public class FileWatcher
{
public MainWindow main;
private FileSystemWatcher _fileWatcher;
public FileWatcher(string Location)
{
_fileWatcher = new FileSystemWatcher(PathLocation(Location));
_fileWatcher.IncludeSubdirectories = true;
_fileWatcher.Created += new FileSystemEventHandler(_fileWatcher_Created);
_fileWatcher.EnableRaisingEvents = true;
}
private string PathLocation(string Location)
{
string value = String.Empty;
try
{
value = Location;
if (value != string.Empty)
{
return value;
}
}
catch (Exception ex)
{
//Implement logging on future version
}
return value;
}
void _fileWatcher_Created(object sender, FileSystemEventArgs e)
{
Logging.Log(String.Format("Evento criado por " + Environment.UserName + " Em " + DateTime.Now + " File Created: Patch:{0}, Name:{1}", e.FullPath, e.Name));
}
}
由于您正在实施 WPF 应用程序,因此请利用其数据绑定功能。也就是说,您不需要在 FileWatcher
class.
MainWindow
class
您需要的是 FileWatcher
class 中所有触发事件的字符串集合,它绑定到您的 ListBox。
在您的 MainWindow.xaml 中,添加以下行:
<ListBox Grid.Row="3" ItemsSource="{Binding FileWatcher.EventsFired}"/>
将您的 MainWindow.xaml.cs 更改为以下内容:
public partial class MainWindow : Window, INotifyPropertyChanged //Notify the UI when changes occur
{
private string _location;
private FileWatcher _fileWachter;
public FileWatcher FileWatcher
{
get
{
return _fileWachter;
}
set
{
// this makes your FileWatcher observable by the ui
_fileWachter = value;
OnPropertyChanged();
}
}
public string Location
{
get
{
return _location;
}
set
{
_location = value;
OnPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
Location = string.Empty; //variavel que vai definir a localização da monitorização
// DO NOT FORGET ABOUT THIS ONE
// REGISTER FOR NotifyPropertyChanged
DataContext = this;
}
private void btMon_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog browseFolder = new FolderBrowserDialog();
browseFolder.Description = "Selecione a pasta que deseja monitorizar. Todas as subpastas serão monitorizadas.";
if (browseFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Location = browseFolder.SelectedPath;
System.Windows.MessageBox.Show(Location);
}
} // Definição da localização que passa para o Filewatcher
private void btInMon_Click(object sender, RoutedEventArgs e)
{
FileWatcher = new FileWatcher(Location);
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
// it is good practice to check the handler for null before calling it
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
最后修改你的 FileWatcher
class:
public class FileWatcher : DispatcherObject, INotifyPropertyChanged //Dispatcher object is necessary to call the right dispatcher from the background thread
{
//collect all events from the filewatcher
public ObservableCollection<string> EventsFired
{
get
{
return _eventsFired;
}
set
{
_eventsFired = value;
OnPropertyChanged();
}
}
private FileSystemWatcher _fileWatcher;
private ObservableCollection<string> _eventsFired;
public FileWatcher(string Location)
{
//save all fired events
_eventsFired = new ObservableCollection<string>();
_fileWatcher = new FileSystemWatcher(PathLocation(Location));
_fileWatcher.IncludeSubdirectories = true;
_fileWatcher.Created += _fileWatcher_Created;
_fileWatcher.EnableRaisingEvents = true;
}
private string PathLocation(string Location)
{
string value = String.Empty;
try
{
value = Location;
if (value != string.Empty)
{
return value;
}
}
catch (Exception ex)
{
//Implement logging on future version
}
return value;
}
void _fileWatcher_Created(object sender, FileSystemEventArgs e)
{
//necessary to refresh collection from background thread
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() =>
{
EventsFired.Add(String.Format("Evento criado por " + Environment.UserName + " Em " + DateTime.Now + " File Created: Patch:{0}, Name:{1}", e.FullPath, e.Name));
}));
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
在 MainWindow.xaml 中,您告诉 ListBox 显示文件观察器触发的所有事件(现在只有您创建的文件)。这些保存在 ObservableCollection - 一个集合中,当对集合进行更改时通知 UI,例如添加或删除项目。
必须在 OnCreated 事件上调用 Dispatcher,因为该事件是从非 ui 线程触发的。您无法修改从后台线程绑定 ui 的集合。通过使用 Dispatcher.Invoke,您将新添加的字符串发送到主线程以刷新集合。
希望对您有所帮助!