mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-03 00:00:49 +08:00
282 lines
10 KiB
C#
282 lines
10 KiB
C#
using Serein.Library;
|
||
using Serein.Library.Api;
|
||
using Serein.Library.Utils;
|
||
using Serein.Workbench.Tool;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
|
||
namespace Serein.Workbench.Themes
|
||
{
|
||
/// <summary>
|
||
/// NodeTreeVIewControl.xaml 的交互逻辑
|
||
/// </summary>
|
||
public partial class NodeTreeItemViewControl : UserControl
|
||
{
|
||
public NodeTreeItemViewControl()
|
||
{
|
||
InitializeComponent();
|
||
foreach (var ct in NodeStaticConfig.ConnectionTypes)
|
||
{
|
||
var guid = ToGridView(this, ct);
|
||
guid.Visibility = Visibility.Collapsed;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 保存的节点数据
|
||
/// </summary>
|
||
private IFlowNode nodeModel;
|
||
private IFlowEnvironment flowEnvironment { get; set; }
|
||
|
||
|
||
private class NodeTreeModel
|
||
{
|
||
public IFlowNode RootNode { get; set; }
|
||
public Dictionary<ConnectionInvokeType, List<IFlowNode>> ChildNodes { get; set; }
|
||
}
|
||
|
||
|
||
public void InitAndLoadTree(IFlowEnvironment flowEnvironment, IFlowNode nodeModel)
|
||
{
|
||
this.flowEnvironment = flowEnvironment;
|
||
this.nodeModel = nodeModel;
|
||
RefreshTree();
|
||
}
|
||
|
||
public TreeViewItem RefreshTree()
|
||
{
|
||
IFlowNode rootNodeModel = this.nodeModel;
|
||
NodeTreeModel nodeTreeModel = new NodeTreeModel
|
||
{
|
||
RootNode = rootNodeModel,
|
||
ChildNodes = new Dictionary<ConnectionInvokeType, List<IFlowNode>>()
|
||
{
|
||
{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;
|
||
}
|
||
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 展开子项事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载面板
|
||
/// </summary>
|
||
/// <param name="nodeTreeItemViewControl"></param>
|
||
/// <param name="nodeTreeModel"></param>
|
||
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(WpfFuncTool.CreateMenuItem("从此节点执行", async (s, e) =>
|
||
{
|
||
try
|
||
{
|
||
await flowEnvironment.StartFlowFromSelectNodeAsync(tmpNodeTreeModel.RootNode.Guid);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
SereinEnv.WriteLine(ex);
|
||
return;
|
||
}
|
||
}));
|
||
contextMenu.Items.Add(WpfFuncTool.CreateMenuItem("定位", (s, e) => flowEnvironment.NodeLocate(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;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载节点子项
|
||
/// </summary>
|
||
/// <param name="nodeTreeModel"></param>
|
||
/// <returns></returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 折叠事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
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)
|
||
// };
|
||
//}
|
||
|
||
|
||
}
|
||
}
|