using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows.Controls; using System.Xml; using Aitex.Core.UI.View.Common; using Caliburn.Micro.Core; namespace MECF.Framework.UI.Client.CenterViews.Editors.Sequence { public class FileNode : PropertyChangedBase { #region Variables private string _name = string.Empty; #endregion #region Constructors public FileNode() { this.Files = new ObservableCollection(); this.IsFile = false; } #endregion #region Properties public string Name { get { return _name; } set { _name = value; NotifyOfPropertyChange("Name"); } } public string FullPath { get; set; } public FileNode Parent { get; set; } public ObservableCollection Files { get; set; } public bool IsFile { get; set; } public string PrefixPath { get; set; } public bool IsSelected { get; set; } public bool IsExpanded { get; set; } #endregion #region Methods /// /// 将数中的节点转换为节点数组。 /// /// 是否仅枚举最末端节点。 /// 更新子节点的Selected属性时,需要同时更新中间节点的属性;更新父节点时,只评估终端节点的Selected属性。 /// private List Flatten(bool terminalOnly) { if (Files == null || Files.Count <= 0) return new List(new[] { this }); var lst = Files.SelectMany(x => x.Flatten(terminalOnly)).ToList(); if (!terminalOnly) lst.Add(this); return lst; } /// /// 选择指定的节点。 /// /// public void Select(string fullPath) { var flattenList = Flatten(true); flattenList.ForEach(x => { x.IsSelected = x.FullPath == fullPath; }); Refresh(); } #endregion } public class RecipeSequenceTreeBuilder { public static List GetFiles(string prefixPath, List filenames) { List folders = new List(); FileNode root = new FileNode() { Name = "Files", IsFile = false, FullPath = "", PrefixPath = prefixPath }; folders.Add(root); foreach (string filename in filenames) { string[] filesplits = filename.Split('\\'); FileNode parent = root; if (filesplits.Length > 1) { for (var index = 0; index < filesplits.Length - 1; index++) { bool found = false; for (var j = 0; j < parent.Files.Count; j++) { if (parent.Files[j].Name == filesplits[index] && !parent.Files[j].IsFile) { found = true; parent = parent.Files[j]; break; } } if (!found) { FileNode folder = new FileNode() { Name = filesplits[index], IsFile = false, PrefixPath = prefixPath }; folder.FullPath = (parent.FullPath == string.Empty ? filesplits[index] : parent.FullPath + "\\" + filesplits[index]); folder.Parent = parent; parent.Files.Add(folder); parent = folder; } } } FileNode file = new FileNode() { Name = filesplits[filesplits.Length - 1], IsFile = true, PrefixPath = prefixPath }; file.FullPath = (parent.FullPath == string.Empty ? filesplits[filesplits.Length - 1] : parent.FullPath + "\\" + filesplits[filesplits.Length - 1]); file.Parent = parent; parent.Files.Add(file); } return folders; } public static void CreateTreeViewItems(XmlElement curElementNode, FileNode parent, string prefixPath, string selectionName, bool selectionIsFolder, bool isFolderNodeOnly) { foreach (XmlElement ele in curElementNode.ChildNodes) { if (ele.Name == "File" && !isFolderNodeOnly) { var fileName = ele.Attributes["Name"].Value; fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1); var fullPath = string.IsNullOrEmpty(parent.FullPath) ? fileName : parent.FullPath + "\\" + fileName; var file = new FileNode() { Name = fileName, IsFile = true, PrefixPath = prefixPath, Parent = parent, FullPath = fullPath, }; if (!selectionIsFolder && selectionName == file.FullPath) { file.IsSelected = true; var node = file.Parent; while (node.FullPath.Contains("\\")) { node.IsExpanded = true; node = node.Parent; } } parent.Files.Add(file); } else if (ele.Name == "Folder") { var folderName = ele.Attributes["Name"].Value; folderName = folderName.Substring(folderName.LastIndexOf('\\') + 1); var fullPath = string.IsNullOrEmpty(parent.FullPath) ? folderName : parent.FullPath + "\\" + folderName; var folder = new FileNode() { Name = folderName, IsFile = false, PrefixPath = prefixPath, Parent = parent, FullPath = fullPath, IsExpanded = !fullPath.Contains("\\"), }; parent.Files.Add(folder); if (selectionIsFolder && selectionName == folder.FullPath) { folder.IsSelected = true; var node = folder; while (node.FullPath.Contains("\\")) { node.IsExpanded = true; node = node.Parent; } } CreateTreeViewItems(ele, folder, prefixPath, selectionName, selectionIsFolder, isFolderNodeOnly); } } } /// /// 创建Recipe文件树。 /// /// /// /// /// /// 是否仅显示文件夹 /// 是否显示根节点 /// public static List BuildFileNode(string prefixPath, string selectionName, bool selectionIsFolder, string fileListInXml, bool isFolderNodeOnly = false, bool isShowRoot = false) { var folders = new List(); var root = new FileNode() { Name = "Files", IsFile = false, FullPath = "", PrefixPath = prefixPath }; folders.Add(root); // 是否显示根目录节点 if (isShowRoot) { root.Files.Add(new FileNode() { Name = "\\", IsExpanded = true, PrefixPath = prefixPath, IsFile = false, FullPath = "", }); root = root.Files[0]; } var doc = new XmlDocument(); doc.LoadXml(fileListInXml); CreateTreeViewItems(doc.DocumentElement, root, prefixPath, selectionName, selectionIsFolder, isFolderNodeOnly); return folders; } } }