EnableSnapping完成

This commit is contained in:
艾竹
2023-01-26 20:05:21 +08:00
parent b5867c148e
commit 04db0ef13b
14 changed files with 392 additions and 32 deletions

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
class PathGeneratorsViewModel : BaseViewModel
{
public PathGeneratorsViewModel()
{
Title = "Link 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.";
_service.ColorViewModel.FillColor.Color = System.Windows.Media.Colors.Orange;
DiagramViewModel = new DiagramViewModel();
DiagramViewModel.PageSizeType = PageSizeType.Custom;
DiagramViewModel.PageSize = new Size(double.NaN, double.NaN);
DefaultDesignerItemViewModel node1 = new DefaultDesignerItemViewModel() { Left = 50, Top = 80, Text = "1" };
DiagramViewModel.DirectAddItemCommand.Execute(node1);
DefaultDesignerItemViewModel node2 = new DefaultDesignerItemViewModel() { Left = 300, Top = 350, Text = "2" };
DiagramViewModel.DirectAddItemCommand.Execute(node2);
DefaultDesignerItemViewModel node3 = new DefaultDesignerItemViewModel() { Left = 400, Top = 100, Text = "3" };
DiagramViewModel.DirectAddItemCommand.Execute(node3);
ConnectionViewModel connector1 = new ConnectionViewModel(node1.RightConnector, node2.LeftConnector, DrawMode.ConnectingLineStraight, RouterMode.RouterNormal);
connector1.AddLabel("Straight");
DiagramViewModel.DirectAddItemCommand.Execute(connector1);
ConnectionViewModel connector2 = new ConnectionViewModel(node2.RightConnector, node3.LeftConnector, DrawMode.ConnectingLineSmooth, RouterMode.RouterNormal);
connector2.AddLabel("Smooth");
DiagramViewModel.DirectAddItemCommand.Execute(connector2);
}
}
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
class RoutersViewModel : BaseViewModel
{
public RoutersViewModel()
{
Title = "Link 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.";
_service.ColorViewModel.FillColor.Color = System.Windows.Media.Colors.Orange;
DiagramViewModel = new DiagramViewModel();
DiagramViewModel.PageSizeType = PageSizeType.Custom;
DiagramViewModel.PageSize = new Size(double.NaN, double.NaN);
DefaultDesignerItemViewModel node1 = new DefaultDesignerItemViewModel() { Left = 50, Top = 80, Text = "1" };
DiagramViewModel.DirectAddItemCommand.Execute(node1);
DefaultDesignerItemViewModel node2 = new DefaultDesignerItemViewModel() { Left = 300, Top = 350, Text = "2" };
DiagramViewModel.DirectAddItemCommand.Execute(node2);
DefaultDesignerItemViewModel node3 = new DefaultDesignerItemViewModel() { Left = 350, Top = 100, Text = "3" };
DiagramViewModel.DirectAddItemCommand.Execute(node3);
ConnectionViewModel connector1 = new ConnectionViewModel(node1.RightConnector, node2.LeftConnector, DrawMode.ConnectingLineSmooth, RouterMode.RouterNormal);
connector1.AddLabel("Normal");
DiagramViewModel.DirectAddItemCommand.Execute(connector1);
ConnectionViewModel connector2 = new ConnectionViewModel(node2.RightConnector, node3.LeftConnector, DrawMode.ConnectingLineStraight, RouterMode.RouterOrthogonal);
connector2.AddLabel("Orthogonal");
DiagramViewModel.DirectAddItemCommand.Execute(connector2);
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace AIStudio.Wpf.DiagramDesigner.Demo.ViewModels
{
class SnappingViewModel : BaseViewModel
{
public SnappingViewModel()
{
Title = "Link Snapping";
Info = "While dragging a new link, it will try to find (and link) to the closest target within a radius.";
_service.ColorViewModel.FillColor.Color = System.Windows.Media.Colors.Orange;
DiagramViewModel = new DiagramViewModel();
DiagramViewModel.PageSizeType = PageSizeType.Custom;
DiagramViewModel.PageSize = new Size(double.NaN, double.NaN);
DiagramViewModel.EnableSnapping = true;
DefaultDesignerItemViewModel node1 = new DefaultDesignerItemViewModel() { Left = 50, Top = 50, Text = "1" };
DiagramViewModel.DirectAddItemCommand.Execute(node1);
DefaultDesignerItemViewModel node2 = new DefaultDesignerItemViewModel() { Left = 300, Top = 300, Text = "2" };
DiagramViewModel.DirectAddItemCommand.Execute(node2);
DefaultDesignerItemViewModel node3 = new DefaultDesignerItemViewModel() { Left = 300, Top = 50, Text = "3" };
DiagramViewModel.DirectAddItemCommand.Execute(node3);
}
}
}

View File

@@ -0,0 +1,16 @@
<UserControl x:Class="AIStudio.Wpf.DiagramDesigner.Demo.Views.PathGeneratorsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
xmlns:controls="clr-namespace:AIStudio.Wpf.DiagramDesigner.Demo.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<!-- Diagram Control -->
<dd:DiagramControl x:Name="diagram" DataContext="{Binding DiagramViewModel}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<controls:TitleControl/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace AIStudio.Wpf.DiagramDesigner.Demo.Views
{
/// <summary>
/// PathGeneratorsView.xaml 的交互逻辑
/// </summary>
public partial class PathGeneratorsView : UserControl
{
public PathGeneratorsView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,16 @@
<UserControl x:Class="AIStudio.Wpf.DiagramDesigner.Demo.Views.RoutersView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
xmlns:controls="clr-namespace:AIStudio.Wpf.DiagramDesigner.Demo.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<!-- Diagram Control -->
<dd:DiagramControl x:Name="diagram" DataContext="{Binding DiagramViewModel}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<controls:TitleControl/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace AIStudio.Wpf.DiagramDesigner.Demo.Views
{
/// <summary>
/// RoutersView.xaml 的交互逻辑
/// </summary>
public partial class RoutersView : UserControl
{
public RoutersView()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,16 @@
<UserControl x:Class="AIStudio.Wpf.DiagramDesigner.Demo.Views.SnappingView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram"
xmlns:controls="clr-namespace:AIStudio.Wpf.DiagramDesigner.Demo.Controls"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<!-- Diagram Control -->
<dd:DiagramControl x:Name="diagram" DataContext="{Binding DiagramViewModel}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<controls:TitleControl/>
</Grid>
</UserControl>

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace AIStudio.Wpf.DiagramDesigner.Demo.Views
{
/// <summary>
/// SnappingView.xaml 的交互逻辑
/// </summary>
public partial class SnappingView : UserControl
{
public SnappingView()
{
InitializeComponent();
}
}
}

View File

@@ -17,8 +17,20 @@ namespace AIStudio.Wpf.DiagramDesigner
{ {
public class DesignerCanvas : Canvas public class DesignerCanvas : Canvas
{ {
private IDiagramViewModel _viewModel { get { return DataContext as IDiagramViewModel; } } private IDiagramViewModel _viewModel
private IDiagramServiceProvider _service { get { return DiagramServicesProvider.Instance.Provider; } } {
get
{
return DataContext as IDiagramViewModel;
}
}
private IDiagramServiceProvider _service
{
get
{
return DiagramServicesProvider.Instance.Provider;
}
}
private ConnectionViewModel partialConnection; private ConnectionViewModel partialConnection;
private List<Connector> connectorsHit = new List<Connector>(); private List<Connector> connectorsHit = new List<Connector>();
@@ -54,6 +66,22 @@ namespace AIStudio.Wpf.DiagramDesigner
} }
} }
private bool EnableSnapping
{
get
{
return _viewModel.EnableSnapping;
}
}
private double SnappingRadius
{
get
{
return _viewModel.SnappingRadius;
}
}
#region GridCellSize #region GridCellSize
public static readonly DependencyProperty GridCellSizeProperty = public static readonly DependencyProperty GridCellSizeProperty =
@@ -64,8 +92,14 @@ namespace AIStudio.Wpf.DiagramDesigner
public Size GridCellSize public Size GridCellSize
{ {
get { return (Size)GetValue(GridCellSizeProperty); } get
set { SetValue(GridCellSizeProperty, value); } {
return (Size)GetValue(GridCellSizeProperty);
}
set
{
SetValue(GridCellSizeProperty, value);
}
} }
#endregion #endregion
@@ -80,8 +114,14 @@ namespace AIStudio.Wpf.DiagramDesigner
public bool ShowGrid public bool ShowGrid
{ {
get { return (bool)GetValue(ShowGridProperty); } get
set { SetValue(ShowGridProperty, value); } {
return (bool)GetValue(ShowGridProperty);
}
set
{
SetValue(ShowGridProperty, value);
}
} }
#endregion #endregion
@@ -96,8 +136,14 @@ namespace AIStudio.Wpf.DiagramDesigner
public Color GridColor public Color GridColor
{ {
get { return (Color)GetValue(GridColorProperty); } get
set { SetValue(GridColorProperty, value); } {
return (Color)GetValue(GridColorProperty);
}
set
{
SetValue(GridColorProperty, value);
}
} }
#endregion #endregion
@@ -112,8 +158,14 @@ namespace AIStudio.Wpf.DiagramDesigner
public Size GridMarginSize public Size GridMarginSize
{ {
get { return (Size)GetValue(GridMarginSizeProperty); } get
set { SetValue(GridMarginSizeProperty, value); } {
return (Size)GetValue(GridMarginSizeProperty);
}
set
{
SetValue(GridMarginSizeProperty, value);
}
} }
#endregion #endregion
@@ -204,7 +256,10 @@ namespace AIStudio.Wpf.DiagramDesigner
private Connector sourceConnector; private Connector sourceConnector;
public Connector SourceConnector public Connector SourceConnector
{ {
get { return sourceConnector; } get
{
return sourceConnector;
}
set set
{ {
if (sourceConnector != value) if (sourceConnector != value)
@@ -218,7 +273,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2), Point point = new Point(rectangleBounds.Left + (rectangleBounds.Width / 2),
rectangleBounds.Bottom + (rectangleBounds.Height / 2)); rectangleBounds.Bottom + (rectangleBounds.Height / 2));
partialConnection = new ConnectionViewModel(_viewModel, sourceDataItem, new PartCreatedConnectorInfo(point.X, point.Y), DrawMode, RouterMode); partialConnection = new ConnectionViewModel(_viewModel, sourceDataItem, new PartCreatedConnectorInfo(point.X, point.Y), DrawMode, RouterMode);
_viewModel.DirectAddItemCommand.Execute(partialConnection); _viewModel.DirectAddItemCommand.Execute(partialConnection);
} }
} }
@@ -227,7 +282,10 @@ namespace AIStudio.Wpf.DiagramDesigner
private FullyCreatedConnectorInfo sourceConnectorInfo; private FullyCreatedConnectorInfo sourceConnectorInfo;
public FullyCreatedConnectorInfo SourceConnectorInfo public FullyCreatedConnectorInfo SourceConnectorInfo
{ {
get { return sourceConnectorInfo; } get
{
return sourceConnectorInfo;
}
set set
{ {
if (sourceConnectorInfo != value) if (sourceConnectorInfo != value)
@@ -288,7 +346,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{ {
if (connectorsHit.Count == 0) if (connectorsHit.Count == 0)
{ {
LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(rubberbandSelectionStartPoint.Value); LinkPointDesignerItemViewModel pointItemView = new LinkPointDesignerItemViewModel(rubberbandSelectionStartPoint.Value);
_viewModel.DirectAddItemCommand.Execute(pointItemView); _viewModel.DirectAddItemCommand.Execute(pointItemView);
SourceConnectorInfo = pointItemView.TopConnector; SourceConnectorInfo = pointItemView.TopConnector;
} }
@@ -311,8 +369,7 @@ namespace AIStudio.Wpf.DiagramDesigner
if (_service.DrawModeViewModel.CursorMode == CursorMode.Move) if (_service.DrawModeViewModel.CursorMode == CursorMode.Move)
{ {
_viewModel.SelectedItems.OfType<DesignerItemViewModelBase>().ToList().ForEach(p => _viewModel.SelectedItems.OfType<DesignerItemViewModelBase>().ToList().ForEach(p => {
{
p.Left = currentPoint.X; p.Left = currentPoint.X;
p.Top = currentPoint.Y; p.Top = currentPoint.Y;
}); });
@@ -325,6 +382,19 @@ namespace AIStudio.Wpf.DiagramDesigner
{ {
partialConnection.SinkConnectorInfo = new PartCreatedConnectorInfo(currentPoint.X, currentPoint.Y); partialConnection.SinkConnectorInfo = new PartCreatedConnectorInfo(currentPoint.X, currentPoint.Y);
HitTesting(currentPoint); HitTesting(currentPoint);
if (EnableSnapping)
{
var nearPort = FindNearPortToAttachTo();
if (nearPort != null || partialConnection.SinkConnectorInfoFully != null)
{
//var oldPort = _ongoingLink.TargetPort;
//_ongoingLink.SetTargetPort(nearPort);
//oldPort?.Refresh();
//nearPort?.Refresh();
partialConnection.SinkConnectorInfo = nearPort;
}
}
} }
} }
else else
@@ -377,6 +447,10 @@ namespace AIStudio.Wpf.DiagramDesigner
sinkDataItem.DataItem.Root.DirectRemoveItemCommand.Execute( sinkDataItem.DataItem.Root.DirectRemoveItemCommand.Execute(
sinkDataItem.DataItem.Root.Items[indexOfLastTempConnection]); sinkDataItem.DataItem.Root.Items[indexOfLastTempConnection]);
sinkDataItem.DataItem.Root.AddItemCommand.Execute(new ConnectionViewModel(_viewModel, sourceDataItem, sinkDataItem, DrawMode, RouterMode)); sinkDataItem.DataItem.Root.AddItemCommand.Execute(new ConnectionViewModel(_viewModel, sourceDataItem, sinkDataItem, DrawMode, RouterMode));
}
else if (partialConnection.IsFullConnection)
{
} }
else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine && connectorsHit.Count() == 1) else if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine && connectorsHit.Count() == 1)
{ {
@@ -403,7 +477,7 @@ namespace AIStudio.Wpf.DiagramDesigner
} }
} }
connectorsHit = new List<Connector>(); connectorsHit = new List<Connector>();
sourceConnector = null; sourceConnector = null;
sourceConnectorInfo = null; sourceConnectorInfo = null;
@@ -508,7 +582,7 @@ namespace AIStudio.Wpf.DiagramDesigner
itemBase.Suffix = System.IO.Path.GetExtension(itemBase.Icon).ToLower(); itemBase.Suffix = System.IO.Path.GetExtension(itemBase.Icon).ToLower();
itemBase.InitWidthAndHeight(); itemBase.InitWidthAndHeight();
itemBase.AutoSize(); itemBase.AutoSize();
itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2); itemBase.Left = Math.Max(0, position.X - itemBase.ItemWidth / 2);
itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2); itemBase.Top = Math.Max(0, position.Y - itemBase.ItemHeight / 2);
(DataContext as IDiagramViewModel).AddItemCommand.Execute(itemBase); (DataContext as IDiagramViewModel).AddItemCommand.Execute(itemBase);
@@ -516,5 +590,17 @@ namespace AIStudio.Wpf.DiagramDesigner
} }
e.Handled = true; e.Handled = true;
} }
public FullyCreatedConnectorInfo FindNearPortToAttachTo()
{
foreach (var port in _viewModel.Items.OfType<DesignerItemViewModelBase>().ToList().SelectMany(n => n.Connectors))
{
if (partialConnection.OnGoingPosition.DistanceTo(port.Position) < SnappingRadius &&
partialConnection.SourceConnectorInfo.CanAttachTo(port))
return port;
}
return null;
}
} }
} }

View File

@@ -44,8 +44,7 @@
</Path> </Path>
<Path x:Name="rightarrow" <Path x:Name="rightarrow"
Data="{Binding ShapeViewModel.SinkMarker.Path}" Data="{Binding ShapeViewModel.SinkMarker.Path}"
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
Width="{Binding ShapeViewModel.SinkMarker.Width}" Width="{Binding ShapeViewModel.SinkMarker.Width}"
Stretch="UniformToFill" Stretch="UniformToFill"
HorizontalAlignment="Left" HorizontalAlignment="Left"
@@ -61,8 +60,7 @@
</Path> </Path>
<Path x:Name="leftarrow" <Path x:Name="leftarrow"
Data="{Binding ShapeViewModel.SourceMarker.Path}" Data="{Binding ShapeViewModel.SourceMarker.Path}"
Visibility="{Binding Path=IsFullConnection, Converter={x:Static s:BoolToVisibilityConverter.Instance}}"
Width="{Binding ShapeViewModel.SourceMarker.Width}" Width="{Binding ShapeViewModel.SourceMarker.Width}"
Canvas.Left="{Binding StartPoint.X}" Canvas.Left="{Binding StartPoint.X}"
Canvas.Top="{Binding StartPoint.Y}" Canvas.Top="{Binding StartPoint.Y}"

View File

@@ -13,7 +13,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public FullyCreatedConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, ValueTypePoint valueTypePoint = 0) public FullyCreatedConnectorInfo(DesignerItemViewModelBase dataItem, ConnectorOrientation orientation, bool isInnerPoint = false, ValueTypePoint valueTypePoint = 0)
: base(orientation) : base(orientation)
{ {
this.DataItem = dataItem; this.Parent = dataItem;
this.IsInnerPoint = isInnerPoint; this.IsInnerPoint = isInnerPoint;
this.ValueTypePoint = valueTypePoint; this.ValueTypePoint = valueTypePoint;
if (IsInnerPoint == true) if (IsInnerPoint == true)
@@ -24,7 +24,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, designer) public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SelectableItemBase designer) : base(root, designer)
{ {
this.DataItem = dataItem; this.Parent = dataItem;
if (IsInnerPoint == true) if (IsInnerPoint == true)
{ {
BuildMenuOptions(); BuildMenuOptions();
@@ -33,7 +33,7 @@ namespace AIStudio.Wpf.DiagramDesigner
public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType) public FullyCreatedConnectorInfo(IDiagramViewModel root, DesignerItemViewModelBase dataItem, SerializableItem serializableItem, string serializableType) : base(root, serializableItem, serializableType)
{ {
this.DataItem = dataItem; this.Parent = dataItem;
if (IsInnerPoint == true) if (IsInnerPoint == true)
{ {
BuildMenuOptions(); BuildMenuOptions();
@@ -88,7 +88,10 @@ namespace AIStudio.Wpf.DiagramDesigner
public DesignerItemViewModelBase DataItem public DesignerItemViewModelBase DataItem
{ {
get; private set; get
{
return Parent as DesignerItemViewModelBase;
}
} }
private bool _showConnectors = false; private bool _showConnectors = false;
@@ -257,6 +260,8 @@ namespace AIStudio.Wpf.DiagramDesigner
} }
} }
} }
public virtual bool CanAttachTo(FullyCreatedConnectorInfo port) => port != this && !port.IsReadOnly && DataItem != port.DataItem;
} }

View File

@@ -366,6 +366,31 @@ namespace AIStudio.Wpf.DiagramDesigner
} }
} }
private bool _enableSnapping;
public bool EnableSnapping
{
get
{
return _enableSnapping;
}
set
{
SetProperty(ref _enableSnapping, value);
}
}
private double _snappingRadius = 50;
public double SnappingRadius
{
get
{
return _snappingRadius;
}
set
{
SetProperty(ref _snappingRadius, value);
}
}
private bool _isEditName; private bool _isEditName;
[Browsable(false)] [Browsable(false)]
@@ -1089,7 +1114,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}); });
} }
} }
private void ExecuteBringForwardCommand(object parameter) private void ExecuteBringForwardCommand(object parameter)
{ {
@@ -1391,7 +1416,7 @@ namespace AIStudio.Wpf.DiagramDesigner
SelectedItems.OfType<DesignerItemViewModelBase>().ToList(); SelectedItems.OfType<DesignerItemViewModelBase>().ToList();
List<ConnectionViewModel> selectedConnections = List<ConnectionViewModel> selectedConnections =
SelectedItems.OfType<ConnectionViewModel>().ToList(); SelectedItems.OfType<ConnectionViewModel>().ToList();
foreach (ConnectionViewModel connection in Items.OfType<ConnectionViewModel>()) foreach (ConnectionViewModel connection in Items.OfType<ConnectionViewModel>())
{ {
@@ -1444,7 +1469,7 @@ namespace AIStudio.Wpf.DiagramDesigner
foreach (var diagramItemData in copyitem.DesignerItems) foreach (var diagramItemData in copyitem.DesignerItems)
{ {
DesignerItemViewModelBase newItem = null; DesignerItemViewModelBase newItem = null;
Type type = TypeHelper.GetType(diagramItemData.ModelTypeName); Type type = TypeHelper.GetType(diagramItemData.ModelTypeName);
DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, this, diagramItemData, ".json") as DesignerItemViewModelBase; DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, this, diagramItemData, ".json") as DesignerItemViewModelBase;
@@ -1460,7 +1485,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{ {
items.Add(newItem); items.Add(newItem);
} }
} }
DirectAddItemCommand.Execute(items); DirectAddItemCommand.Execute(items);
OffsetX += 10; OffsetX += 10;
@@ -1751,7 +1776,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{ {
} }

View File

@@ -228,6 +228,14 @@ namespace AIStudio.Wpf.DiagramDesigner
{ {
get; set; get; set;
} }
bool EnableSnapping
{
get; set;
}
double SnappingRadius
{
get; set;
}
Size GridMarginSize Size GridMarginSize
{ {
get; set; get; set;