Sic.Framework/MECF.Framework.UI.Client/CenterViews/Editors/RecipeSequenceTreeBuilder.cs

226 lines
8.5 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
2023-04-13 11:51:03 +08:00
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
2023-04-13 11:51:03 +08:00
public FileNode()
{
this.Files = new ObservableCollection<FileNode>();
this.IsFile = false;
}
#endregion
#region Properties
2023-04-13 11:51:03 +08:00
public string Name
{
get { return _name; }
set { _name = value; NotifyOfPropertyChange("Name"); }
2023-04-13 11:51:03 +08:00
}
public string FullPath { get; set; }
2023-04-13 11:51:03 +08:00
public FileNode Parent { get; set; }
2023-04-13 11:51:03 +08:00
public ObservableCollection<FileNode> Files { get; set; }
2023-04-13 11:51:03 +08:00
public bool IsFile { get; set; }
2023-04-13 11:51:03 +08:00
public string PrefixPath { get; set; }
2023-04-13 11:51:03 +08:00
public bool IsSelected { get; set; }
2023-04-13 11:51:03 +08:00
public bool IsExpanded { get; set; }
#endregion
#region Methods
/// <summary>
/// 将数中的节点转换为节点数组。
/// </summary>
/// <param name="terminalOnly">是否仅枚举最末端节点。</param>
/// <para>更新子节点的Selected属性时需要同时更新中间节点的属性更新父节点时只评估终端节点的Selected属性。</para>
/// <returns></returns>
private List<FileNode> Flatten(bool terminalOnly)
{
if (Files == null || Files.Count <= 0)
return new List<FileNode>(new[] { this });
var lst = Files.SelectMany(x => x.Flatten(terminalOnly)).ToList();
if (!terminalOnly)
lst.Add(this);
return lst;
}
/// <summary>
/// 选择指定的节点。
/// </summary>
/// <param name="fullPath"></param>
public void Select(string fullPath)
{
var flattenList = Flatten(true);
flattenList.ForEach(x => { x.IsSelected = x.FullPath == fullPath; });
Refresh();
}
#endregion
2023-04-13 11:51:03 +08:00
}
2023-04-13 11:51:03 +08:00
public class RecipeSequenceTreeBuilder
{
public static List<FileNode> GetFiles(string prefixPath, List<string> filenames)
{
List<FileNode> folders = new List<FileNode>();
FileNode root = new FileNode() { Name = "Files", IsFile = false, FullPath = "", PrefixPath = prefixPath };
2023-04-13 11:51:03 +08:00
folders.Add(root);
foreach (string filename in filenames)
2023-04-13 11:51:03 +08:00
{
string[] filesplits = filename.Split('\\');
FileNode parent = root;
if (filesplits.Length > 1)
2023-04-13 11:51:03 +08:00
{
for (var index = 0; index < filesplits.Length - 1; index++)
2023-04-13 11:51:03 +08:00
{
bool found = false;
for (var j = 0; j < parent.Files.Count; j++)
2023-04-13 11:51:03 +08:00
{
if (parent.Files[j].Name == filesplits[index] && !parent.Files[j].IsFile)
2023-04-13 11:51:03 +08:00
{
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)
2023-04-13 11:51:03 +08:00
{
foreach (XmlElement ele in curElementNode.ChildNodes)
{
if (ele.Name == "File" && !isFolderNodeOnly)
2023-04-13 11:51:03 +08:00
{
var fileName = ele.Attributes["Name"].Value;
2023-04-13 11:51:03 +08:00
fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);
var fullPath = string.IsNullOrEmpty(parent.FullPath)
2023-04-13 11:51:03 +08:00
? fileName
: parent.FullPath + "\\" + fileName;
var file = new FileNode()
2023-04-13 11:51:03 +08:00
{
Name = fileName,
IsFile = true,
PrefixPath = prefixPath,
Parent = parent,
FullPath = fullPath,
};
if (!selectionIsFolder && selectionName == file.FullPath)
{
file.IsSelected = true;
var node = file.Parent;
2023-04-13 11:51:03 +08:00
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;
2023-04-13 11:51:03 +08:00
folderName = folderName.Substring(folderName.LastIndexOf('\\') + 1);
var fullPath = string.IsNullOrEmpty(parent.FullPath)
2023-04-13 11:51:03 +08:00
? folderName
: parent.FullPath + "\\" + folderName;
var folder = new FileNode()
2023-04-13 11:51:03 +08:00
{
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;
2023-04-13 11:51:03 +08:00
while (node.FullPath.Contains("\\"))
{
node.IsExpanded = true;
node = node.Parent;
}
}
CreateTreeViewItems(ele, folder, prefixPath, selectionName, selectionIsFolder, isFolderNodeOnly);
2023-04-13 11:51:03 +08:00
}
}
}
/// <summary>
/// 创建Recipe文件树。
/// </summary>
/// <param name="prefixPath"></param>
/// <param name="selectionName"></param>
/// <param name="selectionIsFolder"></param>
/// <param name="fileListInXml"></param>
/// <param name="isFolderNodeOnly">是否仅显示文件夹</param>
/// <param name="isShowRoot">是否显示根节点</param>
/// <returns></returns>
public static List<FileNode> BuildFileNode(string prefixPath, string selectionName, bool selectionIsFolder, string fileListInXml, bool isFolderNodeOnly = false, bool isShowRoot = false)
2023-04-13 11:51:03 +08:00
{
var folders = new List<FileNode>();
var root = new FileNode() { Name = "Files", IsFile = false, FullPath = "", PrefixPath = prefixPath };
2023-04-13 11:51:03 +08:00
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();
2023-04-13 11:51:03 +08:00
doc.LoadXml(fileListInXml);
CreateTreeViewItems(doc.DocumentElement, root, prefixPath, selectionName, selectionIsFolder, isFolderNodeOnly);
2023-04-13 11:51:03 +08:00
return folders;
}
}
2023-04-13 11:51:03 +08:00
}