// Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // Copyright (c) 2006 Alexander Olk // // Authors: // Alexander Olk (alex.olk@googlemail.com) // Gert Driesen (drieseng@users.sourceforge.net) // // // changed (simplified) by Alexander Tsyganenko using System.ComponentModel; using System.IO; namespace System.Windows.Forms { public sealed class FolderBrowserDialog : CommonDialog { #region Local Variables private Label descriptionLabel; private Button cancelButton; private Button okButton; private FolderBrowserTreeView folderBrowserTreeView; private string selectedPath = string.Empty; #endregion // Local Variables #region Public Constructors public FolderBrowserDialog() { form = new DialogForm(this); folderBrowserTreeView = new FolderBrowserTreeView(this); okButton = new Button(); cancelButton = new Button(); descriptionLabel = new Label(); form.AcceptButton = okButton; form.CancelButton = cancelButton; form.SuspendLayout(); form.ClientSize = new Drawing.Size(422, 424); form.Text = "Browse For Folder"; // descriptionLabel descriptionLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; descriptionLabel.Location = new Drawing.Point(15, 14); descriptionLabel.Size = new Drawing.Size(392, 40); descriptionLabel.Text = string.Empty; // folderBrowserTreeView folderBrowserTreeView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; folderBrowserTreeView.Location = new Drawing.Point(15, 60); folderBrowserTreeView.Size = new Drawing.Size(392, 312); // okButton okButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; okButton.Location = new Drawing.Point(253, 385); okButton.Size = new Drawing.Size(75, 23); okButton.TabIndex = 1; okButton.Text = "OK"; // cancelButton cancelButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; cancelButton.DialogResult = DialogResult.Cancel; cancelButton.Location = new Drawing.Point(333, 385); cancelButton.Size = new Drawing.Size(75, 23); cancelButton.Text = "Cancel"; form.Controls.Add(cancelButton); form.Controls.Add(okButton); form.Controls.Add(folderBrowserTreeView); form.Controls.Add(descriptionLabel); form.ResumeLayout(false); okButton.Click += new EventHandler(OnClickOKButton); cancelButton.Click += new EventHandler(OnClickCancelButton); form.VisibleChanged += new EventHandler(OnFormVisibleChanged); form.MinimumSize = new Drawing.Size((int)(310 * form.DpiScale), (int)(254 * form.DpiScale)); } #endregion // Public Constructors #region Public Instance Properties [Browsable(true)] [DefaultValue("")] [Localizable(true)] public string Description { set { descriptionLabel.Text = value; } get { return descriptionLabel.Text; } } [Browsable(true)] [DefaultValue("")] [Localizable(true)] public string SelectedPath { set { if (value == null) value = string.Empty; selectedPath = value; } get { return selectedPath; } } public bool ShowNewFolderButton { get; set; } // not implemented #endregion // Public Instance Properties #region Public Instance Methods public override void Reset() { Description = string.Empty; selectedPath = string.Empty; } protected override bool RunDialog() { folderBrowserTreeView.SelectedPath = SelectedPath; return true; } #endregion // Public Instance Methods #region Internal Methods void OnClickOKButton(object sender, EventArgs e) { selectedPath = folderBrowserTreeView.SelectedPath; form.DialogResult = DialogResult.OK; } void OnClickCancelButton(object sender, EventArgs e) { form.DialogResult = DialogResult.Cancel; } void OnFormVisibleChanged(object sender, EventArgs e) { folderBrowserTreeView.Focus(); } #endregion // Internal Methods #region Events #endregion internal class FolderBrowserTreeView : TreeView { private FolderBrowserDialog parentDialog; private ImageList imageList = new ImageList(); private string selectedPath; public string SelectedPath { get => selectedPath; set => FindPath(value); } public FolderBrowserTreeView(FolderBrowserDialog parent_dialog) { parentDialog = parent_dialog; HideSelection = false; ImageList = imageList; SetupImageList(); PopulateTree(); } private void SetupImageList() { imageList.ColorDepth = ColorDepth.Depth32Bit; imageList.ImageSize = new Drawing.Size((int)(16 * DpiScale), (int)(16 * DpiScale)); imageList.Images.Add(ResourceLoader.GetBitmap("folder.png")); } private void PopulateTree() { foreach (var drive in Directory.GetLogicalDrives()) { var node = this.Nodes.Add(drive); node.Tag = drive; node.Nodes.Add("?"); } } private void FindPath(string path) { if (string.IsNullOrEmpty(path)) path = Directory.GetCurrentDirectory(); FindPath(path, this.Nodes); } private void FindPath(string path, TreeNodeCollection nodes) { foreach (TreeNode node in nodes) { var nodePath = node.Tag.ToString(); if (path.StartsWith(nodePath, StringComparison.CurrentCultureIgnoreCase)) { node.Expand(); this.SelectedNode = node; FindPath(path, node.Nodes); } } } private void PopulateTree(string path, TreeNode rootNode) { rootNode.Nodes.Clear(); foreach (var folder in Directory.GetDirectories(path)) { var info = new DirectoryInfo(folder); if ((info.Attributes & FileAttributes.Hidden) != 0) continue; var node = rootNode.Nodes.Add(info.Name); node.Tag = folder; node.Nodes.Add("?"); } } protected override void OnBeforeExpand(TreeViewCancelEventArgs e) { base.OnBeforeExpand(e); var node = e.Node; if (node.Nodes.Count == 1 && node.Nodes[0].Text == "?") { PopulateTree(node.Tag.ToString(), node); } } protected override void OnAfterSelect(TreeViewEventArgs e) { base.OnAfterSelect(e); var node = e.Node; if (node == null) { parentDialog.okButton.Enabled = false; } else { parentDialog.okButton.Enabled = true; selectedPath = node.Tag.ToString(); } } } } }