【问题标题】:Really Custom OpenFileDialog .NET真正自定义 OpenFileDialog .NET
【发布时间】:2013-10-03 16:41:40
【问题描述】:

我想在我的项目中有一个自定义的 OpenFileDialog 表单,我可以在其中添加/删除按钮并自定义我想要的任何东西,就像一个普通的表单一样。这主要是为了适合我使用的主题,另外,我可以添加自定义按钮。有没有关于如何构建自己的教程?是否有任何预先存在的项目可以直接从下载中使用?

【问题讨论】:

标签: c# .net vb.net savefiledialog


【解决方案1】:

如果您使用过 WinForms,很可能在某些时候您想扩展 OpenFileDialog 或 SaveFileDialog,但您放弃了,因为没有简单的方法可以做到这一点,请通过以下链接了解如何使用您自己的自定义... HERE

【讨论】:

  • 他不想扩展它。请在发布答案之前阅读 cmets
  • 仅供参考 - 今天(2018 年 4 月 4 日)尝试使用引用的 CodeProject“以简单的方式扩展 OpenFileDialog 和 SaveFileDialog”,但演示和源代码都不能在 Win 7 机器上正常工作。对话框显示正常,但额外的位显示不正确。我假设标准的打开文件对话框已经改变到无法进行自定义的地步
  • @DanielAbouChleih Thilina H 的解决方案有很多服装,我用过,效果很好,恕我直言,它比“100% 自定义”打开文件对话框更好。
  • @NovaSysEng 解决方案有效,尝试使用github.com/dmihailescu/CustomFileDialog 代替旧链接
【解决方案2】:

我希望这能满足您的要求:

您需要一个TreeView 和一个ImageList

代码

你需要System.Runtime.InteropServices;

以下代码从路径中获取关联图标:

    [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;
    }

使用以下方法获取所有驱动器(最好将其放在构造函数/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);
        }
    }

那么你需要一个用于Expand-Event的EventHandler,它将调用方法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);
        }
    }

最后我在 TreeView 中为 NodeDoubleClick-Event 创建了一个 EventHandler:

    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;
    }

【讨论】:

  • 谢谢,正是我想要的。我已经解决了我的问题,但无论如何我都会将其标记为答案;D
  • 谢谢 :) 也许它会帮助未来的访客
猜你喜欢
  • 2011-08-30
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多