226 lines
8.5 KiB
C#
226 lines
8.5 KiB
C#
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<FileNode>();
|
||
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<FileNode> 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
|
||
|
||
/// <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
|
||
}
|
||
|
||
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 };
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <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)
|
||
{
|
||
var folders = new List<FileNode>();
|
||
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;
|
||
}
|
||
}
|
||
}
|