WPF - File Browse With File Icon And Export To A File

This post is about how to make a File Browser in C# using ListView to contain the file name with icons.

Step 1

Click New Project, then select Visual C# on the left, then Windows and then select Windows Forms Application. Name your project "FileBrowser" and then click OK

WPF
 
Step 2

Design your file browser form as below.
  1. <Window  
  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" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="DocumentIconDemo.MainWindow"  
  5.         Title="MainWindow" Height="500" Width="1000">  
  6.     <Grid>  
  7.         <Grid.ColumnDefinitions>  
  8.             <ColumnDefinition Width="1000*"/>  
  9.             <ColumnDefinition Width="89*"/>  
  10.         </Grid.ColumnDefinitions>  
  11.         <Grid.RowDefinitions>  
  12.             <RowDefinition Height="31*"/>  
  13.             <RowDefinition Height="288*"/>  
  14.         </Grid.RowDefinitions>  
  15.         <Button Content="Folder..."  Grid.Column="1" Click="Button_Click"/>  
  16.         <ScrollViewer Grid.ColumnSpan="2" Grid.Row="1">  
  17.             <ListBox x:Name="lstBox" HorizontalContentAlignment="Stretch" Grid.ColumnSpan="2" Grid.Row="1"  ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionMode="Multiple" >  
  18.                 <ListBox.Template>  
  19.                     <ControlTemplate>  
  20.                         <DockPanel LastChildFill="True">  
  21.                             <Grid DockPanel.Dock="Top" Height="30">  
  22.                                 <Grid.ColumnDefinitions>  
  23.                                     <ColumnDefinition Width="25"/>  
  24.                                     <ColumnDefinition Width="*"/>  
  25.                                     <ColumnDefinition Width="*"/>  
  26.                                     <ColumnDefinition Width="*"/>  
  27.                                     <ColumnDefinition Width="*"/>  
  28.                                 </Grid.ColumnDefinitions>  
  29.   
  30.                                 <Label Grid.Column="1">Path</Label>  
  31.                                 <Label Grid.Column="2">Last Creation</Label>  
  32.                                 <Label Grid.Column="3">Last Access</Label>  
  33.                                 <Label Grid.Column="4">Last Modification</Label>  
  34.                             </Grid>  
  35.                             <ItemsPresenter></ItemsPresenter>  
  36.                         </DockPanel>  
  37.                     </ControlTemplate>  
  38.                 </ListBox.Template>  
  39.                 <ListBox.ItemTemplate>  
  40.                     <DataTemplate>  
  41.                         <Grid d:DesignWidth="372" d:DesignHeight="46" Margin="0,2">  
  42.                             <Grid.ColumnDefinitions>  
  43.                                 <ColumnDefinition Width="25"/>  
  44.                                 <ColumnDefinition Width="*"/>  
  45.                                 <ColumnDefinition Width="*"/>  
  46.                                 <ColumnDefinition Width="*"/>  
  47.                                 <ColumnDefinition Width="*"/>  
  48.                             </Grid.ColumnDefinitions>  
  49.                             <Image Source="{Binding ItemIcon}" />  
  50.                             <Label Content="{Binding ItemText, UpdateSourceTrigger=PropertyChanged,IsAsync=True}" Grid.Column="1"/>  
  51.                             <Label Content="{Binding LastCreation, UpdateSourceTrigger=PropertyChanged,IsAsync=True}" Grid.Column="2"/>  
  52.                             <Label Content="{Binding LastAccess, UpdateSourceTrigger=PropertyChanged,IsAsync=True}" Grid.Column="3"/>  
  53.                             <Label Content="{Binding LastModification, UpdateSourceTrigger=PropertyChanged,IsAsync=True}" Grid.Column="4"/>  
  54.                         </Grid>  
  55.                     </DataTemplate>  
  56.                 </ListBox.ItemTemplate>  
  57.             </ListBox>  
  58.         </ScrollViewer>  
  59.         <TextBlock x:Name="textField" TextWrapping="Wrap" Height="21"  Text="TextBlock"/>  
  60.     </Grid>  
  61. </Window>  

Step 3

Add code to handle your form.

  1. using System;  
  2. using System.Linq;  
  3. using System.Windows;  
  4. using System.Windows.Controls;  
  5. using System.Windows.Media.Imaging;  
  6. using System.IO;  
  7. using System.Threading;  
  8. using System.ComponentModel;  
  9. using System.Reflection;  
  10. using System.Collections.ObjectModel;  
  11.   
  12. namespace DocumentIconDemo  
  13. {  
  14.     /// <summary>  
  15.     /// Interaction logic for MainWindow.xaml  
  16.     /// </summary>  
  17.     public partial class MainWindow : Window, INotifyPropertyChanged  
  18.     {  
  19.         class ListBoxData : INotifyPropertyChanged  
  20.         {            
  21.             public event PropertyChangedEventHandler PropertyChanged;  
  22.             public void NotifyPropertyChanged(string txt)  
  23.             {  
  24.   
  25.                 if (PropertyChanged != null)  
  26.                 {  
  27.                     PropertyChanged(thisnew PropertyChangedEventArgs(txt));  
  28.                     PropertyChanged(thisnew PropertyChangedEventArgs("DisplayMember"));  
  29.                 }  
  30.             }  
  31.             public BitmapSource ItemIcon { getset; }  
  32.             private string itemtext;  
  33.             public string ItemText  
  34.             {  
  35.                 get { return itemtext; }  
  36.                 set  
  37.                 {  
  38.                     itemtext = value;  
  39.                     NotifyPropertyChanged("ItemText");  
  40.                 }  
  41.             }  
  42.             private string lastaccess;  
  43.             public string LastAccess {  
  44.                 get { return lastaccess; }  
  45.                 set  
  46.                 {  
  47.                     lastaccess = value;  
  48.                     NotifyPropertyChanged("LastAccess");  
  49.                 }  
  50.             }  
  51.             private string lastcreation;  
  52.             public string LastCreation {  
  53.                 get { return lastcreation; }  
  54.                 set  
  55.                 {  
  56.                     lastcreation = value;  
  57.                     NotifyPropertyChanged("LastCreation");  
  58.                 }  
  59.             }  
  60.             private string lastmodification;  
  61.             public string LastModification {  
  62.                 get { return lastmodification; }  
  63.                 set  
  64.                 {  
  65.                     lastmodification = value;  
  66.                     NotifyPropertyChanged("LastModification");  
  67.                 }  
  68.             }  
  69.         }  
  70.         ObservableCollection<ListBoxData> data = new ObservableCollection<ListBoxData>();  
  71.         public MainWindow()  
  72.         {  
  73.             InitializeComponent();  
  74.             Loaded += MainWindow_Loaded;  
  75.         }  
  76.   
  77.         void MainWindow_Loaded(object sender, RoutedEventArgs e)  
  78.         {  
  79.             textField.Text = "";  
  80.         }  
  81.         private Thread _thread; string[] dir; // List<ListBoxData> data;  
  82.         private void Button_Click(object sender, RoutedEventArgs e)  
  83.         {  
  84.             var dialog = new System.Windows.Forms.FolderBrowserDialog();  
  85.             System.Windows.Forms.DialogResult result = dialog.ShowDialog();  
  86.   
  87.             if (result == System.Windows.Forms.DialogResult.OK)  
  88.             {  
  89.                 textField.Text = dialog.SelectedPath;  
  90.   
  91.                 if (textField.Text == "")  
  92.                     return;  
  93.   
  94.                 dir = Directory.GetFiles(textField.Text, "*", SearchOption.AllDirectories);  
  95.                 _thread = new Thread(() => showSomePeople(lstBox));  
  96.                 _thread.Start();                  
  97.             }  
  98.             else  
  99.                 textField.Text = "";  
  100.         }  
  101.   
  102.         private async void showSomePeople(ListBox lstBox)  
  103.         {  
  104.             data = GenerateItems();  
  105.             await Dispatcher.BeginInvoke(new Action(delegate ()  
  106.             {  
  107.                 lstBox.ItemsSource = data;  
  108.             }));  
  109.         }  
  110.         public event PropertyChangedEventHandler PropertyChanged;  
  111.         private void NotifyPropertyChanged(string property)  
  112.         {  
  113.             if (PropertyChanged != null)  
  114.             {  
  115.                 PropertyChanged(thisnew PropertyChangedEventArgs(property));  
  116.             }  
  117.         }  
  118.         private ObservableCollection<ListBoxData> GenerateItems()  
  119.         {  
  120.            
  121.             foreach (var filePath in dir)  
  122.             {  
  123.                 var sysicon = System.Drawing.Icon.ExtractAssociatedIcon(filePath);  
  124.                 var bmpSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(  
  125.                             sysicon.Handle,  
  126.                             System.Windows.Int32Rect.Empty,  
  127.                             System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());  
  128.                 if (bmpSrc.CanFreeze)  
  129.                 {  
  130.                     bmpSrc.Freeze();  /*otherwise we get error - Must create DependencySource on same Thread as the DependencyObject*/
  131.                 }  
  132.                 sysicon.Dispose();  
  133.                 DateTime creation = File.GetCreationTime(filePath);  
  134.                 DateTime access = File.GetLastAccessTime(filePath);  
  135.                 DateTime writeT = File.GetLastWriteTime(filePath);  
  136.                 data.Add(new ListBoxData() { ItemIcon = bmpSrc, ItemText = filePath, LastCreation = creation.ToString(), LastAccess = access.ToString(), LastModification = writeT.ToString() });  
  137.   
  138.             }  
  139.             CreateCSVFromGenericList<ListBoxData>(data, "D:\\s.txt");  
  140.             return data;  
  141.         }  
  142.         public static void CreateCSVFromGenericList<T>(ObservableCollection<T> list, string csvCompletePath)  
  143.         {  
  144.             if (list == null || list.Count == 0) return;  
  145.   
  146.             //get type from 0th member  
  147.             Type t = list[0].GetType();  
  148.             string newLine = Environment.NewLine;  
  149.             if (!Directory.Exists(System.IO.Path.GetDirectoryName(csvCompletePath))) Directory.CreateDirectory(System.IO.Path.GetDirectoryName(csvCompletePath));  
  150.             if (!File.Exists(csvCompletePath)) File.Create(csvCompletePath).Close();  
  151.   
  152.             using (var sw = new StreamWriter(csvCompletePath))  
  153.             {  
  154.                 //make a new instance of the class name we figured out to get its props  
  155.                 object o = Activator.CreateInstance(t);  
  156.                 //gets all properties  
  157.                 PropertyInfo[] props = o.GetType().GetProperties();  
  158.                 //foreach of the properties in class above, write out properties  
  159.                 //this is the header row  
  160.                 sw.Write(string.Join(",", props.Where(d => d.Name != "ItemIcon").Select(d => d.Name).ToArray()) + newLine);  
  161.                 //this acts as datarow  
  162.                 foreach (T item in list)  
  163.                 {  
  164.                     //this acts as datacolumn  
  165.                     var row = string.Join("$", props.Where(d => d.Name != "ItemIcon").Select(d => item.GetType()  
  166.                                                                      .GetProperty(d.Name)  
  167.                                                                      .GetValue(item, null)  
  168.                                                                      .ToString())  
  169.                                                             .ToArray());  
  170.                     sw.Write(row + newLine);  
  171.                 }  
  172.             }  
  173.         }  
  174.     }