From dd4cf22db83dc41ddb8cf04c289b8eb95991de30 Mon Sep 17 00:00:00 2001
From: zengwenjie <1663900244@qq.com>
Date: Thu, 18 Sep 2025 16:45:44 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E4=B9=89=E9=80=89=E4=B8=AD=E5=89=8D?=
 =?UTF-8?q?=E3=80=81=E9=80=89=E4=B8=AD=E5=8F=8A=E8=AF=B7=E6=B1=82=E6=89=93?=
 =?UTF-8?q?=E5=BC=80=E7=8B=AC=E7=AB=8B=E8=AE=BE=E8=AE=A1=E5=99=A8=E7=9A=84?=
 =?UTF-8?q?=E4=BA=8B=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
 DeedyDesigner/Deedy.Activity/ActionViewer.cs  | 107 ++++++++++++++++--
 DeedyDesigner/Deedy.Activity/BasalAction.cs   |   2 +-
 .../EventArgs/CancelRoutedEventArgs.cs        |  13 +++
 .../EventArgs/RequestOpenDesignerEventArgs.cs |  22 ++++
 .../Deedy.Activity/IActionElement.cs          |   2 +-
 DeedyDesigner/Deedy.Testing/MainWindow.xaml   |   2 +-
 .../Deedy.Testing/MainWindow.xaml.cs          |   5 +
 7 files changed, 142 insertions(+), 11 deletions(-)
 create mode 100644 DeedyDesigner/Deedy.Activity/EventArgs/CancelRoutedEventArgs.cs
 create mode 100644 DeedyDesigner/Deedy.Activity/EventArgs/RequestOpenDesignerEventArgs.cs
diff --git a/DeedyDesigner/Deedy.Activity/ActionViewer.cs b/DeedyDesigner/Deedy.Activity/ActionViewer.cs
index c2a8eb1..898f188 100644
--- a/DeedyDesigner/Deedy.Activity/ActionViewer.cs
+++ b/DeedyDesigner/Deedy.Activity/ActionViewer.cs
@@ -310,13 +310,16 @@ namespace Deedy.Activity
         {
             if ((bool)e.NewValue)
             {
-                //TODO:发送节点选中事件
+                RoutedEventArgs args = new RoutedEventArgs(SelectedEvent, this.ActionElement);
+                this.RaiseEvent_Selected(args);
+
                 if (this.ActionElement is IContainerForFunction container)
                 {
                     if (container.IsEmbedded) this.IsExpanded = true;
                     else
                     {
-                        //TODO:发送打开辅助编辑器事件
+                        RequestOpenDesignerEventArgs reqArgs = new RequestOpenDesignerEventArgs(RequestOpenDesignerEvent, this.ActionElement);
+                        this.RaiseEvent_RequestOpenDesigner(reqArgs);
                     }
                 }
             }
@@ -582,9 +585,10 @@ namespace Deedy.Activity
                     }
                 }
 
-                if (newValue.IsLockedElement)
+                if (newValue.IsLocked)
                 {
                     this.IsDraggable = false;
+                    // 功能容器类型的锁定元素允许被选中
                     this.IsSelectable = newValue is IContainerForFunction;
                 }
                 else
@@ -726,10 +730,14 @@ namespace Deedy.Activity
             return result;
         }
         protected virtual void RemoveDragAdorner()
-        { }
+        {
+            //TODO:移除拖拽装饰器
+        }
         protected virtual void UpdateDragAdorner(Dock? dock)
-        { }
-        #region 交互事件
+        {
+            //TODO:更新拖拽装饰器
+        }
+        #region 订阅的交互事件
         protected override void OnDragEnter(DragEventArgs e)
         {
             this.IsDragging = true;
@@ -821,7 +829,12 @@ namespace Deedy.Activity
 
             if (e.LeftButton == MouseButtonState.Pressed)
             {
-                this.IsSelected = this.IsSelectable;
+                if (this.IsSelectable)
+                {
+                    CancelRoutedEventArgs args = new CancelRoutedEventArgs(PreviewSelectedEvent, this.ActionElement);
+                    this.RaiseEvent_PreviewSelected(args);
+                    this.IsSelected = !args.Cancel;
+                }
                 if (this.IsDraggable) this._DragStartPoint = e.GetPosition(this);
             }
         }
@@ -839,7 +852,7 @@ namespace Deedy.Activity
             this.RefreshViewerState(isEventNeedHandle);
             if (isEventNeedHandle)
             {
-                if (this.ActionElement == null || this.ActionElement.IsLockedElement) return;
+                if (this.ActionElement == null || this.ActionElement.IsLocked) return;
 
                 var position = e.GetPosition(this);
                 ToolTipService.SetPlacement(this, PlacementMode.Relative);
@@ -885,5 +898,83 @@ namespace Deedy.Activity
             }
         }
         #endregion
+
+        #region 声明的交互事件
+        /// 
+        /// 节点被选中
+        /// 
+		/// 
+        /// 节点被选中:当视图节点被选中时发生
+        /// 
+        public static readonly RoutedEvent SelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Bubble,
+            typeof(EventHandler), typeof(ActionViewer));
+        /// 
+        /// 事件「节点被选中」封装
+        /// 
+        public event EventHandler Selected
+        {
+            add { AddHandler(SelectedEvent, value); }
+            remove { RemoveHandler(SelectedEvent, value); }
+        }
+        /// 
+        /// 事件「节点被选中」触发
+        /// 
+        /// 事件参数
+        protected virtual void RaiseEvent_Selected(RoutedEventArgs args)
+        {
+            // 事件触发前可以进行一定的处理逻辑
+            RaiseEvent(args);
+        }
+        /// 
+        /// 节点将要被选中
+        /// 
+		/// 
+        /// 当节点要被选中前发生,此事件可以被取消
+        /// 
+        public static readonly RoutedEvent PreviewSelectedEvent = EventManager.RegisterRoutedEvent("Selected", RoutingStrategy.Tunnel,
+            typeof(EventHandler), typeof(ActionViewer));
+        /// 
+        /// 事件「节点将要被选中」封装
+        /// 
+        public event EventHandler PreviewSelected
+        {
+            add { AddHandler(SelectedEvent, value); }
+            remove { RemoveHandler(SelectedEvent, value); }
+        }
+        /// 
+        /// 事件「节点将要被选中」触发
+        /// 
+        /// 事件参数
+        protected virtual void RaiseEvent_PreviewSelected(CancelRoutedEventArgs args)
+        {
+            // 事件触发前可以进行一定的处理逻辑
+            RaiseEvent(args);
+        }
+        /// 
+        /// 请求打开独立的设计器
+        /// 
+		/// 
+        /// 当一个逻辑容器节点被选中,且要求系统打开独立设计器时发送此事件
+        /// 
+        public static readonly RoutedEvent RequestOpenDesignerEvent = EventManager.RegisterRoutedEvent("RequestOpenDesigner", RoutingStrategy.Bubble,
+            typeof(EventHandler), typeof(ActionViewer));
+        /// 
+        /// 事件「请求打开独立的设计器」封装
+        /// 
+        public event EventHandler RequestOpenDesigner
+        {
+            add { AddHandler(RequestOpenDesignerEvent, value); }
+            remove { RemoveHandler(RequestOpenDesignerEvent, value); }
+        }
+        /// 
+        /// 事件「请求打开独立的设计器」触发
+        /// 
+        /// 事件参数
+        protected virtual void RaiseEvent_RequestOpenDesigner(RequestOpenDesignerEventArgs args)
+        {
+            // 事件触发前可以进行一定的处理逻辑
+            RaiseEvent(args);
+        }
+        #endregion
     }
 }
diff --git a/DeedyDesigner/Deedy.Activity/BasalAction.cs b/DeedyDesigner/Deedy.Activity/BasalAction.cs
index 0262239..357b0a1 100644
--- a/DeedyDesigner/Deedy.Activity/BasalAction.cs
+++ b/DeedyDesigner/Deedy.Activity/BasalAction.cs
@@ -18,7 +18,7 @@ namespace Deedy.Activity
         public string Remark { get; set; } = "";
         public string Identify { get; set; } = "";
         public int DepthLevel { get; protected internal set; } = 0;
-        public bool IsLockedElement { get; set; } = false;
+        public bool IsLocked { get; set; } = false;
         protected internal LogInfo _InstantInfo = LogInfo.Empty;
         /// 
         /// 即时消息
diff --git a/DeedyDesigner/Deedy.Activity/EventArgs/CancelRoutedEventArgs.cs b/DeedyDesigner/Deedy.Activity/EventArgs/CancelRoutedEventArgs.cs
new file mode 100644
index 0000000..45ac288
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/EventArgs/CancelRoutedEventArgs.cs
@@ -0,0 +1,13 @@
+using System.Windows;
+
+namespace Deedy.Activity
+{
+    public class CancelRoutedEventArgs : RoutedEventArgs
+    {
+        public CancelRoutedEventArgs() : base() { }
+        public CancelRoutedEventArgs(RoutedEvent routedEvent) : base(routedEvent) { }
+        public CancelRoutedEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { }
+
+        public bool Cancel { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/DeedyDesigner/Deedy.Activity/EventArgs/RequestOpenDesignerEventArgs.cs b/DeedyDesigner/Deedy.Activity/EventArgs/RequestOpenDesignerEventArgs.cs
new file mode 100644
index 0000000..d18c49e
--- /dev/null
+++ b/DeedyDesigner/Deedy.Activity/EventArgs/RequestOpenDesignerEventArgs.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace Deedy.Activity
+{
+    public class RequestOpenDesignerEventArgs : RoutedEventArgs
+    {
+        public RequestOpenDesignerEventArgs() : base() { }
+        public RequestOpenDesignerEventArgs(RoutedEvent routedEvent) : base(routedEvent) { }
+        public RequestOpenDesignerEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { }
+        [AllowNull]
+        public Type DesignerType { get; set; }
+        [AllowNull]
+        public object DesignerInstance { get; set; }
+        public bool IsNeedPopup { get; set; }
+    }
+}
diff --git a/DeedyDesigner/Deedy.Activity/IActionElement.cs b/DeedyDesigner/Deedy.Activity/IActionElement.cs
index bcc2be1..51885e6 100644
--- a/DeedyDesigner/Deedy.Activity/IActionElement.cs
+++ b/DeedyDesigner/Deedy.Activity/IActionElement.cs
@@ -9,7 +9,7 @@ namespace Deedy.Activity
     public interface IActionElement : IElement
     {
         public IActionViewer? ActionViewer { get; }
-        public bool IsLockedElement { get; set; }
+        public bool IsLocked { get; set; }
         public LogInfo InstantInfo { get; }
     }
 }
diff --git a/DeedyDesigner/Deedy.Testing/MainWindow.xaml b/DeedyDesigner/Deedy.Testing/MainWindow.xaml
index f319344..fb57713 100644
--- a/DeedyDesigner/Deedy.Testing/MainWindow.xaml
+++ b/DeedyDesigner/Deedy.Testing/MainWindow.xaml
@@ -5,7 +5,7 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:Deedy.Testing"
         mc:Ignorable="d"
-        Title="MainWindow" Height="450" Width="800">
+        Title="MainWindow" Height="450" Width="800" Closing="Window_Closing">
     
 
     
diff --git a/DeedyDesigner/Deedy.Testing/MainWindow.xaml.cs b/DeedyDesigner/Deedy.Testing/MainWindow.xaml.cs
index 1a461cc..2a710e6 100644
--- a/DeedyDesigner/Deedy.Testing/MainWindow.xaml.cs
+++ b/DeedyDesigner/Deedy.Testing/MainWindow.xaml.cs
@@ -20,5 +20,10 @@ namespace Deedy.Testing
         {
             InitializeComponent();
         }
+
+        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
+        {
+
+        }
     }
 }
\ No newline at end of file