これまでリストビューのViewプロパティは View.Detailsを使用してきました。画像ファイルであればどのような画像なのかわかるようにアイコンで表示させます。またアイコンの大きさも自由に変更できるようにします。
以下はアイコンの大きさを指定するためのダイアログです。イメージリストに設定できるサイズが256ピクセルまでなのでNumericUpDownの最大値を256にしています。最小値は1以上であればよいのですが、あまり小さいとよくわからないので16ピクセルにしています。
[確定]がクリックされたら設定している値がフィールド変数に格納されます。これをつかってアイコンの大きさを変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public partial class FormIconSize : Form { public FormIconSize() { InitializeComponent(); numericUpDown1.Minimum = 16; numericUpDown1.Maximum = 256; buttonOK.DialogResult = DialogResult.OK; buttonOK.Click += ButtonOK_Click; } public int IconSize = 0; private void FormIconSize_Load(object sender, EventArgs e) { if(IconSize < numericUpDown1.Minimum) numericUpDown1.Value = numericUpDown1.Minimum; else numericUpDown1.Value = IconSize; } private void ButtonOK_Click(object sender, EventArgs e) { IconSize = (int)numericUpDown1.Value; if(IconSize > numericUpDown1.Maximum) IconSize = (int)numericUpDown1.Maximum; } } |
アイコンの大きさを設定するダイアログが[確定]で閉じられたら、その値を取得してIconSizeプロパティを設定します。メニューから32×32ピクセル、64×64ピクセル、128×128ピクセルが選択できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public partial class Form1 : Form { private void MenuItemIconFreeSize_Click(object sender, EventArgs e) { FormIconSize f = new FormIconSize(); f.IconSize = IconSize; if(f.ShowDialog() == DialogResult.OK) IconSize = f.IconSize; f.Dispose(); } private void MenuItemDetails_Click(object sender, EventArgs e) { IconSize = -1; } private void MenuItemIcon32_Click(object sender, EventArgs e) { IconSize = 32; } private void MenuItemIcon64_Click(object sender, EventArgs e) { IconSize = 64; } private void MenuItemIcon128_Click(object sender, EventArgs e) { IconSize = 128; } } |
IconSizeプロパティが変更されたらリストビューの表示を変更します。現在選択されているフォルダが存在することを確認したら、自作メソッドShowItems(string folderPath)で表示内容を変更します。
自作メソッドのGetFileImage(string path)は、ファイルがイメージファイルの場合はそのビットマップイメージを、それ以外のファイルの場合はアプリケーションと関連づけられたファイルのアイコンからビットマップイメージを取得するためのものです。
ShowItems(string folderPath)メソッドを使えば、MoveRootFolder(string driveName)メソッドと MoveToFolder(string path)メソッドもシンプルになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
public partial class Form1 : Form { int _iconSize = -1; int IconSize { get { return _iconSize; } set { _iconSize = value; if(MoveRootIfNotExistCurFolder()) return; ShowItems(CurFolderPath); } } private void ShowItems(string folderPath) { if(IconSize == -1) listView1.View = View.Details; else listView1.View = View.LargeIcon; DirectoryInfo info = new DirectoryInfo(folderPath); DirectoryInfo[] ds = null; FileInfo[] fs = null; try { ds = info.GetDirectories(); fs = info.GetFiles(); ds = ds.OrderBy(x => x.Name).ToArray(); fs = fs.OrderBy(x => x.Name).ToArray(); } catch { MessageBox.Show("アクセスを拒否されました!", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // 不要になったイメージリストとイメージは破棄する if(listView1.LargeImageList != null) { ImageList list = listView1.LargeImageList; foreach(Image image in list.Images) image.Dispose(); list.Dispose(); listView1.LargeImageList = null; } ImageList imageList = new ImageList(); listView1.LargeImageList = imageList; listView1.SmallImageList = imageList; if(listView1.View == View.Details) imageList.ImageSize = new Size(16, 16); else imageList.ImageSize = new Size(IconSize, IconSize); imageList.ColorDepth = ColorDepth.Depth32Bit; CurFolderPath = info.FullName; SelectedPath = ""; listView1.Items.Clear(); listView1.BeginUpdate(); int imageIndex = 0; foreach(DirectoryInfo dirInfo in ds) { string fullName = dirInfo.FullName; if( fullName.ToLower().EndsWith(":\\system volume information") || fullName.ToLower().EndsWith(":\\$recycle.bin") ) continue; ListViewItem item = new ListViewItem(new string[] { dirInfo.Name, "フォルダ", dirInfo.CreationTime.ToString(), dirInfo.LastWriteTime.ToString(), "", // フォルダなのでサイズはない GetCommentFromPath(dirInfo.FullName) }); listView1.Items.Add(item); Image image = GetFolderImage(); imageList.Images.Add(image); item.ImageIndex = imageIndex; imageIndex++; } foreach(var fileInfo in fs) { ListViewItem item = new ListViewItem(new string[] { fileInfo.Name, "ファイル", fileInfo.CreationTime.ToString(), fileInfo.LastWriteTime.ToString(), (fileInfo.Length/1024 +1).ToString(), GetCommentFromPath(fileInfo.FullName) }); listView1.Items.Add(item); Bitmap bitmap = GetFileImage(fileInfo.FullName); imageList.Images.Add(bitmap); item.ImageIndex = imageIndex; imageIndex++; } listView1.EndUpdate(); } void MoveRootFolder(string driveName) { DriveInfo driveInfo = new DriveInfo(driveName); ShowItems(driveInfo.RootDirectory.FullName); } void MoveToFolder(string path) { ShowItems(path); } } |
ファイルがイメージファイルの場合はそのビットマップイメージを、それ以外のファイルの場合はアプリケーションと関連づけられたファイルのアイコンからビットマップイメージを取得するGetFileImage(string path)メソッドを示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { Bitmap GetFileImage(string path) { try { Image image = Image.FromFile(path); Bitmap bitmap = new Bitmap(image); image.Dispose(); return bitmap; } catch { Icon icon = Icon.ExtractAssociatedIcon(path); Bitmap bitmap = icon.ToBitmap(); icon.Dispose(); return bitmap; } } } |
フォルダを表示するためのビットマップデータを取得するためのGetFolderImage()メソッドを示します。ファイルアイコンを取得するためにAPI関数 SHGetFileInfo関数を使用しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public partial class Form1 : Form { Image GetFolderImage() { SHFILEINFO shinfo = new SHFILEINFO(); IntPtr hSuccess = SHGetFileInfo("", 0, ref shinfo, (uint)System.Runtime.InteropServices.Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_LARGEICON); if(hSuccess != IntPtr.Zero) { Icon appIcon = Icon.FromHandle(shinfo.hIcon); return appIcon.ToBitmap(); } return null; } // SHGetFileInfo関数 [System.Runtime.InteropServices.DllImport("shell32.dll")] private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); // SHGetFileInfo関数で使用する構造体 private struct SHFILEINFO { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; // SHGetFileInfo関数で使用するフラグ private const uint SHGFI_ICON = 0x100; // アイコン・リソースの取得 private const uint SHGFI_LARGEICON = 0x0; // 大きいアイコン private const uint SHGFI_SMALLICON = 0x1; // 小さいアイコン } |