diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs
index 6e598e9..714e0c7 100644
--- a/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs
+++ b/AIStudio.Wpf.DiagramApp/ViewModels/MainWindowViewModel.cs
@@ -1166,14 +1166,14 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
//var colors = ColorGallery.GetGradient(ColorGallery.StandardThemeColors[i], 10);
//for (var j = 9; j >= 0; j--)
//{
- // result.Add(colors[j]);
+ // result.AddTo(colors[j]);
//}
}
{
//var colors = ColorGallery.GetGradient(Colors.Black, 10);
//for (var j = 9; j >= 0; j--)
//{
- // result.Add(colors[j]);
+ // result.AddTo(colors[j]);
//}
}
return result.ToArray();
diff --git a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs
index 88b1df6..d7364cf 100644
--- a/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs
+++ b/AIStudio.Wpf.DiagramApp/ViewModels/MindViewModel.cs
@@ -103,24 +103,24 @@ namespace AIStudio.Wpf.Flowchart
var level1node = MindDiagramViewModel.RootItems.FirstOrDefault();
MindNode level2node1_1 = new MindNode(DiagramViewModel) { Text = "分支主题1" };
- MindDiagramViewModel.AddChildCommand.Execute(new MindNode[] { level1node, level2node1_1 });
+ level2node1_1.AddTo(level1node, 0, false);
MindNode level2node1_1_1 = new MindNode(DiagramViewModel) { Text = "分支主题1_1" };
- MindDiagramViewModel.AddChildCommand.Execute(new MindNode[] { level2node1_1, level2node1_1_1 });
+ level2node1_1_1.AddTo(level2node1_1, 0, false);
MindNode level2node1_1_2 = new MindNode(DiagramViewModel) { Text = "分支主题1_2" };
- MindDiagramViewModel.AddChildCommand.Execute(new MindNode[] { level2node1_1, level2node1_1_2 }); ;
+ level2node1_1_2.AddTo(level2node1_1, 0, false);
MindNode level2node1_1_3 = new MindNode(DiagramViewModel) { Text = "分支主题1_3" };
- MindDiagramViewModel.AddChildCommand.Execute(new MindNode[] { level2node1_1, level2node1_1_3 });
+ level2node1_1_3.AddTo(level2node1_1, 0, false);
MindNode level2node1_2 = new MindNode(DiagramViewModel) { Text = "分支主题2" };
- MindDiagramViewModel.AddChildCommand.Execute(new MindNode[] { level1node, level2node1_2 });
+ level2node1_2.AddTo(level1node, 0, false);
MindNode level2node1_3 = new MindNode(DiagramViewModel) { Text = "分支主题3" };
- MindDiagramViewModel.AddChildCommand.Execute(new MindNode[] { level1node, level2node1_3 });
+ level2node1_3.AddTo(level1node, 0, false);
- level1node.LayoutUpdated();
+ DiagramViewModel.Init();
}
protected override DiagramViewModel GetDiagramViewModel(string name, DiagramType diagramType)
diff --git a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml
index c87d708..225d59f 100644
--- a/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml
+++ b/AIStudio.Wpf.DiagramApp/Views/MainWindow.xaml
@@ -1819,6 +1819,11 @@
+
+
+
+
+
@@ -1867,11 +1872,11 @@
-
+
-
+
@@ -1892,7 +1897,7 @@
-
+
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/LabelsViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/LabelsViewModel.cs
index 9058ecb..58769ab 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/LabelsViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/LabelsViewModel.cs
@@ -9,7 +9,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
public LabelsViewModel()
{
- Title = "Link Labels";
+ Title = "Url Labels";
Info = "Labels help you show more information through out a link. You can specify a distance or an offset." +
"The content of the labels is still limited because of Blazor's poor SVG support.";
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/MarkersViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/MarkersViewModel.cs
index 8cea720..3f0dbad 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/MarkersViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/MarkersViewModel.cs
@@ -9,7 +9,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
public MarkersViewModel()
{
- Title = "Link Markers";
+ Title = "Url Markers";
Info = "Markers are SVG Paths that you can put at the beginning or at the end of your links.";
DiagramViewModel = new DiagramViewModel();
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/PathGeneratorsViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/PathGeneratorsViewModel.cs
index 2f2530e..01ece75 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/PathGeneratorsViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/PathGeneratorsViewModel.cs
@@ -9,7 +9,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
public PathGeneratorsViewModel()
{
- Title = "Link Path Generators";
+ Title = "Url Path Generators";
Info = "Path generators are functions that take as input the calculated route and output SVG paths, " +
"alongside the markers positions and their angles. There are currently two generators: Straight and Smooth.";
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/RoutersViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/RoutersViewModel.cs
index 04affeb..8afae08 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/RoutersViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/RoutersViewModel.cs
@@ -9,7 +9,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
public RoutersViewModel()
{
- Title = "Link Routers";
+ Title = "Url Routers";
Info = "Routers are functions that take as input the link's vertices and can add points in between. " +
"There are currently two routers: Normal and Orthogonal.";
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/SnappingViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/SnappingViewModel.cs
index 45cea18..4ed1fb1 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/SnappingViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/SnappingViewModel.cs
@@ -9,7 +9,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
public SnappingViewModel()
{
- Title = "Link Snapping";
+ Title = "Url Snapping";
Info = "While dragging a new link, it will try to find (and link) to the closest target within a radius.";
DiagramViewModel = new DiagramViewModel();
diff --git a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/VerticesViewModel.cs b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/VerticesViewModel.cs
index 3591eb8..da1da35 100644
--- a/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/VerticesViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner.Demo/ViewModels/Links/VerticesViewModel.cs
@@ -9,7 +9,7 @@ namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
public VerticesViewModel()
{
- Title = "Link Vertices";
+ Title = "Url Vertices";
Info = "Click on a link to create a vertex. Double click on a vertex to delete it. " +
"You can drag the vertices around.";
diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs
index fcf7e1d..3a35833 100644
--- a/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs
+++ b/AIStudio.Wpf.DiagramDesigner/Controls/DragThumb.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
+using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner.Controls
{
@@ -16,6 +17,13 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
base.DragCompleted += DragThumb_DragCompleted;
}
+ public IDiagramViewModel DiagramViewModel
+ {
+ get
+ {
+ return (this.DataContext as SelectableDesignerItemViewModelBase)?.Root;
+ }
+ }
private List designerItems;
private bool drag;
@@ -51,11 +59,10 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
designerItems = designerItems.Distinct().ToList();
+ DiagramViewModel.DoCommandManager.BeginDo = true;
foreach (DesignerItemViewModelBase item in designerItems.OfType())
- {
- item.BeginDo = true;
- item.SetOldValue(item.Left, nameof(item.Left));
- item.SetOldValue(item.Top, nameof(item.Top));
+ {
+ item.SetOldValue(item.TopLeft, nameof(item.TopLeft));
}
e.Handled = true;
@@ -75,10 +82,25 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
foreach (DesignerItemViewModelBase item in designerItems.OfType())
{
item.SetCellAlignment();
- item.BeginDo = false;
- item.RaiseTopLeft();
}
+ Dictionary> infos =
+ designerItems.OfType().ToDictionary(p => p,
+ p => new Tuple(p.GetOldValue< PointBase >(nameof(p.TopLeft)), p.TopLeft));
+ DiagramViewModel.DoCommandManager.BeginDo = false;
+ DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.TopLeft = info.Value.Item2;
+ }
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.TopLeft = info.Value.Item1;
+ }
+ });
e.Handled = true;
}
}
diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs
index 9aca585..71affa6 100644
--- a/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs
+++ b/AIStudio.Wpf.DiagramDesigner/Controls/ResizeThumb.cs
@@ -5,6 +5,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
+using AIStudio.Wpf.DiagramDesigner.Geometrys;
namespace AIStudio.Wpf.DiagramDesigner.Controls
{
@@ -17,6 +18,14 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
base.DragCompleted += ResizeThumb_DragCompleted;
}
+ public IDiagramViewModel DiagramViewModel
+ {
+ get
+ {
+ return (this.DataContext as SelectableDesignerItemViewModelBase)?.Root;
+ }
+ }
+
private List designerItems;
IDiagramViewModel diagarmViewModel;
@@ -27,11 +36,11 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
if (designerItem != null && designerItem.IsSelected)
{
designerItems = designerItem.Root.SelectedItems.ToList();
+
+ DiagramViewModel.DoCommandManager.BeginDo = true;
foreach (DesignerItemViewModelBase item in designerItems.OfType())
{
- item.BeginDo = true;
- item.SetOldValue(item.ItemWidth, nameof(item.ItemWidth));
- item.SetOldValue(item.ItemHeight, nameof(item.ItemHeight));
+ item.SetOldValue(item.Size, nameof(item.Size));
}
e.Handled = true;
@@ -48,10 +57,26 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
{
foreach (DesignerItemViewModelBase item in designerItems.OfType())
{
- item.BeginDo = false;
- item.RaiseItemWidthHeight();
+
}
+ Dictionary> infos =
+ designerItems.OfType().ToDictionary(p => p,
+ p => new Tuple(p.GetOldValue(nameof(p.Size)), p.Size));
+ DiagramViewModel.DoCommandManager.BeginDo = false;
+ DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Size = info.Value.Item2;
+ }
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Size = info.Value.Item1;
+ }
+ });
e.Handled = true;
}
}
diff --git a/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs b/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs
index b0f7f08..452a7d3 100644
--- a/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs
+++ b/AIStudio.Wpf.DiagramDesigner/Controls/RotateThumb.cs
@@ -24,6 +24,14 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
DragCompleted += RotateThumb_DragCompleted;
}
+ public IDiagramViewModel DiagramViewModel
+ {
+ get
+ {
+ return (this.DataContext as SelectableDesignerItemViewModelBase)?.Root;
+ }
+ }
+
private List designerItems;
private void RotateThumb_DragStarted(object sender, DragStartedEventArgs e)
@@ -34,9 +42,9 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
{
designerItems = designerItem.Root.SelectedItems.ToList();
+ DiagramViewModel.DoCommandManager.BeginDo = true;
foreach (DesignerItemViewModelBase item in designerItems.OfType())
{
- item.BeginDo = true;
item.SetOldValue(this.designerItem.Angle, nameof(this.designerItem.Angle));
}
@@ -69,10 +77,26 @@ namespace AIStudio.Wpf.DiagramDesigner.Controls
{
foreach (DesignerItemViewModelBase item in designerItems.OfType())
{
- item.BeginDo = false;
- item.RaiseAngle();
+
}
+ Dictionary> infos =
+ designerItems.OfType().ToDictionary(p => p,
+ p => new Tuple(p.GetOldValue(nameof(p.Angle)), p.Angle));
+ DiagramViewModel.DoCommandManager.BeginDo = false;
+ DiagramViewModel.DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Angle = info.Value.Item2;
+ }
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Angle = info.Value.Item1;
+ }
+ });
e.Handled = true;
}
}
diff --git a/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs b/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs
index 3417918..e86d45c 100644
--- a/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs
+++ b/AIStudio.Wpf.DiagramDesigner/Helpers/DoCommandManager.cs
@@ -53,7 +53,7 @@ namespace AIStudio.Wpf.DiagramDesigner
get; private set;
}
- public int Capacity { get; set; } = 10;
+ public int Capacity { get; set; } = 100;
public DoCommandManager()
{
@@ -66,10 +66,18 @@ namespace AIStudio.Wpf.DiagramDesigner
UnDoActionStack = new Stack();
}
+ public bool BeginDo
+ {
+ get;set;
+ }
+
private bool _undoing;
public void DoNewCommand(string name, Action action, Action unDoAction, Action clearAction = null, bool doit = true)
{
- if (_undoing == true) return;
+ if (BeginDo == true)
+ return;
+ if (_undoing == true)
+ return;
try
{
_undoing = true;
@@ -103,7 +111,8 @@ namespace AIStudio.Wpf.DiagramDesigner
if (!CanUnDo)
return;
- if (_undoing == true) return;
+ if (_undoing == true)
+ return;
try
{
_undoing = true;
@@ -123,7 +132,8 @@ namespace AIStudio.Wpf.DiagramDesigner
if (!CanReDo)
return;
- if (_undoing == true) return;
+ if (_undoing == true)
+ return;
try
{
_undoing = true;
diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs
index 09cd7bb..f9665d7 100644
--- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs
+++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DesignerItemViewModelBase.cs
@@ -553,11 +553,6 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
- public bool BeginDo
- {
- get; set;
- }
-
public IObservable WhenConnectorsChanged
{
get
diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs
index b59cb6c..2d68145 100644
--- a/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs
@@ -319,16 +319,16 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
- private Size _gridMargin = new Size(28, 28);
+ private Size _gridMarginSize = new Size(28, 28);
public Size GridMarginSize
{
get
{
- return _gridMargin;
+ return _gridMarginSize;
}
set
{
- SetProperty(ref _gridMargin, value);
+ SetProperty(ref _gridMarginSize, value);
}
}
@@ -336,11 +336,11 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get
{
- return _gridMargin.Width;
+ return _gridMarginSize.Width;
}
set
{
- _gridMargin.Width = value;
+ _gridMarginSize.Width = value;
RaisePropertyChanged(nameof(GridMarginSize));
}
}
@@ -349,11 +349,11 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get
{
- return _gridMargin.Height;
+ return _gridMarginSize.Height;
}
set
{
- _gridMargin.Height = value;
+ _gridMarginSize.Height = value;
RaisePropertyChanged(nameof(GridMarginSize));
}
}
@@ -630,7 +630,7 @@ namespace AIStudio.Wpf.DiagramDesigner
get; set;
} = true;
- protected DoCommandManager DoCommandManager = new DoCommandManager();
+ public DoCommandManager DoCommandManager { get; private set; } = new DoCommandManager();
public event DiagramEventHandler Event;
@@ -1181,7 +1181,7 @@ namespace AIStudio.Wpf.DiagramDesigner
RaisePropertyChanged("Items");
}
- private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ protected virtual void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
RaisePropertyChanged(sender, e.PropertyName);
if (e.PropertyName == "IsSelected")
@@ -1189,12 +1189,6 @@ namespace AIStudio.Wpf.DiagramDesigner
RaisePropertyChanged(nameof(SelectedItem));
}
- //连续改变,需要特殊处理,不单独触发属性改变ReDo
- if (sender is DesignerItemViewModelBase designer)
- {
- if (designer.BeginDo) return;
- }
-
var selectable = sender as SelectableViewModelBase;
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
@@ -1211,6 +1205,8 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
+
+
//提供给标尺计算,延迟100ms,等布局改变再计算。
private void OnZoomValueChanged(string obj)
{
@@ -1392,7 +1388,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public void ClearSelectedItems()
{
- foreach (var item in this.Items.ToList())
+ foreach (var item in this.SelectedItems.ToList())
{
item.IsSelected = false;
}
@@ -2356,6 +2352,8 @@ namespace AIStudio.Wpf.DiagramDesigner
FitViewModel = new FitViewModel() { BoundingRect = DiagramViewModelHelper.GetBoundingRectangle(selectedItems) };
}
+
+
public void UpdateZIndex()
{
List ordered = Items.OrderBy(p => p.ZIndex).ToList();
diff --git a/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs b/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs
index c16d875..b7c4756 100644
--- a/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs
+++ b/AIStudio.Wpf.DiagramDesigner/ViewModels/IDiagramViewModel.cs
@@ -322,6 +322,10 @@ namespace AIStudio.Wpf.DiagramDesigner
}
#endregion
+ DoCommandManager DoCommandManager
+ {
+ get;
+ }
#region 设置选项
DiagramOption DiagramOption
{
diff --git a/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_0bdyaape_wpftmp.csproj b/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_0bdyaape_wpftmp.csproj
new file mode 100644
index 0000000..1d17de6
--- /dev/null
+++ b/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_0bdyaape_wpftmp.csproj
@@ -0,0 +1,249 @@
+
+
+ AIStudio.Wpf.Mind
+ obj\Debug\
+ obj\
+ F:\aistudio.-wpf.-diagram\AIStudio.Wpf.Mind\obj\
+ <_TargetAssemblyProjectName>AIStudio.Wpf.Mind
+
+
+
+ true
+ AIStudio.Wpf.Controls
+ akwkevin
+ https://gitee.com/akwkevin
+ A.png
+
+
+ 1.0.6
+ 一个Wpf的思维导图控件
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_5ymptayx_wpftmp.csproj b/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_5ymptayx_wpftmp.csproj
new file mode 100644
index 0000000..1d17de6
--- /dev/null
+++ b/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_5ymptayx_wpftmp.csproj
@@ -0,0 +1,249 @@
+
+
+ AIStudio.Wpf.Mind
+ obj\Debug\
+ obj\
+ F:\aistudio.-wpf.-diagram\AIStudio.Wpf.Mind\obj\
+ <_TargetAssemblyProjectName>AIStudio.Wpf.Mind
+
+
+
+ true
+ AIStudio.Wpf.Controls
+ akwkevin
+ https://gitee.com/akwkevin
+ A.png
+
+
+ 1.0.6
+ 一个Wpf的思维导图控件
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_rllyqvfb_wpftmp.csproj b/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_rllyqvfb_wpftmp.csproj
new file mode 100644
index 0000000..2f3b1f9
--- /dev/null
+++ b/AIStudio.Wpf.Mind/AIStudio.Wpf.Mind_rllyqvfb_wpftmp.csproj
@@ -0,0 +1,179 @@
+
+
+ AIStudio.Wpf.Mind
+ obj\Debug\
+ obj\
+ F:\aistudio.-wpf.-diagram\AIStudio.Wpf.Mind\obj\
+ <_TargetAssemblyProjectName>AIStudio.Wpf.Mind
+
+
+
+ true
+ AIStudio.Wpf.Controls
+ akwkevin
+ https://gitee.com/akwkevin
+ A.png
+
+
+ 1.0.6
+ 一个Wpf的思维导图控件
+
+
+
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml b/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
index 33ca6e8..315bbc9 100644
--- a/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
+++ b/AIStudio.Wpf.Mind/Controls/ToolBoxControl.xaml
@@ -34,7 +34,7 @@
-
+
-
+
-
+
-
+
@@ -107,11 +107,11 @@
-
+
-
+
-
+
-
+
-
+
+
@@ -425,7 +426,7 @@
-
+
@@ -454,14 +455,14 @@
-
+
-
+
@@ -490,7 +491,7 @@
-
+
@@ -611,7 +612,7 @@
-
+
-
+
@@ -90,7 +90,7 @@
IsHitTestVisible="False"/>
p.LayoutUpdated());
base.Init();
}
- public void InitRootItem()
+ private MindNode AddRootItem()
{
- ClearSelectedItemsCommand.Execute(null);
+ ClearSelectedItems();
MindNode level1node = new MindNode(this) { Root = this, Id = Guid.NewGuid(), Text = "思维导图" };
level1node.InitLayout(true);
Items.Add(level1node);
level1node.IsSelected = true;
- CenterMoveCommand.Execute(level1node);
+ Move(level1node, null, null);
+
+ return level1node;
}
protected override void ExecutedResetLayoutCommand(object obj)
@@ -357,31 +391,6 @@ namespace AIStudio.Wpf.Mind.ViewModels
ResetChildren(parent.Children);
}
}
-
- private List GetParent(MindNode node)
- {
- List mindnode = new List();
- while (node.ParentNode != null)
- {
- mindnode.Add(node.ParentNode);
- node = node.ParentNode;
- }
- return mindnode;
- }
-
- private List GetChildren(MindNode parent)
- {
- List mindnode = new List();
- if (parent.Children != null)
- {
- foreach (var child in parent.Children)
- {
- mindnode.Add(child);
- mindnode.AddRange(GetChildren(child));
- }
- }
- return mindnode;
- }
#endregion
#region 命令使能
@@ -402,49 +411,75 @@ namespace AIStudio.Wpf.Mind.ViewModels
}
#endregion
+ #region 属性改变
+ protected override void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ base.Item_PropertyChanged(sender, e);
+ if (e.PropertyName == "IsSelected")
+ {
+ if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
+ {
+ LinkInfo = new LinkInfo(MindSelectedItem?.LinkInfo);
+ ImageInfo = new ImageInfo(MindSelectedItem?.ImageInfo);
+ Remark = MindSelectedItem?.Remark;
+ }
+ }
+ }
+ #endregion
+
#region 新增,删除
public void ExecuteAddRootCommand(object parameter)
{
- InitRootItem();
+ MindNode rootitem = null;
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ rootitem = AddRootItem();
+ },
+ () => {
+ if (rootitem != null)
+ {
+ Remove(rootitem);
+ }
+ });
+
}
public void ExecuteAddChildCommand(object parameter)
{
List items = new List();
- if (parameter is MindNode parent)
+ List newitems = new List();
+ if (parameter is MindNode node)
{
-
+ items.Add(node);
}
else if (parameter is IEnumerable para)
{
- parent = para.FirstOrDefault();//第一个固定为父节点
- items = para.Skip(1).ToList();
+ items.AddRange(para);
}
else
{
- parent = SelectedItem as MindNode;
- }
-
- if (items?.Count == 0)
- {
- var node = new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" };
- items.Add(node);
+ items.AddRange(SelectedItems.OfType());
}
DoCommandManager.DoNewCommand(this.ToString(),
() => {
+
foreach (var item in items)
{
- parent.AddChild(item);
+ var newitem = new MindNode(this) { Text = $"分支主题{item.Children.Count + 1}" };
+ newitem.AddTo(item);
+ newitems.Add(newitem);
}
- parent.LayoutUpdated();
+
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
},
() => {
- foreach (var item in items)
+ foreach (var item in newitems)
{
- parent.RemoveChild(item);
+ item.RemoveFrom();
}
- parent.LayoutUpdated();
+
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
});
}
@@ -452,214 +487,256 @@ namespace AIStudio.Wpf.Mind.ViewModels
public void ExecuteAddParentCommand(object parameter)
{
List items = new List();
+ List newitems = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
}
else if (parameter is IEnumerable para)
{
- node = para.FirstOrDefault();//第一个固定为父节点
- items = para.Skip(1).ToList();
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
- if (node.Parent is MindNode parent)
- {
- if (items?.Count == 0)
- {
- items.Add(new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" });
- }
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in items)
+ {
+ if (item.ParentNode == null)
+ continue;
- DoCommandManager.DoNewCommand(this.ToString(),
- () => {
- int index = parent.Children.IndexOf(node);
+ int index = item.ParentNode.Children.IndexOf(item);
- parent.AddChild(items[0], index + 1);
- parent.RemoveChild(node);
- items[0].AddChild(node);
+ var newitem = new MindNode(this) { Text = $"分支主题{index + 1}" };
+ newitem.AddTo(item.ParentNode, index);
+ item.RemoveFrom();
+ item.AddTo(newitem, -1, false);
+ newitems.Add(newitem);
+ }
- parent.LayoutUpdated();
- },
- () => {
- int index = parent.Children.IndexOf(items[0]);
- items[0].RemoveChild(node);
- parent.AddChild(node, index + 1);
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
+ },
+ () => {
+ foreach (var item in items)
+ {
+ if (item.ParentNode == null || item.ParentNode.ParentNode == null)
+ continue;
- parent.LayoutUpdated();
- });
+ var parent = item.ParentNode;
+ int index = item.ParentNode.ParentNode.Children.IndexOf(item.ParentNode);
+ item.RemoveFrom();
+ parent.RemoveFrom();
+ item.AddTo(parent.ParentNode, index);
+ }
- }
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
+ });
}
public void ExecuteAddPearCommand(object parameter)
{
List items = new List();
- if (parameter is MindNode pear)
+ List newitems = new List();
+ if (parameter is MindNode node)
{
-
+ items.Add(node);
}
else if (parameter is IEnumerable para)
{
- pear = para.FirstOrDefault();//第一个固定为同级节点
- items = para.Skip(1).ToList();
+ items.AddRange(para);
}
else
{
- pear = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
- if (pear.Parent is MindNode parent)
- {
- if (items?.Count == 0)
- {
- var node = new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" };
- items.Add(node);
- }
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in items)
+ {
+ if (item.ParentNode == null)
+ continue;
- DoCommandManager.DoNewCommand(this.ToString(),
- () => {
- int index = parent.Children.IndexOf(pear);
- for (int i = 0; i < items.Count; i++)
- {
- parent.AddChild(items[i], index + i + 1);
- }
+ int index = item.ParentNode.Children.IndexOf(item);
+ var newitem = new MindNode(this) { Text = $"分支主题{item.ParentNode.Children.Count + 1}" };
+ item.IsSelected = false;
+ newitem.AddTo(item.ParentNode, index + 1);
+ newitems.Add(newitem);
+ }
- parent.LayoutUpdated();
- },
- () => {
- for (int i = 0; i < items.Count; i++)
- {
- parent.RemoveChild(items[i]);
- }
- parent.LayoutUpdated();
- });
-
- }
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
+ },
+ () => {
+ foreach (var item in newitems)
+ {
+ item.RemoveFrom();
+ item.LayoutUpdated();
+ }
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
+ });
}
private void ExecuteMoveBackCommand(object parameter)
{
+ List items = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
+ }
+ else if (parameter is IEnumerable para)
+ {
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
- }
-
- if (node.Parent is MindNode parent)
- {
- DoCommandManager.DoNewCommand(this.ToString(),
- () => {
- int index = parent.Children.IndexOf(node);
- if (index < parent.Children.Count - 1)
- {
- parent.RemoveChild(node);
- parent.AddChild(node, index + 1);
- parent.LayoutUpdated();
- }
- },
- () => {
- int index = parent.Children.IndexOf(node);
- if (index > 0)
- {
- parent.RemoveChild(node);
- parent.AddChild(node, index - 1);
- parent.LayoutUpdated();
- }
- });
+ items.AddRange(SelectedItems.OfType());
}
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ MoveBack(items);
+ },
+ () => {
+ MoveForward(items);
+ });
}
private void ExecuteMoveForwardCommand(object parameter)
{
+ List items = new List();
+ List newitems = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
+ }
+ else if (parameter is IEnumerable para)
+ {
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
- if (node.Parent is MindNode parent)
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ MoveForward(items);
+ },
+ () => {
+ MoveBack(items);
+ });
+ }
+
+ private void MoveBack(List items)
+ {
+ foreach (var item in items)
{
- DoCommandManager.DoNewCommand(this.ToString(),
- () => {
- int index = parent.Children.IndexOf(node);
- if (index > 0)
- {
- parent.RemoveChild(node);
- parent.AddChild(node, index - 1);
- parent.LayoutUpdated();
- }
- },
- () => {
- int index = parent.Children.IndexOf(node);
- if (index < parent.Children.Count - 1)
- {
- parent.RemoveChild(node);
- parent.AddChild(node, index + 1);
- parent.LayoutUpdated();
- }
- });
- }
+ if (item.ParentNode == null)
+ continue;
+ var parent = item.ParentNode;
+ int index = parent.Children.IndexOf(item);
+
+ if (index < parent.Children.Count - 1)
+ {
+ item.RemoveFrom();
+ item.AddTo(parent, index + 1);
+ }
+ }
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
+ }
+
+ private void MoveForward(List items)
+ {
+ foreach (var item in items)
+ {
+ if (item.ParentNode == null)
+ continue;
+
+ var parent = item.ParentNode;
+ int index = parent.Children.IndexOf(item);
+
+ if (index > 0)
+ {
+ item.RemoveFrom();
+ item.AddTo(parent, index - 1);
+ }
+ }
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
}
protected override bool Delete(object parameter)
{
- List nodes = new List();
+ List items = new List();
List others = new List();
- if (parameter is MindNode node1)
+ if (parameter is MindNode node)
{
- nodes.Add(node1);
+ items.Add(node);
}
else if (parameter is IEnumerable para)
{
- nodes.AddRange(para);
+ items.AddRange(para);
}
else
{
- nodes.AddRange(SelectedItems.OfType());
+ items.AddRange(SelectedItems.OfType());
- others = SelectedItems.Where(p => !(p is MindNode)).ToList();
+ others = SelectedItems.Where(p => !(p is MindNode)).ToList();
}
- if (nodes.FirstOrDefault()?.IsEditing != false)
+ if (items.FirstOrDefault()?.IsEditing != false)
{
return false;
}
- if (nodes.Any())
+ if (items.Any())
{
- Dictionary indexs = nodes.ToDictionary(p => p, p => p.ParentNode != null ? p.ParentNode.Children.IndexOf(p) : 0);
+ //把子节点都加上
+ foreach (var item in items.ToList())
+ {
+ var children = item.GetChildren();
+ items.AddRange(children);
+ }
+ //去重
+ items = items.Distinct().ToList();
+
+ Dictionary> indexs = items.ToDictionary(p => p, p => new Tuple(p.ParentNode != null ? p.ParentNode.Children.IndexOf(p) : 0, p.ParentNode));
DoCommandManager.DoNewCommand(this.ToString(),
() => {
- foreach (var node in nodes)
+
+ foreach (var item in items.ToList())
{
- node.Remove(true);
+ item.RemoveFrom();
}
- RootItems.ForEach(p => p.LayoutUpdated());
if (others.Any())
{
base.Delete(others);
}
+
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
},
() => {
- foreach (var node in nodes)
+ if (others.Any())
{
- node.ParentNode.AddChild(node, indexs[node]);
+ base.Add(others);
}
- RootItems.ForEach(p => p.LayoutUpdated());
+
+ foreach (var item in items)
+ {
+ item.AddTo(indexs[item].Item2, indexs[item].Item1, false);
+ if (item.ParentId == Guid.Empty)
+ {
+ item.Offset = new PointBase();
+ }
+ }
+
+ items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.LayoutUpdated());
});
return true;
}
@@ -671,7 +748,6 @@ namespace AIStudio.Wpf.Mind.ViewModels
#region 复制,粘贴
protected override void FixOtherInfo(List items)
{
-
List parents = new List();
foreach (var item in items.OfType())
{
@@ -698,100 +774,202 @@ namespace AIStudio.Wpf.Mind.ViewModels
{
if (obj is object[] array && array.Length == 2)
{
- SelectedItems.OfType().ToList().ForEach(p => {
- if (p.LinkInfo == null)
- p.LinkInfo = new LinkInfo();
-
- p.LinkInfo.Link = array[0]?.ToString();
- p.LinkInfo.Text = array[1]?.ToString();
-
- });
+ if (string.IsNullOrEmpty(array[0]?.ToString()))
+ {
+ return;
+ }
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.LinkInfo);
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.LinkInfo = new LinkInfo(array[0]?.ToString(), array[1]?.ToString());
+ });
+ },
+ () => {
+ foreach (var linkInfo in infos)
+ {
+ linkInfo.Key.LinkInfo = linkInfo.Value;
+ }
+ });
}
}
private void ExecuteRemoveLinkCommand(object obj)
{
- SelectedItems.OfType().ToList().ForEach(p => {
- if (p.LinkInfo != null)
- {
- p.LinkInfo.Link = null;
- p.LinkInfo.Text = null;
- }
- });
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.LinkInfo);
+
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.LinkInfo = null;
+ });
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.LinkInfo = info.Value;
+ }
+ });
}
private void ExecuteAddImageCommand(object obj)
{
if (obj is object[] array && array.Length == 2)
{
- SelectedItems.OfType().ToList().ForEach(p => {
- if (p.ImageInfo == null)
- p.ImageInfo = new ImageInfo();
-
- p.ImageInfo.Url = array[0]?.ToString();
- p.ImageInfo.Text = array[1]?.ToString();
-
- });
+ if (string.IsNullOrEmpty(array[0]?.ToString()))
+ {
+ return;
+ }
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.ImageInfo);
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.ImageInfo = new ImageInfo(array[0]?.ToString(), array[1]?.ToString());
+ });
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.ImageInfo = info.Value;
+ }
+ });
}
}
private void ExecuteRemoveImageCommand(object obj)
{
- SelectedItems.OfType().ToList().ForEach(p => {
- if (p.ImageInfo != null)
- {
- p.ImageInfo.Url = null;
- p.ImageInfo.Text = null;
- }
- });
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.ImageInfo);
+
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.ImageInfo = null;
+ });
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.ImageInfo = info.Value;
+ }
+ });
}
private void ExecuteAddRemarkCommand(object obj)
{
- SelectedItems.OfType().ToList().ForEach(p => p.Remark = obj?.ToString());
+
+ if (string.IsNullOrEmpty(obj?.ToString()))
+ {
+ return;
+ }
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.Remark);
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.Remark = obj?.ToString();
+ });
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Remark = info.Value;
+ }
+ });
+
}
private void ExecuteRemoveRemarkCommand(object obj)
{
- SelectedItems.OfType().ToList().ForEach(p => p.Remark = null);
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.Remark);
+
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.Remark = null;
+ });
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Remark = info.Value;
+ }
+ });
}
private void ExecuteAddPriorityCommand(object obj)
{
- if (double.TryParse(obj.ToString(), out var priority))
- {
- SelectedItems.OfType().ToList().ForEach(p => p.Priority = priority);
- }
- else
- {
- SelectedItems.OfType().ToList().ForEach(p => p.Priority = null);
- }
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.Priority);
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ if (double.TryParse(obj.ToString(), out var priority))
+ {
+ SelectedItems.OfType().ToList().ForEach(p => p.Priority = priority);
+ }
+ else
+ {
+ SelectedItems.OfType().ToList().ForEach(p => p.Priority = null);
+ }
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Priority = info.Value;
+ }
+ });
+
}
private void ExecuteAddRatioCommand(object obj)
{
- if (double.TryParse(obj.ToString(), out var rate))
- {
- SelectedItems.OfType().ToList().ForEach(p => p.Rate = rate);
- }
- else
- {
- SelectedItems.OfType().ToList().ForEach(p => p.Rate = null);
- }
+ Dictionary infos = SelectedItems.OfType().ToDictionary(p => p, p => p.Rate);
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ if (double.TryParse(obj.ToString(), out var rate))
+ {
+ SelectedItems.OfType().ToList().ForEach(p => p.Rate = rate);
+ }
+ else
+ {
+ SelectedItems.OfType().ToList().ForEach(p => p.Rate = null);
+ }
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.Rate = info.Value;
+ }
+ });
}
private void ExecuteAddTagCommand(object obj)
{
- SelectedItems.OfType().ToList().ForEach(p => {
- p.Tags.Add(obj?.ToString());
- });
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.Tags.Add(obj?.ToString());
+ });
+ },
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.Tags.Remove(obj?.ToString());
+ });
+ });
+
}
private void ExecuteRemoveTagCommand(object obj)
{
- SelectedItems.OfType().ToList().ForEach(p => {
- p.Tags.Remove(obj?.ToString());
- });
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.Tags.Remove(obj?.ToString());
+ });
+ },
+ () => {
+ SelectedItems.OfType().ToList().ForEach(p => {
+ p.Tags.Add(obj?.ToString());
+ });
+ });
+
}
#endregion
@@ -800,56 +978,90 @@ namespace AIStudio.Wpf.Mind.ViewModels
{
if (obj is MindType mindType)
{
+ MindType = mindType;
+ }
+ }
+
+ private void ExecutedChangeMindType(MindType oldvalue, MindType newvalue)
+ {
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
Items.OfType().ToList().ForEach(item => { item.InitLayout(true); });
Items.OfType().ToList().ForEach(item => { item.InitConnectLayout(); });
RootItems?.ForEach(p => p.LayoutUpdated());
- }
+ },
+ () => {
+ _mindType = oldvalue;
+ Items.OfType().ToList().ForEach(item => { item.InitLayout(true); });
+ Items.OfType().ToList().ForEach(item => { item.InitConnectLayout(); });
+ RootItems?.ForEach(p => p.LayoutUpdated());
+ });
}
private void ExecutedChangeMindThemeCommand(object obj)
{
- if (obj is string mindThemeModel)
+ string oldmindThemeModel = MindThemeModel.Name;
+ if (obj is string mindThemeModel && mindThemeModel != oldmindThemeModel)
{
- MindThemeModel = MindThemeHelper.GetTheme(mindThemeModel);
- if (MindThemeModel?.Dark == true)
- {
- PageBackground = Colors.Black;
- }
- else
- {
- PageBackground = Colors.White;
- }
- Items.OfType().ToList().ForEach(item => { item.ThemeChange(); });
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ MindThemeModel = MindThemeHelper.GetTheme(mindThemeModel);
+ if (MindThemeModel?.Dark == true)
+ {
+ PageBackground = Colors.Black;
+ }
+ else
+ {
+ PageBackground = Colors.White;
+ }
+ Items.OfType().ToList().ForEach(item => { item.ThemeChange(); });
+ },
+ () => {
+ MindThemeModel = MindThemeHelper.GetTheme(oldmindThemeModel);
+ if (MindThemeModel?.Dark == true)
+ {
+ PageBackground = Colors.Black;
+ }
+ else
+ {
+ PageBackground = Colors.White;
+ }
+ Items.OfType().ToList().ForEach(item => { item.ThemeChange(); });
+ });
}
}
private void ExecutedClearThemeCommand(object parameter)
{
- List nodes = new List();
- if (parameter is MindNode node1)
+ List items = new List();
+ if (parameter is MindNode node)
{
- nodes.Add(node1);
+ items.Add(node);
}
else if (parameter is IEnumerable para)
{
- nodes.AddRange(para);
+ items.AddRange(para);
}
else
{
- nodes.AddRange(SelectedItems.OfType());
+ items.AddRange(SelectedItems.OfType());
}
- if (nodes.Any())
+ if (items.Any())
{
+ Dictionary infos = items.OfType().ToDictionary(p => p, p => MindThemeHelper.GetThemeModel(p));
DoCommandManager.DoNewCommand(this.ToString(),
() => {
- foreach (var node in nodes)
+ foreach (var item in items)
{
- node.ThemeChange();
+ item.ThemeChange();
}
},
() => {
- //ToDo
+ foreach (var info in infos)
+ {
+ MindThemeHelper.SetThemeModel(info.Key, info.Value);
+ }
});
}
}
@@ -876,37 +1088,40 @@ namespace AIStudio.Wpf.Mind.ViewModels
{
if (_formatNode != null)
{
- List nodes = new List();
- if (parameter is MindNode node1)
+ List items = new List();
+ if (parameter is MindNode node)
{
- nodes.Add(node1);
+ items.Add(node);
}
else if (parameter is IEnumerable para)
{
- nodes.AddRange(para);
+ items.AddRange(para);
}
else
{
- nodes.AddRange(SelectedItems.OfType());
+ items.AddRange(SelectedItems.OfType());
}
- if (nodes.Any())
+ if (items.Any())
{
+ Dictionary> infos = items.OfType().ToDictionary(p => p, p => new Tuple(MindThemeHelper.GetColorViewModel(p), MindThemeHelper.GetFontViewModel(p)));
DoCommandManager.DoNewCommand(this.ToString(),
() => {
- foreach (var node in nodes)
+ foreach (var item in items)
{
- CopyHelper.CopyPropertyValue(_formatNode.ColorViewModel, node.ColorViewModel);
- CopyHelper.CopyPropertyValue(_formatNode.FontViewModel, node.FontViewModel);
+ CopyHelper.CopyPropertyValue(_formatNode.ColorViewModel, item.ColorViewModel);
+ CopyHelper.CopyPropertyValue(_formatNode.FontViewModel, item.FontViewModel);
}
},
() => {
- //ToDo
+ foreach (var info in infos)
+ {
+ CopyHelper.CopyPropertyValue(info.Value.Item1, info.Key.ColorViewModel);
+ CopyHelper.CopyPropertyValue(info.Value.Item2, info.Key.FontViewModel);
+ }
});
}
-
}
-
}
#endregion
@@ -916,106 +1131,230 @@ namespace AIStudio.Wpf.Mind.ViewModels
var rootitem = MindSelectedItem?.RootNode;
if (rootitem != null)
{
- rootitem.Left = (PageSize.Width - rootitem.ItemWidth) / 2;
- rootitem.Top = (PageSize.Height - rootitem.ItemHeight) / 2;
- rootitem?.LayoutUpdated();
- FitViewModel = new FitViewModel() { BoundingRect = rootitem.GetBounds() };
+ var left = rootitem.Left;
+ var top = rootitem.Top;
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ Move(rootitem, null, null);
+ },
+ () => {
+ Move(rootitem, left, top);
+ });
}
}
+ private void Move(MindNode rootitem, double? left, double? top)
+ {
+ if (left == null)
+ left = (PageSize.Width - rootitem.ItemWidth) / 2;
+ if (top == null)
+ top = (PageSize.Height - rootitem.ItemHeight) / 2;
+ rootitem.Left = left.Value;
+ rootitem.Top = top.Value;
+ rootitem?.LayoutUpdated();
+ FitViewModel = new FitViewModel() { BoundingRect = rootitem.GetBounds() };
+ }
+
private void ExecutedExpand2LevelCommand(object obj)
{
int level = 0;
- int.TryParse(obj?.ToString(), out level);
- foreach (var item in Items.OfType())
+ if (int.TryParse(obj?.ToString(), out level))
{
- if (item.NodeLevel == 0)
- {
- continue;
- }
- else if (item.NodeLevel < level)
- {
- item.IsExpanded = true;
- }
- else
- {
- item.IsExpanded = false;
- }
+ Dictionary infos = Items.OfType().ToDictionary(p => p, p => p.IsExpanded);
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in Items.OfType())
+ {
+ if (item.NodeLevel == 0)
+ {
+ continue;
+ }
+ else if (item.NodeLevel < level)
+ {
+ item.IsExpanded = true;
+ }
+ else
+ {
+ item.IsExpanded = false;
+ }
+ }
+ },
+ () => {
+ foreach (var info in infos)
+ {
+ info.Key.IsExpanded = info.Value;
+ }
+ });
}
}
protected void ExecuteSelectBrotherCommand(object parameter)
{
+ List items = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
+ }
+ else if (parameter is IEnumerable para)
+ {
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
- if (node != null && node.ParentNode != null)
+ if (items.Any())
{
- foreach (var child in node.ParentNode.Children)
- {
- child.IsSelected = true;
- }
+ List selecteditems = new List();
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in items)
+ {
+ if (item != null && item.ParentNode != null)
+ {
+ foreach (var child in item.ParentNode.Children)
+ {
+ if (child.IsSelected != true)
+ {
+ child.IsSelected = true;
+ selecteditems.Add(child);
+ }
+ }
+ }
+ }
+ },
+ () => {
+ foreach (var item in selecteditems)
+ {
+ item.IsSelected = false;
+ }
+ });
}
}
protected void ExecuteSelectPearCommand(object parameter)
{
+ List items = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
+ }
+ else if (parameter is IEnumerable para)
+ {
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
- if (node != null)
+ if (items.Any())
{
- foreach (var item in Items.OfType().Where(p => p.NodeLevel == node.NodeLevel))
- {
- item.IsSelected = true;
- }
+ List selecteditems = new List();
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in items)
+ {
+ foreach (var pear in Items.OfType().Where(p => p.RootNode == item.RootNode && p.NodeLevel == item.NodeLevel))
+ {
+ if (pear.IsSelected != true)
+ {
+ pear.IsSelected = true;
+ selecteditems.Add(pear);
+ }
+ }
+ }
+ },
+ () => {
+ foreach (var item in selecteditems)
+ {
+ item.IsSelected = false;
+ }
+ });
}
}
protected void ExecuteSelectRouteCommand(object parameter)
{
+ List items = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
+ }
+ else if (parameter is IEnumerable para)
+ {
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
-
- if (node != null)
+ if (items.Any())
{
- GetParent(node).ForEach(p => p.IsSelected = true);
+ List selecteditems = new List();
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in items)
+ {
+ var parents = item.GetParent();
+ foreach (var parent in parents)
+ {
+ if (parent.IsSelected != true)
+ {
+ parent.IsSelected = true;
+ selecteditems.Add(parent);
+ }
+ }
+ }
+ }, () => {
+ foreach (var item in selecteditems)
+ {
+ item.IsSelected = false;
+ }
+ });
}
}
protected void ExecuteSelectChildCommand(object parameter)
{
+ List items = new List();
if (parameter is MindNode node)
{
-
+ items.Add(node);
+ }
+ else if (parameter is IEnumerable para)
+ {
+ items.AddRange(para);
}
else
{
- node = SelectedItem as MindNode;
+ items.AddRange(SelectedItems.OfType());
}
-
- if (node != null)
+ if (items.Any())
{
- GetChildren(node).ForEach(p => p.IsSelected = true);
- }
+ List selecteditems = new List();
+ DoCommandManager.DoNewCommand(this.ToString(),
+ () => {
+ foreach (var item in items)
+ {
+ var children = item.GetChildren();
+ foreach (var child in children)
+ {
+ if (child.IsSelected != true)
+ {
+ child.IsSelected = true;
+ selecteditems.Add(child);
+ }
+ }
+ }
+ }, () => {
+ foreach (var item in selecteditems)
+ {
+ item.IsSelected = false;
+ }
+ });
+ }
}
#endregion
diff --git a/AIStudio.Wpf.Mind/ViewModels/MindNode.cs b/AIStudio.Wpf.Mind/ViewModels/MindNode.cs
index 1a2dde6..1ab6a85 100644
--- a/AIStudio.Wpf.Mind/ViewModels/MindNode.cs
+++ b/AIStudio.Wpf.Mind/ViewModels/MindNode.cs
@@ -87,8 +87,6 @@ namespace AIStudio.Wpf.Mind.ViewModels
MoveBackCommand = (Root as IMindDiagramViewModel)?.MoveBackCommand;
BuildMenuOptions();
Tags = new ObservableCollection();
- LinkInfo = new LinkInfo();
- ImageInfo = new ImageInfo();
}
protected override void InitNew()
@@ -103,14 +101,14 @@ namespace AIStudio.Wpf.Mind.ViewModels
this.PropertyChanged -= this.Item_PropertyChanged;
IsInnerConnector = true;
- MindLayout.Appearance(this, MindThemeModel, initAppearance);
+ MindLayout.Appearance(this, MindThemeModel, initAppearance);
this.PropertyChanged += this.Item_PropertyChanged;
}
public void ThemeChange()
{
MindThemeHelper.ThemeChange(this, MindThemeModel);
- }
+ }
protected override void LoadDesignerItemViewModel(SelectableItemBase designerbase)
{
@@ -121,8 +119,8 @@ namespace AIStudio.Wpf.Mind.ViewModels
Spacing = designer.Spacing;
Offset = designer.Offset;
IsExpanded = designer.IsExpanded;
- LinkInfo = new LinkInfo() { Link = designer.LinkInfoItem?.Link, Text = designer.LinkInfoItem?.Text };
- ImageInfo = new ImageInfo() { Url = designer.ImageInfoItem?.Url, Text = designer.ImageInfoItem?.Text };
+ LinkInfo = new LinkInfo(designer.LinkInfoItem?.Url, designer.LinkInfoItem?.Text);
+ ImageInfo = new ImageInfo(designer.ImageInfoItem?.Url, designer.ImageInfoItem?.Text);
Remark = designer.Remark;
Priority = designer.Priority;
Rate = designer.Rate;
@@ -306,15 +304,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
}
set
{
- if (_linkInfo != null)
- {
- _linkInfo.PropertyChanged -= Item_PropertyChanged;
- }
SetProperty(ref _linkInfo, value);
- if (_linkInfo != null)
- {
- _linkInfo.PropertyChanged += Item_PropertyChanged; ;
- }
}
}
@@ -327,15 +317,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
}
set
{
- if (_imageInfo != null)
- {
- _imageInfo.PropertyChanged -= Item_PropertyChanged;
- }
SetProperty(ref _imageInfo, value);
- if (_imageInfo != null)
- {
- _imageInfo.PropertyChanged += Item_PropertyChanged;
- }
}
}
@@ -491,52 +473,35 @@ namespace AIStudio.Wpf.Mind.ViewModels
#endregion
#region 操作
- public void AddChild(MindNode item, int index = -1)
+ public void AddTo(MindNode parent, int index = -1, bool isSelected = true)
{
+ //parent为空,为根节点
if (index >= 0)
{
- this.Children.Insert(index, item);
+ parent?.Children.Insert(index, this);
}
else
{
- this.Children.Add(item);
+ parent?.Children.Add(this);
}
- item.Parent = this;
- item.ParentId = this.Id;
- item.InitLayout(true);//因为节点的层级不同的样式,所以需要Parent确定后才能初始化
+ this.Parent = parent;
+ this.ParentId = parent?.Id ?? Guid.Empty;
+ this.InitLayout(true);//因为节点的层级不同的样式,所以需要Parent确定后才能初始化
+ this.InitConnectLayout();
- ConnectionViewModel connector = MindLayout?.GetOrSetConnectionViewModel(this, item);
- Root?.Add(new SelectableDesignerItemViewModelBase[] { item, connector });
- connector.ZIndex = -1;
- connector.IsSelected = false;
- item.IsSelected = false;
- this.IsSelected = true;
- }
+ Root?.Add(this);
- public void RemoveChild(MindNode item, bool removeall = false)
- {
- item.PropertyChanged -= Item_PropertyChanged;
-
- this.Children.Remove(item);
-
- var connectors = Root?.Items.OfType().Where(p => p.SinkConnectorInfoFully?.DataItem == item).ToList();
-
- Root?.Remove(item);
- Root?.Remove(connectors);
-
- if (removeall)
+ if (isSelected)
{
- if (item.Children?.Count > 0)
+ if (parent != null)
{
- foreach (var child in item.Children.ToList())
- {
- item.RemoveChild(child, removeall);
- }
+ parent.IsSelected = false;
}
+ this.IsSelected = true;
}
}
- public void Remove(bool removeall = false)
+ public void RemoveFrom()
{
this.PropertyChanged -= Item_PropertyChanged;
if (this.ParentNode != null)
@@ -548,16 +513,16 @@ namespace AIStudio.Wpf.Mind.ViewModels
Root?.Remove(this);
Root?.Remove(connectors);
- if (removeall)
- {
- if (this.Children?.Count > 0)
- {
- foreach (var child in this.Children.ToList())
- {
- child.Remove(removeall);
- }
- }
- }
+ //if (removeall)
+ //{
+ // if (this.Children?.Count > 0)
+ // {
+ // foreach (var child in this.Children.ToList())
+ // {
+ // child.RemoveFrom(removeall);
+ // }
+ // }
+ //}
}
public void InitConnectLayout()
@@ -570,16 +535,15 @@ namespace AIStudio.Wpf.Mind.ViewModels
else if (ParentNode != null)
{
connector = MindLayout?.GetOrSetConnectionViewModel(ParentNode, this, null);
- Root?.Add(new SelectableDesignerItemViewModelBase[] { connector });
+ Root?.Add(new SelectableDesignerItemViewModelBase[] { connector });
connector.ZIndex = -1;
connector.IsSelected = false;
}
}
#endregion
-
private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
- if (GetLevel1Node()?.LayoutUpdating == true) return;
+ if (GetLevel1Node()?.LayoutUpdating == true) return;
switch (e.PropertyName)
{
@@ -601,7 +565,6 @@ namespace AIStudio.Wpf.Mind.ViewModels
case nameof(Rate):
case nameof(Priority):
case nameof(Remark):
- case nameof(LinkInfo.Link):
{
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
@@ -616,16 +579,31 @@ namespace AIStudio.Wpf.Mind.ViewModels
}
break;
}
- case nameof(ImageInfo.Url):
+ case nameof(LinkInfo):
{
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
- if (string.IsNullOrEmpty(valuePropertyChangedEventArgs.OldValue?.ToString()) && !string.IsNullOrEmpty(valuePropertyChangedEventArgs.NewValue?.ToString()))
+ if (valuePropertyChangedEventArgs.OldValue == null && valuePropertyChangedEventArgs.NewValue != null)
+ {
+ ItemWidth += 24;
+ }
+ else if (valuePropertyChangedEventArgs.OldValue != null && valuePropertyChangedEventArgs.NewValue == null)
+ {
+ ItemWidth -= 24;
+ }
+ }
+ break;
+ }
+ case nameof(ImageInfo):
+ {
+ if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
+ {
+ if (valuePropertyChangedEventArgs.OldValue == null && valuePropertyChangedEventArgs.NewValue != null)
{
ItemWidth = Math.Max(ItemWidth, 160);
ItemHeight += 135;
}
- else if (!string.IsNullOrEmpty(valuePropertyChangedEventArgs.OldValue?.ToString()) && string.IsNullOrEmpty(valuePropertyChangedEventArgs.NewValue?.ToString()))
+ else if (valuePropertyChangedEventArgs.OldValue != null && valuePropertyChangedEventArgs.NewValue == null)
{
ItemHeight -= 135;
}
@@ -664,6 +642,32 @@ namespace AIStudio.Wpf.Mind.ViewModels
return node;
}
+ public List GetParent()
+ {
+ var node = this;
+ List mindnode = new List();
+ while (node.ParentNode != null)
+ {
+ mindnode.Add(node.ParentNode);
+ node = node.ParentNode;
+ }
+ return mindnode;
+ }
+
+ public List GetChildren()
+ {
+ List mindnode = new List();
+ if (this.Children != null)
+ {
+ foreach (var child in this.Children)
+ {
+ mindnode.Add(child);
+ mindnode.AddRange(child.GetChildren());
+ }
+ }
+ return mindnode;
+ }
+
protected void UpdateOffsetX(double oldvalue, double newvalue)
{
Offset += new VectorBase(newvalue - oldvalue, 0);
@@ -682,61 +686,63 @@ namespace AIStudio.Wpf.Mind.ViewModels
#endregion
}
- public class LinkInfo : BindableBase
+ public class LinkInfo
{
- private string _link;
- public string Link
+ public string Url
{
- get
- {
- return _link;
- }
- set
- {
- SetProperty(ref _link, value);
- }
+ get; set;
}
- private string _text;
public string Text
{
- get
- {
- return _text;
- }
- set
- {
- SetProperty(ref _text, value);
- }
+ get; set;
+ }
+
+ public LinkInfo()
+ {
+
+ }
+
+ public LinkInfo(string url, string text)
+ {
+ Url = url;
+ Text = text;
+ }
+
+ public LinkInfo(LinkInfo info)
+ {
+ Url = info?.Url;
+ Text = info?.Text;
}
}
- public class ImageInfo : BindableBase
+ public class ImageInfo
{
- private string _url;
public string Url
{
- get
- {
- return _url;
- }
- set
- {
- SetProperty(ref _url, value);
- }
+ get; set;
}
- private string _text;
public string Text
{
- get
- {
- return _text;
- }
- set
- {
- SetProperty(ref _text, value);
- }
+ get; set;
+ }
+
+ public ImageInfo()
+ {
+
+ }
+
+ public ImageInfo(string url, string text)
+ {
+ Url = url;
+ Text = text;
+ }
+
+ public ImageInfo(ImageInfo info)
+ {
+ Url = info?.Url;
+ Text = info?.Text;
}
}
}