我有一個 WinForm 應用程式,它采用兩個 TreeView 的結構并將它們作為檔案夾實作到用戶在下拉選單中選擇的路徑中。
Drop Down 當前從 Z 獲取所有可選擇的檔案夾:
現在我的 TreeViewloremPath
有正確的驅動器 Z: 但ipsumPath
應該進入 R: 但具有相同的下拉 - 因為第二個驅動器具有與Z:完全相同的檔案夾結構所以而不是構建一個全新的下拉, 我只需要更改R:中的路徑,ipsumPath
并且可以為兩個 Treeview 使用一個 Drop Down。
所以我有一個關于 StackOverflow 的上一個問題,我被推薦為兩個 TreeViews 使用硬編碼路徑,但我不知道如何實作它。
我嘗試了類似的東西:
var testPath= new DirectoryInfo("R:\\").GetDirectories();
var treeSeperator = ipsumPath.PathSeparator;
var dirSep = Path.DirectorySeparatorChar.ToString();
foreach (var node in GetCheckedNodes(ipsumPath.Nodes))
{
var sPath = Path.Combine(testPath.ToString(), node.FullPath.Replace(treeSeperator, dirSep));
Directory.CreateDirectory(sPath);
}
但這根本不起作用。
我的整個代碼:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using IWshRuntimeLibrary;
using System.Reflection;
namespace Form1
{
public partial class Form1 : Form
{
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect,
int nTopRect,
int nRightRect,
int nBottomRect,
int nWidthEllipse,
int nHeightEllipse
);
public Form1()
{
InitializeComponent();
this.FormBorderStyle = FormBorderStyle.None;
Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width, Height, 20, 20));
foreach (TreeNode tn in loremPath.Nodes)
{
tn.Expand();
}
foreach (TreeNode tn in ipsumPath.Nodes)
{
tn.Expand();
}
ipsumDropDown.Items.AddRange(new[] { "R:\\", "Z:\\" });
loremDropDown.DataSource = new DirectoryInfo($"{ipsumDropDown.SelectedItem}").GetDirectories();
}
private void CreateShortcutToCurrentAssembly(string saveDir)
{
var testPath = loremDropDown.SelectedValue.ToString();
WshShell wshShell = new WshShell();
string fileName = testPath "\\" Application.ProductName ".lnk";
IWshShortcut shortcut = (IWshShortcut)wshShell.CreateShortcut(fileName);
shortcut.TargetPath = Application.ExecutablePath;
shortcut.Save();
}
private void close_Click(object sender, EventArgs e)
{
System.Windows.Forms.Application.Exit();
}
private void loremPath_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.Unknown) return;
foreach (TreeNode n in e.Node.Children())
n.Checked = e.Node.Checked;
foreach (TreeNode p in e.Node.Parents())
p.Checked = p.Nodes.OfType<TreeNode>().Any(n => n.Checked);
}
private IEnumerable<TreeNode> GetCheckedNodes(TreeNodeCollection nodeCol)
{
foreach (TreeNode node in nodeCol)
{
if (node.Checked ||
node.Nodes.Cast<TreeNode>().Any(n => n.Checked))
{
yield return node;
}
foreach (TreeNode childNode in GetCheckedNodes(node.Nodes))
{
if (childNode.Checked)
yield return childNode;
}
}
}
private void projektordnerGenerieren_Click(object sender, EventArgs e)
{
var destPath = loremDropDown.SelectedValue.ToString();
var treeSep = loremPath.PathSeparator;
var dirSep = Path.DirectorySeparatorChar.ToString();
foreach (var node in GetCheckedNodes(loremPath.Nodes))
{
var sPath = Path.Combine(destPath, node.FullPath.Replace(treeSep, dirSep));
Directory.CreateDirectory(sPath);
}
foreach (var node in GetCheckedNodes(ipsumPath.Nodes))
{
var sPath = Path.Combine(destPath, node.FullPath.Replace(treeSep, dirSep));
Directory.CreateDirectory(sPath);
}
string folder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
CreateShortcutToCurrentAssembly(folder);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.loremPath.SelectedNode = this.loremPath.Nodes[0];
this.ipsumPath.SelectedNode = this.ipsumPath.Nodes[0];
loremPath.SelectedNode.Text = textBox1.Text;
ipsumPath.SelectedNode.Text = textBox1.Text;
}
private void ipsumPath_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.Unknown) return;
foreach (TreeNode n in e.Node.Children())
n.Checked = e.Node.Checked;
foreach (TreeNode p in e.Node.Parents())
p.Checked = p.Nodes.OfType<TreeNode>().Any(n => n.Checked);
}
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool ReleaseCapture();
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
private void alleErweitern_Click(object sender, EventArgs e)
{
foreach (TreeNode tn in loremPath.Nodes)
{
tn.Expand();
}
foreach (TreeNode tn in ipsumPath.Nodes)
{
tn.Expand();
}
}
private void alleReduzieren_Click(object sender, EventArgs e)
{
foreach (TreeNode tn in loremPath.Nodes)
{
tn.Collapse();
}
foreach (TreeNode tn in ipsumPath.Nodes)
{
tn.Collapse();
}
}
private void minimize_Click(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Minimized;
}
}
static class TreeViewExtensions
{
public static IEnumerable<TreeNode> Children(this TreeNode node)
{
foreach (TreeNode n in node.Nodes)
{
yield return n;
foreach (TreeNode child in Children(n))
yield return child;
}
}
public static IEnumerable<TreeNode> Parents(this TreeNode node)
{
var p = node.Parent;
while (p != null)
{
yield return p;
p = p.Parent;
}
}
}
}
uj5u.com熱心網友回復:
您在這里嘗試解決的問題是鏡像TreeNode
檔案系統中檢查的分支并在目標目錄中創建類似的目錄結構。目標目錄可以位于特定驅動器之一中,例如R:
和Z:
。所以,讓我們分解一下。
目的地驅動器
首先,您需要在串列控制元件中列出目標驅動器,例如ComboBox
選擇一個。您可以通過該
另一方面,如果您有兩個TreeView
控制元件,并且需要同時在兩個不同的驅動器中創建目錄結構,并且兩個驅動器具有相同的目標目錄結構,那么您只需要更改驅動器...(忽略 cmbDrives在這種情況下)...
public Form1()
{
InitializeComponent();
// ...
loremDropDown.DisplayMember = "Name";
loremDropDown.ValueMember = "FullName";
loremDropDown.DataSource = new DirectoryInfo("F:\\").GetDirectories();
}
private void SomeButton_Click(object sender, EventArgs e)
{
var drive = "F:\\";
var selDir = loremDropDown.SelectedValue.ToString();
var destPath = selDir.Replace(Path.GetPathRoot(selDir), drive);
var treeSep = pathLorem.PathSeparator;
var dirSep = Path.DirectorySeparatorChar.ToString();
foreach (var node in GetCheckedNodes(pathLorem.Nodes))
{
var sPath = Path.Combine(destPath, node.FullPath.Replace(treeSep, dirSep));
Directory.CreateDirectory(sPath);
}
drive = "Z:\\";
destPath = selDir.Replace(Path.GetPathRoot(selDir), drive);
foreach (var node in GetCheckedNodes(ipsumPath.Nodes))
{
var sPath = Path.Combine(destPath, node.FullPath.Replace(treeSep, dirSep));
Directory.CreateDirectory(sPath);
}
}
此外,如果有可能pathLorem
并且ipsumPath
每個都可以在F:
或Z:
或其他地方輸出,那么您需要結合這里提到的兩個想法并添加兩個驅動器選擇器(例如ComboBox
)從它們中選擇每個驅動器的目標驅動器而不是硬-對它們進行編碼。或者,如果一次處理單個TreeView
是可以接受的,那么您只需要一個cmbDrives
組合框和兩個RadioButton
控制元件來相應地選擇pathLorem
或ipsumPath
控制元件來處理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/506799.html