WPF日積月累之檔案監測與DataGrid指定Row的顏色
阿新 • • 發佈:2018-11-02
一、概述
關於DataGrid指定Row的顏色,我們可以使用轉換器和DataGridRow的Style來實現。對於檔案的檢測,我們可以使用FileSystemWatcher來實現。
二、Demo
Converter程式碼如下:
1 using System; 2 using System.Windows.Data; 3 using System.Windows.Media; 4 5 namespace FileWatcher 6 { 7 public class BGConverter : IValueConverter 8 {View Code9 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 10 { 11 string operation = (string)value; 12 switch(operation) 13 { 14 case "Created": 15 return Brushes.Green;16 17 case "Deleted": 18 return Brushes.Red; 19 20 case "Renamed": 21 return Brushes.Orange; 22 default: 23 return Brushes.Black; 24 } 25 26 }27 28 public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 29 { 30 return null; 31 } 32 } 33 }
前臺程式碼如下:
1 <Window x:Class="FileWatcher.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:FileWatcher" 7 mc:Ignorable="d" 8 Title="FileWatcher" Height="434.877" Width="673.774" Background="#FF387BB6"> 9 <Grid> 10 <Grid.RowDefinitions> 11 <RowDefinition Height="30"/> 12 <RowDefinition Height="*"/> 13 </Grid.RowDefinitions> 14 <StackPanel Orientation="Horizontal" HorizontalAlignment="Right"> 15 <Label Content="資料夾路徑:" Foreground="#FF224664"></Label> 16 <TextBox Width="168" Margin="2 4 2 0" Name="tbxPath" Text="D:\MyTest\Test"></TextBox> 17 <Button Content="開始監聽" Margin="60 2 8 2" Click="Button_Click" Background="#FF2E76B6"/> 18 </StackPanel> 19 <DataGrid Grid.Row="1" Margin="5" ItemsSource="{Binding FileCollection}" AutoGenerateColumns="False" Name="dataGrid" CanUserAddRows="False"> 20 <DataGrid.Resources> 21 <local:BGConverter x:Key="bgconverter"/> 22 <Style TargetType="DataGridRow"> 23 <Setter Property="Foreground" Value="{Binding Path=Operation, Converter={StaticResource bgconverter}}"/> 24 </Style> 25 </DataGrid.Resources> 26 <DataGrid.Columns> 27 <DataGridTemplateColumn> 28 <DataGridTemplateColumn.CellTemplate> 29 <DataTemplate> 30 <CheckBox x:Name="cbCheck" HorizontalAlignment="Center" 31 IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 32 Margin="3,2,0,0" Background="#07638a"/> 33 </DataTemplate> 34 </DataGridTemplateColumn.CellTemplate> 35 <DataGridTemplateColumn.Header> 36 <CheckBox x:Name="CheckAll" Width="auto" Content="All" Foreground="#F33A98E7" HorizontalAlignment="Center" 37 Background="Red" Margin="20 0 0 0" 38 IsChecked="{Binding DataContext.IsAllChecked, Mode=TwoWay, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGrid}, UpdateSourceTrigger=PropertyChanged}"/> 39 40 </DataGridTemplateColumn.Header> 41 </DataGridTemplateColumn> 42 <DataGridTextColumn Width="100" Header="File" Binding="{Binding FileName}" IsReadOnly="True"/> 43 <DataGridTextColumn Header="Path" Width="120" Binding="{Binding FilePath}" IsReadOnly="True"/> 44 <DataGridTextColumn Header="Operation" Width="100" Binding="{Binding Operation}" IsReadOnly="True"/> 45 <DataGridTextColumn Header="Date" Width="120" Binding="{Binding Date}" IsReadOnly="True"/> 46 <DataGridTextColumn Header="Note" Width="150" Binding="{Binding Note}" IsReadOnly="False"/> 47 48 49 </DataGrid.Columns> 50 </DataGrid> 51 </Grid> 52 </Window>View Code
後臺程式碼如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Collections.ObjectModel; 4 using System.ComponentModel; 5 using System.IO; 6 using System.Linq; 7 using System.Windows; 8 9 namespace FileWatcher 10 { 11 public abstract class ViewModelBase : INotifyPropertyChanged 12 { 13 public virtual string DisplayName { get; set; } 14 15 public event PropertyChangedEventHandler PropertyChanged; 16 17 protected void OnPropertyChanged(string propertyName) 18 { 19 PropertyChangedEventHandler handler = PropertyChanged; 20 21 if (handler != null) 22 { 23 handler(this, new PropertyChangedEventArgs(propertyName)); 24 } 25 } 26 27 } 28 /// <summary> 29 /// Interaction logic for MainWindow.xaml 30 /// </summary> 31 public partial class MainWindow : Window, INotifyPropertyChanged 32 { 33 public event PropertyChangedEventHandler PropertyChanged; 34 35 protected void OnPropertyChanged(string propertyName) 36 { 37 PropertyChangedEventHandler handler = PropertyChanged; 38 39 if (handler != null) 40 { 41 handler(this, new PropertyChangedEventArgs(propertyName)); 42 } 43 } 44 private List<string> fileList = new List<string>(); 45 private ObservableCollection<FileInfo> fileCollection = new ObservableCollection<FileInfo>(); 46 public ObservableCollection<FileInfo> FileCollection 47 { 48 get { return fileCollection; } 49 set 50 { 51 fileCollection = value; 52 OnPropertyChanged("FileCollection"); 53 } 54 } 55 private bool isAllChecked; 56 public bool IsAllChecked 57 { 58 get { return isAllChecked; } 59 set 60 { 61 isAllChecked = value; 62 OnPropertyChanged("IsAllChecked"); 63 64 for (int i = 0; i < FileCollection.Count; i++) 65 { 66 FileCollection[i].IsChecked = isAllChecked; 67 } 68 //OnPropertyChanged("FilaCalibrationProtocols"); 69 } 70 } 71 FileSystemWatcher fsw = new FileSystemWatcher(); 72 public MainWindow() 73 { 74 InitializeComponent(); 75 dataGrid.DataContext = this; 76 fsw.Path = @"C:\"; //設定監控的檔案目錄 77 fsw.Filter = "*.*"; //設定監控檔案的型別 78 fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.Size; //設定檔案的檔名、目錄名及檔案的大小改動會觸發Changed事件 79 80 fsw.Created += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle); //繫結事件觸發後處理資料的方法。 81 82 fsw.Deleted += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle); 83 84 fsw.Changed += new FileSystemEventHandler(this.fileSystemWatcher_EventHandle); 85 86 fsw.Renamed += new RenamedEventHandler(this.fileSystemWatcher_Renamed); //重新命名事件與增刪改傳遞的引數不一樣。 87 88 } 89 private void fileSystemWatcher_EventHandle(object sender, FileSystemEventArgs e) //檔案增刪改時被呼叫的處理方法 90 { 91 this.Dispatcher.BeginInvoke( 92 new Action(() => 93 { 94 95 var fileInfo = new FileInfo() { Operation = e.ChangeType.ToString(), Date = DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss"), FileName = e.Name, FilePath = e.FullPath, IsChecked = false }; 96 97 if(e.ChangeType.ToString() == "Created") 98 { 99 var fileName = from file in fileList.Distinct() 100 where file == e.Name 101 select file; 102 if (fileName.Count() > 0) 103 { 104 fileInfo.Note = $"{e.Name} have already been {e.ChangeType} before."; 105 MessageBox.Show($"{e.Name} have already been {e.ChangeType} before."); 106 } 107 } 108 109 fileCollection.Add(fileInfo); 110 111 fileList.Add(e.Name); 112 }) 113 ); 114 115 } 116 private void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e) //檔案重新命名時被呼叫的處理方法 117 { 118 this.Dispatcher.BeginInvoke( 119 new Action(() => 120 { 121 fileCollection.Add(new FileInfo() { Operation = e.ChangeType.ToString(), Date = DateTime.Now.ToLongTimeString(), FileName = e.OldName + " --> " + e.Name, FilePath = e.FullPath, IsChecked = false }); 122 fileList.Add(e.Name); 123 }) 124 ); 125 126 } 127 128 private void Button_Click(object sender, RoutedEventArgs e) 129 { 130 if(Directory.Exists(tbxPath.Text)) 131 { 132 fsw.Path = tbxPath.Text; 133 } 134 fsw.EnableRaisingEvents = true; 135 } 136 } 137 public class FileInfo : ViewModelBase 138 { 139 private bool isChecked; 140 141 public bool IsChecked 142 { get { return isChecked; } set { isChecked = value; OnPropertyChanged("IsChecked"); } } 143 144 145 private string fileName; 146 public string FileName 147 { 148 get { return fileName; } 149 set { fileName = value; } 150 } 151 152 private string filePath; 153 public string FilePath 154 { 155 get { return filePath; } 156 set { filePath = value; } 157 } 158 159 private string operation; 160 public string Operation 161 { 162 get { return operation; } 163 set { operation = value; } 164 } 165 166 private string date; 167 public string Date 168 { 169 get { return date; } 170 set { date = value; } 171 } 172 173 private string note; 174 public string Note 175 { 176 get { return note; } 177 set { note = value; } 178 } 179 180 } 181 }View Code
執行結果如下: