基本框架定义完成

This commit is contained in:
zengwenjie
2025-09-16 21:33:34 +08:00
parent 5935564927
commit 75a9aa8462
23 changed files with 1395 additions and 171 deletions

View File

@@ -3,11 +3,13 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
@@ -19,41 +21,40 @@ using System.Windows.Shapes;
namespace Deedy.Activity
{
/// <summary>
/// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
///
/// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:Deedy.Design"
///
///
/// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:Deedy.Design;assembly=Deedy.Design"
///
/// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
/// 并重新生成以避免编译错误:
///
/// 在解决方案资源管理器中右击目标项目,然后依次单击
/// “添加引用”->“项目”->[浏览查找并选择此项目]
///
///
/// 步骤 2)
/// 继续操作并在 XAML 文件中使用控件。
///
/// <MyNamespace:ActionViewer/>
///
/// 用于为Action提供显示视图
/// </summary>
[IconKey(ThemeKeys.KEY_Activity_DefaultIcon)]
[TemplatePart(Name = PART_ItemsContainer, Type = typeof(ItemsControl))]
[TemplatePart(Name = PART_TitleContainer, Type = typeof(FrameworkElement))]
[TemplatePart(Name = PART_StateDecorator, Type = typeof(ViewerStateDecorator))]
public class ActionViewer : Control, IActionViewer
{
public const string PART_ItemsContainer = "PART_ItemsContainer";
public const string PART_TitleContainer = "PART_TitleContainer";
public const string PART_StateDecorator = "PART_StateDecorator";
[AllowNull]
protected internal ItemsControl ItemsContainer;
[AllowNull]
protected internal FrameworkElement TitleContainer;
[AllowNull]
protected internal ViewerStateDecorator StateDecorator;
static ActionViewer()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ActionViewer), new FrameworkPropertyMetadata(typeof(ActionViewer)));
}
public ActionViewer()
{
ToolTipService.SetInitialShowDelay(this, 0);
ToolTipService.SetBetweenShowDelay(this, 0);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.ItemsContainer = this.GetTemplateChild(PART_ItemsContainer) as ItemsControl;
this.TitleContainer = this.GetTemplateChild(PART_TitleContainer) as FrameworkElement;
this.StateDecorator = this.GetTemplateChild(PART_StateDecorator) as ViewerStateDecorator;
this.RefreshViewerState();
}
public event PropertyChangedEventHandler? PropertyChanged;
/// <summary>
@@ -86,60 +87,404 @@ namespace Deedy.Activity
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
[AllowNull]
public Runtime Runtime { get; protected internal set; }
public Runtime Runtime => throw new NotImplementedException();
/// <summary>
/// 是否显示Break控制手柄
/// </summary>
public Visibility ShowBreakHandle
{
get { return (Visibility)GetValue(ShowBreakHandleProperty); }
protected internal set { SetValue(ShowBreakHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowBreakHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowBreakHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowBreakHandleProperty = ShowBreakHandlePropertyKey.DependencyProperty;
public Visibility ShowBreakHandle => throw new NotImplementedException();
/// <summary>
/// 是否显示重手柄
/// </summary>
public Visibility ShowContinueHandle
{
get { return (Visibility)GetValue(ShowContinueHandleProperty); }
protected internal set { SetValue(ShowContinueHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowContinueHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowContinueHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowContinueHandleProperty = ShowContinueHandlePropertyKey.DependencyProperty;
public Visibility ShowContinueHandle => throw new NotImplementedException();
/// <summary>
/// 是否显示退出手柄
/// </summary>
public Visibility ShowExitHandle
{
get { return (Visibility)GetValue(ShowExitHandleProperty); }
protected internal set { SetValue(ShowExitHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowExitHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowExitHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowExitHandleProperty = ShowExitHandlePropertyKey.DependencyProperty;
public Visibility ShowExitHandle => throw new NotImplementedException();
/// <summary>
/// 是否显示返回手柄
/// </summary>
public Visibility ShowReturnHandle
{
get { return (Visibility)GetValue(ShowReturnHandleProperty); }
protected internal set { SetValue(ShowReturnHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowReturnHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowReturnHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowReturnHandleProperty = ShowReturnHandlePropertyKey.DependencyProperty;
public Visibility ShowReturnHandle => throw new NotImplementedException();
/// <summary>
/// 是否显示自定义手柄
/// </summary>
public Visibility ShowCustomizeHandle
{
get { return (Visibility)GetValue(ShowCustomizeHandleProperty); }
protected internal set { SetValue(ShowCustomizeHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowCustomizeHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowCustomizeHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowCustomizeHandleProperty = ShowCustomizeHandlePropertyKey.DependencyProperty;
public Visibility ShowCustomHandle => throw new NotImplementedException();
/// <summary>
/// 是否显示进入区
/// </summary>
public Visibility ShowEntryZone
{
get { return (Visibility)GetValue(ShowEntryZoneProperty); }
protected internal set { SetValue(ShowEntryZonePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowEntryZonePropertyKey =
DependencyProperty.RegisterReadOnly("ShowEntryZone", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Visible));
public static readonly DependencyProperty ShowEntryZoneProperty = ShowEntryZonePropertyKey.DependencyProperty;
public Visibility ShowHeader => throw new NotImplementedException();
/// <summary>
/// 是否显示退出区
/// </summary>
public Visibility ShowLeaveZone
{
get { return (Visibility)GetValue(ShowLeaveZoneProperty); }
protected internal set { SetValue(ShowLeaveZonePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowLeaveZonePropertyKey =
DependencyProperty.RegisterReadOnly("ShowLeaveZone", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Visible));
public static readonly DependencyProperty ShowLeaveZoneProperty = ShowLeaveZonePropertyKey.DependencyProperty;
public Visibility ShowFooter => throw new NotImplementedException();
/// <summary>
/// 是否显示消息回显
/// </summary>
public Visibility ShowInfoHandle
{
get { return (Visibility)GetValue(ShowInfoHandleProperty); }
protected internal set { SetValue(ShowInfoHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowInfoHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowInfoHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowInfoHandleProperty = ShowInfoHandlePropertyKey.DependencyProperty;
public Visibility ShowInfoHandle => throw new NotImplementedException();
/// <summary>
/// 是否显示删除图标
/// </summary>
public Visibility ShowDeleteHandle
{
get { return (Visibility)GetValue(ShowDeleteHandleProperty); }
protected internal set { SetValue(ShowDeleteHandlePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowDeleteHandlePropertyKey =
DependencyProperty.RegisterReadOnly("ShowDeleteHandle", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowDeleteHandleProperty = ShowDeleteHandlePropertyKey.DependencyProperty;
public Visibility ShowDeleteHandle => throw new NotImplementedException();
/// <summary>
/// 显示左侧退出线
/// </summary>
public Visibility ShowLeftExitline
{
get { return (Visibility)GetValue(ShowLeftExitlineProperty); }
protected internal set { SetValue(ShowLeftExitlinePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowLeftExitlinePropertyKey =
DependencyProperty.RegisterReadOnly("ShowLeftExitline", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowLeftExitlineProperty = ShowLeftExitlinePropertyKey.DependencyProperty;
public Visibility ShowLeftExitline => throw new NotImplementedException();
/// <summary>
/// 显示右侧退出线
/// </summary>
public Visibility ShowRightExitline
{
get { return (Visibility)GetValue(ShowRightExitlineProperty); }
protected internal set { SetValue(ShowRightExitlinePropertyKey, value); }
}
public static readonly DependencyPropertyKey ShowRightExitlinePropertyKey =
DependencyProperty.RegisterReadOnly("ShowRightExitline", typeof(Visibility), typeof(ActionViewer), new PropertyMetadata(Visibility.Collapsed));
public static readonly DependencyProperty ShowRightExitlineProperty = ShowRightExitlinePropertyKey.DependencyProperty;
public Visibility ShowRightExitline => throw new NotImplementedException();
public LogInfo InstantInfo => throw new NotImplementedException();
/// <summary>
/// 即时消息
/// </summary>
public LogInfo InstantInfo
{
get { return (LogInfo)GetValue(InstantInfoProperty); }
protected internal set { SetValue(InstantInfoPropertyKey, value); }
}
public static readonly DependencyPropertyKey InstantInfoPropertyKey =
DependencyProperty.RegisterReadOnly("InstantInfo", typeof(LogInfo), typeof(ActionViewer), new PropertyMetadata(LogInfo.Empty,
(d, e) => (d as ActionViewer)?.InstantInfo_PropertyChangedCallback(e)));
public static readonly DependencyProperty InstantInfoProperty = InstantInfoPropertyKey.DependencyProperty;
/// <summary>
/// 处理「ActionViewer.InstantInfo」属性变更
/// </summary>
protected virtual void InstantInfo_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is LogInfo logInfo)
{
this.ToolTip = logInfo.ToString();
//TODO更新消息显示图标
}
}
public LogInfoCollection LogInfos => throw new NotImplementedException();
/// <summary>
/// 信息列表
/// </summary>
public LogInfoCollection LogInfos
{
get { return (LogInfoCollection)GetValue(LogInfosProperty); }
protected internal set { SetValue(LogInfosPropertyKey, value); }
}
public static readonly DependencyPropertyKey LogInfosPropertyKey =
DependencyProperty.RegisterReadOnly("LogInfos", typeof(LogInfoCollection), typeof(ActionViewer), new PropertyMetadata(null));
public static readonly DependencyProperty LogInfosProperty = LogInfosPropertyKey.DependencyProperty;
public uint ElementCount => throw new NotImplementedException();
/// <summary>
/// 子元素数量
/// </summary>
public int ElementCount
{
get { return (int)GetValue(ElementCountProperty); }
protected internal set { SetValue(ElementCountPropertyKey, value); }
}
public static readonly DependencyPropertyKey ElementCountPropertyKey =
DependencyProperty.RegisterReadOnly("ElementCount", typeof(int), typeof(ActionViewer), new PropertyMetadata(0));
public static readonly DependencyProperty ElementCountProperty = ElementCountPropertyKey.DependencyProperty;
public bool IsSelectable => throw new NotImplementedException();
/// <summary>
/// 是否可被选中
/// </summary>
public bool IsSelectable
{
get { return (bool)GetValue(IsSelectableProperty); }
protected internal set { SetValue(IsSelectablePropertyKey, value); }
}
public static readonly DependencyPropertyKey IsSelectablePropertyKey =
DependencyProperty.RegisterReadOnly("IsSelectable", typeof(bool), typeof(ActionViewer), new PropertyMetadata(true));
public static readonly DependencyProperty IsSelectableProperty = IsSelectablePropertyKey.DependencyProperty;
public bool IsSelected => throw new NotImplementedException();
/// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get { return (bool)GetValue(IsSelectedProperty); }
protected internal set { SetValue(IsSelectedPropertyKey, value); }
}
public static readonly DependencyPropertyKey IsSelectedPropertyKey =
DependencyProperty.RegisterReadOnly("IsSelected", typeof(bool), typeof(ActionViewer), new PropertyMetadata(false));
public static readonly DependencyProperty IsSelectedProperty = IsSelectedPropertyKey.DependencyProperty;
public bool IsCanExpand => throw new NotImplementedException();
/// <summary>
/// 是否可被展开
/// </summary>
public bool IsExpandable
{
get { return (bool)GetValue(IsExpandableProperty); }
protected internal set { SetValue(IsExpandablePropertyKey, value); }
}
public static readonly DependencyPropertyKey IsExpandablePropertyKey =
DependencyProperty.RegisterReadOnly("IsExpandable", typeof(bool), typeof(ActionViewer), new PropertyMetadata(true));
public static readonly DependencyProperty IsExpandableProperty = IsExpandablePropertyKey.DependencyProperty;
public bool IsExpanded => throw new NotImplementedException();
/// <summary>
/// 是否展开
/// </summary>
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
protected internal set { SetValue(IsExpandedPropertyKey, value); }
}
public static readonly DependencyPropertyKey IsExpandedPropertyKey =
DependencyProperty.RegisterReadOnly("IsExpanded", typeof(bool), typeof(ActionViewer), new PropertyMetadata(true));
public static readonly DependencyProperty IsExpandedProperty = IsExpandedPropertyKey.DependencyProperty;
public ViewerState ViewerState => throw new NotImplementedException();
/// <summary>
/// 是否可被拖动
/// </summary>
public bool IsDraggable
{
get { return (bool)GetValue(IsDraggableProperty); }
protected internal set { SetValue(IsDraggablePropertyKey, value); }
}
public static readonly DependencyPropertyKey IsDraggablePropertyKey =
DependencyProperty.RegisterReadOnly("IsDraggable", typeof(bool), typeof(ActionViewer), new PropertyMetadata(true));
public static readonly DependencyProperty IsDraggableProperty = IsDraggablePropertyKey.DependencyProperty;
public WorkMode WorkMode => throw new NotImplementedException();
public Brush FillBrush => throw new NotImplementedException();
/// <summary>
/// 是否正在拖动
/// </summary>
public bool IsDragging
{
get { return (bool)GetValue(IsDraggingProperty); }
protected internal set { SetValue(IsDraggingPropertyKey, value); }
}
public static readonly DependencyPropertyKey IsDraggingPropertyKey =
DependencyProperty.RegisterReadOnly("IsDragging", typeof(bool), typeof(ActionViewer), new PropertyMetadata(false));
public static readonly DependencyProperty IsDraggingProperty = IsDraggingPropertyKey.DependencyProperty;
public Brush StrokeBrush => throw new NotImplementedException();
/// <summary>
/// 视图状态
/// </summary>
public ViewerState ViewerState
{
get { return (ViewerState)GetValue(ViewerStateProperty); }
protected internal set { SetValue(ViewerStatePropertyKey, value); }
}
public static readonly DependencyPropertyKey ViewerStatePropertyKey =
DependencyProperty.RegisterReadOnly("ViewerState", typeof(ViewerState), typeof(ActionViewer), new PropertyMetadata(ViewerState.Normal,
(d, e) => (d as ActionViewer)?.ViewerState_PropertyChangedCallback(e)));
public static readonly DependencyProperty ViewerStateProperty = ViewerStatePropertyKey.DependencyProperty;
/// <summary>
/// 处理「ActionViewer.ViewerState」属性变更
/// </summary>
protected virtual void ViewerState_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
{
this.StyleSelector?.SelectStyle(this.ActionElement, this);
}
public double StrokeThickness => throw new NotImplementedException();
/// <summary>
/// 工作模式:非设计模式下不允许拖放操作;编辑、运行、回显三种模式不可相互切换,但可以与等待和预览状态切换。
/// </summary>
public WorkMode WorkMode
{
get { return (WorkMode)GetValue(WorkModeProperty); }
protected internal set { SetValue(WorkModePropertyKey, value); }
}
public static readonly DependencyPropertyKey WorkModePropertyKey =
DependencyProperty.RegisterReadOnly("WorkMode", typeof(WorkMode), typeof(ActionViewer), new PropertyMetadata(WorkMode.Waiting));
public static readonly DependencyProperty WorkModeProperty = WorkModePropertyKey.DependencyProperty;
public Thickness MarginCorrection_Top => throw new NotImplementedException();
/// <summary>
/// 填充画刷
/// </summary>
public Brush FillBrush
{
get { return (Brush)GetValue(FillBrushProperty); }
set { SetValue(FillBrushProperty, value); }
}
public static readonly DependencyProperty FillBrushProperty =
DependencyProperty.Register("FillBrush", typeof(Brush), typeof(ActionViewer), new PropertyMetadata(Brushes.Gray));
public Thickness MarginCorrection_Bottom => throw new NotImplementedException();
/// <summary>
/// 画线画刷
/// </summary>
public Brush StrokeBrush
{
get { return (Brush)GetValue(StrokeBrushProperty); }
set { SetValue(StrokeBrushProperty, value); }
}
public static readonly DependencyProperty StrokeBrushProperty =
DependencyProperty.Register("StrokeBrush", typeof(Brush), typeof(ActionViewer), new PropertyMetadata(Brushes.Orange));
/// <summary>
/// 画线宽度
/// </summary>
public double StrokeThickness
{
get { return (double)GetValue(StrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
public static readonly DependencyProperty StrokeThicknessProperty =
DependencyProperty.Register("StrokeThickness", typeof(double), typeof(ActionViewer), new PropertyMetadata(2.0,
(d, e) => (d as ActionViewer)?.StrokeThickness_PropertyChangedCallback(e)));
/// <summary>
/// 处理「ActionViewer.StrokeThickness」属性变更
/// </summary>
protected virtual void StrokeThickness_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is double value)
{
if (value < 2)
{
this.StrokeThickness = 2;
return;
}
double halfValue = value / 2;
this.MarginCorrection_Top = new Thickness(0, halfValue, 0, 0);
this.MarginCorrection_Bottom = new Thickness(0, 0, 0, halfValue);
this.MarginCorrection_TopBottom = new Thickness(0, halfValue, 0, halfValue);
}
else this.StrokeThickness = 2;
}
public Thickness MarginCorrection_TopBottom => throw new NotImplementedException();
/// <summary>
/// 被托管动作元素的图标
/// </summary>
public ImageSource ElementIcon
{
get { return (ImageSource)GetValue(ElementIconProperty); }
protected internal set { SetValue(ElementIconPropertyKey, value); }
}
public static readonly DependencyPropertyKey ElementIconPropertyKey =
DependencyProperty.RegisterReadOnly("ElementIcon", typeof(ImageSource), typeof(ActionViewer), new PropertyMetadata(null));
public static readonly DependencyProperty ElementIconProperty = ElementIconPropertyKey.DependencyProperty;
/// <summary>
/// 视图样式选择器
/// </summary>
[AllowNull]
public StyleSelector StyleSelector
{
get { return (StyleSelector)GetValue(StyleSelectorProperty); }
set { SetValue(StyleSelectorProperty, value); }
}
public static readonly DependencyProperty StyleSelectorProperty =
DependencyProperty.Register("StyleSelector", typeof(StyleSelector), typeof(ActionViewer), new PropertyMetadata(null));
/// <summary>
/// 上边距修正
/// </summary>
public Thickness MarginCorrection_Top
{
get { return (Thickness)GetValue(MarginCorrection_TopProperty); }
protected internal set { SetValue(MarginCorrection_TopPropertyKey, value); }
}
public static readonly DependencyPropertyKey MarginCorrection_TopPropertyKey =
DependencyProperty.RegisterReadOnly("MarginCorrection_Top", typeof(Thickness), typeof(ActionViewer), new PropertyMetadata(new Thickness()));
public static readonly DependencyProperty MarginCorrection_TopProperty = MarginCorrection_TopPropertyKey.DependencyProperty;
/// <summary>
/// 下边距修正
/// </summary>
public Thickness MarginCorrection_Bottom
{
get { return (Thickness)GetValue(MarginCorrection_BottomProperty); }
protected internal set { SetValue(MarginCorrection_BottomPropertyKey, value); }
}
public static readonly DependencyPropertyKey MarginCorrection_BottomPropertyKey =
DependencyProperty.RegisterReadOnly("MarginCorrection_Bottom", typeof(Thickness), typeof(ActionViewer), new PropertyMetadata(new Thickness()));
public static readonly DependencyProperty MarginCorrection_BottomProperty = MarginCorrection_BottomPropertyKey.DependencyProperty;
/// <summary>
/// 上下边距修正
/// </summary>
public Thickness MarginCorrection_TopBottom
{
get { return (Thickness)GetValue(MarginCorrection_TopBottomProperty); }
protected internal set { SetValue(MarginCorrection_TopBottomPropertyKey, value); }
}
public static readonly DependencyPropertyKey MarginCorrection_TopBottomPropertyKey =
DependencyProperty.RegisterReadOnly("MarginCorrection_TopBottom", typeof(Thickness), typeof(ActionViewer), new PropertyMetadata(new Thickness()));
public static readonly DependencyProperty MarginCorrection_TopBottomProperty = MarginCorrection_TopBottomPropertyKey.DependencyProperty;
/// <summary>
/// 动作节点
/// </summary>
@@ -159,36 +504,334 @@ namespace Deedy.Activity
protected virtual void ActionElement_PropertyChangedCallback(DependencyPropertyChangedEventArgs e)
{
if (e.OldValue is IActionElement oldValue)
{
oldValue.PropertyChanged -= ActionElement_PropertyChanged;
if (oldValue is ICombinedElement combinedElement)
{
this.ElementCount = 0;
combinedElement.Elements.CollectionChanged -= Elements_CollectionChanged;
}
this.ShowEntryZone = Visibility.Visible;
this.ShowLeaveZone = Visibility.Visible;
this.ShowLeftExitline = Visibility.Collapsed;
this.ShowRightExitline = Visibility.Collapsed;
this.ShowBreakHandle = Visibility.Collapsed;
this.ShowContinueHandle = Visibility.Collapsed;
this.ShowCustomizeHandle = Visibility.Collapsed;
this.ShowExitHandle = Visibility.Collapsed;
this.ShowReturnHandle = Visibility.Collapsed;
}
if (e.NewValue is IActionElement newValue)
{
newValue.PropertyChanged += ActionElement_PropertyChanged;
Type elementType = newValue.GetType();
IconKeyAttribute? iconKey = elementType.GetCustomAttribute<IconKeyAttribute>();
if (iconKey != null)
{
ImageSource? icon = iconKey.TryFindResource(this) as ImageSource;
if (icon != null) this.ElementIcon = icon;
else
{
iconKey = this.GetType().GetCustomAttribute<IconKeyAttribute>();
if (iconKey != null) icon = iconKey.TryFindResource(this) as ImageSource;
if (icon != null) this.ElementIcon = icon;
else this.ClearValue(ElementIconPropertyKey);
}
}
if (newValue.IsLockedElement)
{
this.IsDraggable = false;
this.IsSelectable = false;
}
else
{
this.IsDraggable = true;
this.IsSelectable = true;
}
if (newValue is ICombinedElement newCombinedElement)
{
this.IsExpandable = true;
this.ElementCount = newCombinedElement.Elements.Count;
newCombinedElement.Elements.CollectionChanged += Elements_CollectionChanged;
}
else this.IsExpandable = false;
if (newValue is ICriticalZoneManageable criticalZoneManageable)
{
if (criticalZoneManageable.IsLeaveZoneHidden) this.ShowLeaveZone = Visibility.Collapsed;
if (criticalZoneManageable.IsEntryZoneHidden) this.ShowEntryZone = Visibility.Collapsed;
}
if (newValue is IExitlineManageable exitlinemanageable)
{
if ((exitlinemanageable.ExitlinePosition & ExitlinePosition.LeftLower) == ExitlinePosition.LeftLower)
this.ShowLeftExitline = Visibility.Visible;
if ((exitlinemanageable.ExitlinePosition & ExitlinePosition.Rightlower) == ExitlinePosition.Rightlower)
this.ShowRightExitline = Visibility.Visible;
}
if (newValue is ILogicController logicController)
{
switch (logicController.LogicalBehavior)
{
case LogicalBehavior.Exit: this.ShowExitHandle = Visibility.Visible; break;
case LogicalBehavior.Return: this.ShowReturnHandle = Visibility.Visible; break;
case LogicalBehavior.Break: this.ShowBreakHandle = Visibility.Visible; break;
case LogicalBehavior.Continue: this.ShowContinueHandle = Visibility.Visible; break;
case LogicalBehavior.Customize: this.ShowCustomizeHandle = Visibility.Visible; break;
default:
break;
}
}
//TODO根据节点的特征与当前工作状态来判定如何处理当前视图的属性
}
}
private void ActionElement_PropertyChanged(object? sender, PropertyChangedEventArgs e)
protected virtual void Elements_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (this.ActionElement is ICombinedElement combined)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
this.IsExpanded = true;
this.ElementCount = combined.Elements.Count;
}
}
protected virtual void ActionElement_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
//TODO处理托管的IActionElement节点的属性变更
case nameof(IActionElement.InstantInfo):
this.InstantInfo = this.ActionElement.InstantInfo;
break;
default: break;
}
}
public void ReadyToWorking(IElement? element = null, Output? output = null)
{
throw new NotImplementedException();
if (this.ActionElement != element && element is IActionElement action) this.ActionElement = action;
if (this.WorkMode == WorkMode.Waiting) this.WorkMode = WorkMode.Preview;
}
public void ReadyToEditing(Runtime runtime)
{
throw new NotImplementedException();
this.ReadyToWorking();
this.WorkMode = WorkMode.Editing;
}
public void ReadyToRunning(Runtime runtime)
{
throw new NotImplementedException();
this.ReadyToWorking();
this.WorkMode = WorkMode.Running;
}
/// <summary>
/// 刷新视图样式
/// </summary>
protected virtual void RefreshViewerState(bool isOverMe = false)
{
if (this.IsDragging)
{
if (this.IsSelected)
{
if (isOverMe) this.ViewerState = ViewerState.SelectedDragHover;
else this.ViewerState = ViewerState.Selected;
}
else
{
if (isOverMe) this.ViewerState = ViewerState.NormalDragHover;
else this.ViewerState = ViewerState.Normal;
}
}
else
{
if (this.IsSelected)
{
if (isOverMe) this.ViewerState = ViewerState.SelectedHover;
else this.ViewerState = ViewerState.Selected;
}
else
{
if (isOverMe) this.ViewerState = ViewerState.NormalHover;
else this.ViewerState = ViewerState.Normal;
}
}
}
/// <summary>
/// 检查事件源是否需要自身处理
/// </summary>
/// <param name="eventSource">引发事件的源</param>
/// <returns>只有事件源是自身或事件源的第一个SmartView类型的祖辈是自身时才需要处理</returns>
protected virtual bool IsEventNeedToHandle(object eventSource)
{
bool result = false;
if (eventSource is ActionViewer view && view != this) result = false;
if (eventSource is not ActionViewer && eventSource is DependencyObject dobj && this == dobj.FindAncestor<ActionViewer>()) result = true;
return result;
}
protected virtual void RemoveDragAdorner()
{ }
protected virtual void UpdateDragAdorner(Dock? dock)
{ }
#region
protected override void OnDragEnter(DragEventArgs e)
{
this.IsDragging = true;
ToolTipService.SetIsEnabled(this, false);
base.OnDragEnter(e);
}
protected override void OnDragLeave(DragEventArgs e)
{
this.IsDragging = false;
base.OnDragLeave(e);
}
private bool _CanDropInParent = false;
private bool _CanDropChild = false;
private DropPlacement _DropPlacement = DropPlacement.Uncertain;
protected override void OnDragOver(DragEventArgs e)
{
if (this.IsEventNeedToHandle(e.OriginalSource))
{
this.RefreshViewerState(true);
FrameworkElement hitElement = this;
if (this.TitleContainer != null && this.TitleContainer.Visibility == Visibility.Visible)
hitElement = this.TitleContainer;
Point currentPoint = e.GetPosition(hitElement);
if (this._CanDropInParent && (currentPoint.Y < 10 || currentPoint.Y < 10))
{
this._DropPlacement = DropPlacement.BeforeMe;
this.UpdateDragAdorner(Dock.Top);
}
else if (this._CanDropInParent && (hitElement.ActualHeight - currentPoint.Y < 10 || hitElement.ActualWidth - currentPoint.X < 10))
{
this._DropPlacement = DropPlacement.BehindMe;
this.UpdateDragAdorner(Dock.Bottom);
}
else if (this._CanDropChild)
{
this._DropPlacement = DropPlacement.WithinMe;
this.UpdateDragAdorner(null);
}
else
{
this._DropPlacement = DropPlacement.Rejected;
this.RemoveDragAdorner();
}
}
else
{
this.RefreshViewerState();
this.RemoveDragAdorner();
}
base.OnDragOver(e);
}
protected override void OnDrop(DragEventArgs e)
{
this.IsDragging = false;
this.RefreshViewerState();
this.RemoveDragAdorner();
if (this.IsEventNeedToHandle(e.OriginalSource))
{
//TODO发送准备放置事件如果事件被处理则「return」放弃默认逻辑
//注意这里不能标记e.Handle=true;否则可能会造成视图显示状态异常
if (e.Data.GetData(typeof(DragDropData)) is DragDropData data)
{
data.Placement = this._DropPlacement;
//TODO执行放置操作
}
}
base.OnDrop(e);
}
protected override void OnMouseEnter(MouseEventArgs e)
{
base.OnMouseEnter(e);
ToolTipService.SetIsEnabled(this, true);
if (!this.IsDragging) this.RefreshViewerState(true);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
base.OnMouseLeave(e);
if (!this.IsDragging) this.RefreshViewerState();
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if (e.LeftButton == MouseButtonState.Pressed)
{
this.IsSelected = this.IsSelectable;
if (this.IsDraggable) this._DragStartPoint = e.GetPosition(this);
}
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
this._DragStartPoint = null;
}
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (this.IsDragging) return;
bool isEventNeedHandle = this.IsEventNeedToHandle(e.OriginalSource);
this.RefreshViewerState(isEventNeedHandle);
if (isEventNeedHandle)
{
if (this.ActionElement == null || this.ActionElement.IsLockedElement) return;
var position = e.GetPosition(this);
ToolTipService.SetPlacement(this, PlacementMode.Relative);
ToolTipService.SetPlacementTarget(this, this);
ToolTipService.SetHorizontalOffset(this, position.X + 16);
ToolTipService.SetVerticalOffset(this, position.Y + 16);
}
}
private readonly object _DragLock = new();
private Point? _DragStartPoint = null;
protected override void OnPreviewMouseMove(MouseEventArgs e)
{
base.OnPreviewMouseMove(e);
if (!this.IsDraggable) return;
if (e.LeftButton == MouseButtonState.Pressed)
{
lock (_DragLock)
{
if (this.IsDragging || !_DragStartPoint.HasValue) return;
if (_DragStartPoint.HasValue)
{
Point currentPoint = e.GetPosition(this);
if (Math.Abs(this._DragStartPoint.Value.X - currentPoint.X) > SystemParameters.MinimumHorizontalDragDistance
||
Math.Abs(this._DragStartPoint.Value.Y - currentPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
{
//TODO发送准备拖动事件如果事件被响应则「return」退出原本逻辑
DragDropEffects dragDropEffects = DragDropEffects.Link;
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
dragDropEffects |= DragDropEffects.Copy;
else dragDropEffects |= DragDropEffects.Move;
//TODO构造拖动数据
e.Handled = true;
this._DragStartPoint = null;
//TODO启动拖动逻辑
//DragDrop.DoDragDrop(this, data, data.dragEffect);
}
}
}
}
}
#endregion
}
}