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