问题
I want to have an custom OpenFileDialog form within my project where I can add/remove buttons and customize whatever I want like a normal form. This is mainly so that it fits into the theme I am using, additionally, I can add custom buttons. Is there any tutorials on how I could construct my own? Are there any pre-existing projects I can use straight out of the download?
回答1:
I hope that will fit your requirements:
You will need one TreeView and an ImageList
Code
You will need System.Runtime.InteropServices;
And following code to get the associated icon from the path:
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
class Win32
{
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath,
uint dwFileAttributes,
ref SHFILEINFO psfi,
uint cbSizeFileInfo,
uint uFlags);
}
private int GetIconOfFile_Folder(string Path)
{
IntPtr hImgSmall; //the handle to the system image list
IntPtr hImgLarge; //the handle to the system image list
string fName; // 'the file name to get icon from
SHFILEINFO shinfo = new SHFILEINFO();
//Use this to get the small Icon
hImgSmall = Win32.SHGetFileInfo(Path, 0, ref shinfo,
(uint)Marshal.SizeOf(shinfo),
Win32.SHGFI_ICON |
Win32.SHGFI_SMALLICON);
//Use this to get the large Icon
//hImgLarge = SHGetFileInfo(fName, 0,
//ref shinfo, (uint)Marshal.SizeOf(shinfo),
//Win32.SHGFI_ICON | Win32.SHGFI_LARGEICON);
//The icon is returned in the hIcon member of the shinfo
//struct
System.Drawing.Icon myIcon =
System.Drawing.Icon.FromHandle(shinfo.hIcon);
imageList1.Images.Add(myIcon);
return imageList1.Images.Count - 1;
}
Use following Method to Get all your Drives (best place it in your constructor/Form_Load):
private void GetAllDrives()
{
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (var drive in drives)
{
TreeNode rootTreeNode = new TreeNode();
rootTreeNode.Text = drive.Name;
rootTreeNode.Tag = drive.Name;
rootTreeNode.ImageIndex = GetIconOfFile_Folder(drive.Name);
rootTreeNode.SelectedImageIndex = rootTreeNode.ImageIndex;
rootTreeNode.Nodes.Add(" "); //Placeholder to enable expanding (+)
treeView1.Nodes.Add(rootTreeNode);
}
}
Then you will need an EventHandler for the Expand-Event, which will call the method GetFilesAndFolder()
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
e.Node.Nodes.Clear();
GetFilesAndFolder(e.Node, (string)e.Node.Tag);
}
private void GetFilesAndFolder(TreeNode tn, string Path)
{
try
{
string[] Directories = Directory.GetDirectories(Path);
string[] Files = Directory.GetFiles(Path);
foreach (string dir in Directories)
{
TreeNode dirTreeNode = new TreeNode();
dirTreeNode.Tag = dir;
dirTreeNode.Text = new DirectoryInfo(dir).Name;
dirTreeNode.ImageIndex = GetIconOfFile_Folder(dir);
dirTreeNode.SelectedImageIndex = dirTreeNode.ImageIndex;
dirTreeNode.Nodes.Add(" ");
tn.Nodes.Add(dirTreeNode);
}
foreach (string file in Files)
{
TreeNode fileTreeNode = new TreeNode();
fileTreeNode.Tag = file;
fileTreeNode.Text = new FileInfo(file).Name;
fileTreeNode.ImageIndex = GetIconOfFile_Folder(file);
fileTreeNode.SelectedImageIndex = fileTreeNode.ImageIndex;
tn.Nodes.Add(fileTreeNode);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
Finally I have created an EventHandler for the NodeDoubleClick-Event in the TreeView:
private void treeView1_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (CheckIfPathIsFile(e.Node.Tag.ToString()) == true) //If the Tag (Path) is a File
{
//Do something with the Path (close this Form + return Path)
}
}
private bool CheckIfPathIsFile(string Path)
{
// get the file attributes for file or directory
FileAttributes attr = File.GetAttributes(Path);
//detect whether its a directory or file
if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
return false;
else
return true;
}
回答2:
If you used WinForms, chances are that at some point you wanted to extend the OpenFileDialog or SaveFileDialog, but you gave up because there is no easy way to do it,Go with following link to get undestand how to custermize with your own... HERE
来源:https://stackoverflow.com/questions/19049822/really-custom-openfiledialog-net