using Serein.Library; using Serein.Library.Api; using Serein.Library.Utils; using System.Windows; using System.Windows.Controls; namespace Serein.Workbench.Themes { /// /// NodeTreeVIewControl.xaml 的交互逻辑 /// public partial class NodeTreeItemViewControl : UserControl { public NodeTreeItemViewControl() { InitializeComponent(); foreach (var ct in NodeStaticConfig.ConnectionTypes) { var guid = ToGridView(this, ct); guid.Visibility = Visibility.Collapsed; } } /// /// 保存的节点数据 /// private NodeModelBase nodeModel; private IFlowEnvironment flowEnvironment { get; set; } private class NodeTreeModel { public NodeModelBase RootNode { get; set; } public Dictionary> ChildNodes { get; set; } } public void InitAndLoadTree(IFlowEnvironment flowEnvironment, NodeModelBase nodeModel) { this.flowEnvironment = flowEnvironment; this.nodeModel = nodeModel; RefreshTree(); } public TreeViewItem RefreshTree() { NodeModelBase rootNodeModel = this.nodeModel; NodeTreeModel nodeTreeModel = new NodeTreeModel { RootNode = rootNodeModel, ChildNodes = new Dictionary>() { {ConnectionInvokeType.Upstream, []}, {ConnectionInvokeType.IsSucceed, [rootNodeModel]}, {ConnectionInvokeType.IsFail, []}, {ConnectionInvokeType.IsError, []}, } }; string? itemName = rootNodeModel.MethodDetails?.MethodAnotherName; if (string.IsNullOrEmpty(itemName)) { itemName = rootNodeModel.ControlType.ToString(); } var rootNode = new TreeViewItem { Header = itemName, Tag = nodeTreeModel, }; LoadNodeItem(this, nodeTreeModel); rootNode.Expanded += TreeViewItem_Expanded; // 监听展开事件 rootNode.IsExpanded = true; return rootNode; } /// /// 展开子项事件 /// /// /// private void TreeViewItem_Expanded(object sender, RoutedEventArgs e) { if (sender is TreeViewItem item && item.Tag is NodeTreeModel nodeTreeModel) { item.Items.Clear(); NodeTreeItemViewControl? nodeTreeItemViewControl = LoadTNoderee(nodeTreeModel); if (nodeTreeItemViewControl is not null) { LoadNodeItem(nodeTreeItemViewControl, nodeTreeModel); item.Items.Add(nodeTreeItemViewControl); } item.IsSelected = false; } e.Handled = true; } /// /// 加载面板 /// /// /// private void LoadNodeItem(NodeTreeItemViewControl nodeTreeItemViewControl, NodeTreeModel nodeTreeModel) { foreach (var ct in NodeStaticConfig.ConnectionTypes) { var treeViewer = ToTreeView(nodeTreeItemViewControl, ct); var guid = ToGridView(nodeTreeItemViewControl, ct); treeViewer.Items.Clear(); // 移除对象树的所有节点 var list = nodeTreeModel.ChildNodes[ct]; if (list.Count > 0) { foreach (var child in list) { NodeTreeModel tmpNodeTreeModel = new NodeTreeModel { RootNode = child, ChildNodes = child.SuccessorNodes, }; string? itemName = child?.MethodDetails?.MethodAnotherName; if (string.IsNullOrEmpty(itemName)) { itemName = child?.ControlType.ToString(); } TreeViewItem treeViewItem = new TreeViewItem { Header = itemName, Tag = tmpNodeTreeModel }; treeViewItem.Expanded += TreeViewItem_Expanded; var contextMenu = new ContextMenu(); contextMenu.Items.Add(MainWindow.CreateMenuItem("从此节点执行", async (s, e) => { try { await flowEnvironment.StartAsyncInSelectNode(tmpNodeTreeModel.RootNode.Guid); } catch (Exception ex) { SereinEnv.WriteLine(ex); return; } })); contextMenu.Items.Add(MainWindow.CreateMenuItem("定位", (s, e) => flowEnvironment.NodeLocated(tmpNodeTreeModel.RootNode.Guid))); treeViewItem.ContextMenu = contextMenu; treeViewItem.Margin = new Thickness(-20, 0, 0, 0); treeViewer.Items.Add(treeViewItem); } guid.Visibility = Visibility.Visible; } else { guid.Visibility = Visibility.Collapsed; } } } /// /// 加载节点子项 /// /// /// private NodeTreeItemViewControl? LoadTNoderee(NodeTreeModel nodeTreeModel) { NodeTreeItemViewControl nodeTreeItemViewControl = null; foreach (var connectionType in NodeStaticConfig.ConnectionTypes) { var childNodeModels = nodeTreeModel.ChildNodes[connectionType]; if (childNodeModels.Count > 0) { nodeTreeItemViewControl ??= new NodeTreeItemViewControl(); } else { continue; } TreeView treeView = ToTreeView(nodeTreeItemViewControl, connectionType); foreach (var childNodeModel in childNodeModels) { NodeTreeModel tempNodeTreeModel = new NodeTreeModel { RootNode = childNodeModel, ChildNodes = childNodeModel.SuccessorNodes, }; string? itemName = childNodeModel?.MethodDetails?.MethodAnotherName; if (string.IsNullOrEmpty(itemName)) { itemName = childNodeModel?.ControlType.ToString(); } TreeViewItem treeViewItem = new TreeViewItem { Header = itemName, Tag = tempNodeTreeModel }; treeViewItem.Margin = new Thickness(-20, 0, 0, 0); treeViewItem.Visibility = Visibility.Visible; treeView.Items.Add(treeViewItem); } } if (nodeTreeItemViewControl is not null) { foreach (var connectionType in NodeStaticConfig.ConnectionTypes) { var childNodeModels = nodeTreeModel.ChildNodes[connectionType]; if (childNodeModels.Count > 0) { nodeTreeItemViewControl ??= new NodeTreeItemViewControl(); } else { continue; } } } return nodeTreeItemViewControl; } /// /// 折叠事件 /// /// /// private void TreeViewItem_Collapsed(object sender, RoutedEventArgs e) { if (sender is TreeViewItem item && item.Items.Count > 0) { item.Items.Clear(); } } public static TreeView ToTreeView(NodeTreeItemViewControl item, ConnectionInvokeType connectionType) { return connectionType switch { ConnectionInvokeType.Upstream => item.UpstreamTreeNodes, ConnectionInvokeType.IsError => item.IsErrorTreeNodes, ConnectionInvokeType.IsFail => item.IsFailTreeNodes, ConnectionInvokeType.IsSucceed => item.IsSucceedTreeNodes, _ => throw new Exception("LoadNodeItem Error :ConnectionType is " + connectionType) }; } public static Grid ToGridView(NodeTreeItemViewControl item, ConnectionInvokeType connectionType) { return connectionType switch { ConnectionInvokeType.Upstream => item.UpstreamTreeGuid, ConnectionInvokeType.IsError => item.IsErrorTreeGuid, ConnectionInvokeType.IsFail => item.IsFailTreeGuid, ConnectionInvokeType.IsSucceed => item.IsSucceedTreeGuid, _ => throw new Exception("LoadNodeItem Error :ConnectionType is " + connectionType) }; } //public static System.Windows.Shapes.Rectangle ToRectangle(NodeTreeItemViewControl item, ConnectionType connectionType) //{ // return connectionType switch // { // ConnectionType.Upstream => item.UpstreamTreeRectangle, // ConnectionType.IsError => item.IsErrorRectangle, // ConnectionType.IsFail => item.IsFailRectangle, // ConnectionType.IsSucceed => item.IsSucceedRectangle, // _ => throw new Exception("LoadNodeItem Error :ConnectionType is " + connectionType) // }; //} } }