Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs
2023-03-05 21:30:53 +08:00

2299 lines
76 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using AIStudio.Wpf.DiagramDesigner.Geometrys;
using AIStudio.Wpf.DiagramDesigner.Helpers;
using AIStudio.Wpf.DiagramDesigner.Models;
using Newtonsoft.Json;
namespace AIStudio.Wpf.DiagramDesigner
{
public class DiagramViewModel : BindableBase, IDiagramViewModel
{
#region
public ObservableCollection<SelectableDesignerItemViewModelBase> Items { get; set; } = new ObservableCollection<SelectableDesignerItemViewModelBase>();
public List<SelectableDesignerItemViewModelBase> SelectedItems
{
get
{
return Items.Where(x => x.IsSelected).ToList();
}
}
public SelectableDesignerItemViewModelBase SelectedItem
{
get
{
return SelectedItems.FirstOrDefault();
}
}
private SelectionService selectionService;
public SelectionService SelectionService
{
get
{
if (selectionService == null)
selectionService = new SelectionService(this);
return selectionService;
}
}
private bool _isReadOnly;
public bool IsReadOnly
{
get
{
return _isReadOnly;
}
set
{
SetProperty(ref _isReadOnly, value);
}
}
public bool IsLoading
{
get; set;
}
public IDrawModeViewModel DrawModeViewModel
{
get; set;
}
public IColorViewModel ColorViewModel
{
get; set;
}
public IFontViewModel FontViewModel
{
get; set;
}
public IShapeViewModel ShapeViewModel
{
get; set;
}
private PageSizeType _pageSizeType = PageSizeType.A4;
public PageSizeType PageSizeType
{
get
{
return _pageSizeType;
}
set
{
SetProperty(ref _pageSizeType, value);
RaisePropertyChanged(nameof(PageSize));
}
}
private Size _pageSize = new Size(1000, 600);
public Size PageSize
{
get
{
if (PageSizeOrientation == PageSizeOrientation.Vertical)
{
return GetPageSize();
}
else
{
return new Size(GetPageSize().Height, GetPageSize().Width);
}
}
set
{
if (SetProperty(ref _pageSize, value))
{
RaisePropertyChanged(nameof(PhysicalPageSize));
}
}
}
public Size PhysicalPageSize
{
get
{
return new Size(ScreenHelper.WidthToMm(PageSize.Width), ScreenHelper.WidthToMm(PageSize.Height));
}
set
{
PageSize = new Size(ScreenHelper.MmToWidth(value.Width), ScreenHelper.MmToWidth(value.Height));
}
}
public Size GetPageSize()
{
Size size = _pageSize;
switch (PageSizeType)
{
case PageSizeType.A3: size = new Size(297, 420); break;
case PageSizeType.A4: size = new Size(210, 297); break;
case PageSizeType.A5: size = new Size(148, 210); break;
case PageSizeType.B4: size = new Size(257, 364); break;
case PageSizeType.B5: size = new Size(176, 250); break;
case PageSizeType.DLEnvelope: size = new Size(110, 220); break;
case PageSizeType.C5Envelope: size = new Size(162, 229); break;
case PageSizeType.Quarto: size = new Size(215, 275); break;
case PageSizeType.C6Quarto: size = new Size(114, 162); break;
case PageSizeType.B5Quarto: size = new Size(176, 250); break;
case PageSizeType.ItalyQuarto: size = new Size(110, 230); break;
case PageSizeType.A4small: size = new Size(210, 297); break;
case PageSizeType.GermanStdFanfold: size = new Size(215.9, 304.8); break;
case PageSizeType.GermanLegalFanfold: size = new Size(203.2, 330.2); break;
case PageSizeType.PRC16K: size = new Size(146, 215); break;
case PageSizeType.PRC32K: size = new Size(97, 151); break;
case PageSizeType.Letter: size = new Size(215.9, 279.4); break;
case PageSizeType.Folio: size = new Size(215.9, 330.2); break;
case PageSizeType.Legal: size = new Size(215.9, 355.6); break;
case PageSizeType.Executive: size = new Size(184.15, 266.7); break;
case PageSizeType.Statement: size = new Size(139.7, 215.9); break;
case PageSizeType.Envelope: size = new Size(104.77, 241.3); break;
case PageSizeType.MonarchEnvelope: size = new Size(98.425, 190.5); break;
case PageSizeType.Tabloid: size = new Size(279.4, 431.8); break;
case PageSizeType.LetterSmall: size = new Size(215.9, 279.4); break;
case PageSizeType.CSheet: size = new Size(431.8, 558.8); break;
case PageSizeType.DSheet: size = new Size(558.8, 863.6); break;
case PageSizeType.ESheet: size = new Size(863.6, 1117.6); break;
}
return new Size(ScreenHelper.MmToWidth(size.Width), ScreenHelper.MmToWidth(size.Height));
}
private PageSizeOrientation _pageSizeOrientation;
public PageSizeOrientation PageSizeOrientation
{
get
{
return _pageSizeOrientation;
}
set
{
SetProperty(ref _pageSizeOrientation, value);
RaisePropertyChanged(nameof(PageSize));
}
}
private PageUnit _pageUnit = PageUnit.cm;
[Browsable(false)]
public PageUnit PageUnit
{
get
{
return _pageUnit;
}
set
{
if (value != PageUnit.cm && value != PageUnit.inch)
{
return;
}
SetProperty(ref _pageUnit, value);
}
}
private Size _gridCellSize = new Size(100, 100);
public Size GridCellSize
{
get
{
return _gridCellSize;
}
set
{
SetProperty(ref _gridCellSize, value);
}
}
public double GridCellWidth
{
get
{
return _gridCellSize.Width;
}
set
{
_gridCellSize.Width = value;
RaisePropertyChanged(nameof(PhysicalGridCellWidth));
RaisePropertyChanged(nameof(GridCellSize));
}
}
public double GridCellHeight
{
get
{
return _gridCellSize.Height;
}
set
{
_gridCellSize.Height = value;
RaisePropertyChanged(nameof(PhysicalGridCellHeight));
RaisePropertyChanged(nameof(GridCellSize));
}
}
public Size PhysicalGridCellSize
{
get
{
return new Size(ScreenHelper.WidthToMm(GridCellSize.Width), ScreenHelper.WidthToMm(GridCellSize.Height));
}
set
{
GridCellSize = new Size(ScreenHelper.MmToWidth(value.Width), ScreenHelper.MmToWidth(value.Height));
}
}
public double PhysicalGridCellWidth
{
get
{
return ScreenHelper.WidthToMm(GridCellWidth);
}
set
{
GridCellWidth = ScreenHelper.MmToWidth(value);
}
}
public double PhysicalGridCellHeight
{
get
{
return ScreenHelper.WidthToMm(GridCellHeight);
}
set
{
GridCellHeight = ScreenHelper.MmToWidth(value);
}
}
private Color _pageBackground = Colors.White;
public Color PageBackground
{
get
{
return _pageBackground;
}
set
{
SetProperty(ref _pageBackground, value);
}
}
private bool _showGrid = true;
public bool ShowGrid
{
get
{
return _showGrid;
}
set
{
SetProperty(ref _showGrid, value);
}
}
private Color _gridColor = Colors.LightGray;
public Color GridColor
{
get
{
return _gridColor;
}
set
{
SetProperty(ref _gridColor, value);
}
}
private Size _gridMargin = new Size(28, 28);
public Size GridMarginSize
{
get
{
return _gridMargin;
}
set
{
SetProperty(ref _gridMargin, value);
}
}
public double GridMarginWidth
{
get
{
return _gridMargin.Width;
}
set
{
_gridMargin.Width = value;
RaisePropertyChanged(nameof(GridMarginSize));
}
}
public double GridMarginHeight
{
get
{
return _gridMargin.Height;
}
set
{
_gridMargin.Height = value;
RaisePropertyChanged(nameof(GridMarginSize));
}
}
public Size PhysicalGridMarginSize
{
get
{
return new Size(ScreenHelper.WidthToMm(GridMarginSize.Width), ScreenHelper.WidthToMm(GridMarginSize.Height));
}
set
{
GridMarginSize = new Size(ScreenHelper.MmToWidth(value.Width), ScreenHelper.MmToWidth(value.Height));
}
}
public double PhysicalGridMarginWidth
{
get
{
return ScreenHelper.WidthToMm(GridMarginWidth);
}
set
{
GridMarginWidth = ScreenHelper.MmToWidth(value);
}
}
public double PhysicalGridMarginHeight
{
get
{
return ScreenHelper.WidthToMm(GridMarginHeight);
}
set
{
GridMarginHeight = ScreenHelper.MmToWidth(value);
}
}
private double _zoomValue = 1;
[Browsable(false)]
public double ZoomValue
{
get
{
return _zoomValue;
}
set
{
SetProperty(ref _zoomValue, value);
}
}
private double _maximumZoomValue = 3;
[Browsable(false)]
public double MaximumZoomValue
{
get
{
return _maximumZoomValue;
}
set
{
SetProperty(ref _maximumZoomValue, value);
}
}
private double _minimumZoomValue = 0.5;
[Browsable(false)]
public double MinimumZoomValue
{
get
{
return _minimumZoomValue;
}
set
{
SetProperty(ref _minimumZoomValue, value);
}
}
private bool _defaultZoomBox;
public bool DefaultZoomBox
{
get
{
return _defaultZoomBox;
}
set
{
SetProperty(ref _defaultZoomBox, value);
}
}
private double _delayZoomValue = 1;
[Browsable(false)]
public double DelayZoomValue
{
get
{
return _delayZoomValue;
}
set
{
SetProperty(ref _delayZoomValue, value);
}
}
private string _name;
[Browsable(false)]
public string Name
{
get
{
return _name;
}
set
{
SetProperty(ref _name, value);
}
}
private DiagramType _diagramType;
[Browsable(false)]
public DiagramType DiagramType
{
get
{
return _diagramType;
}
set
{
SetProperty(ref _diagramType, value);
}
}
private CellHorizontalAlignment _cellHorizontalAlignment;
[Browsable(false)]
public CellHorizontalAlignment CellHorizontalAlignment
{
get
{
return _cellHorizontalAlignment;
}
set
{
SetProperty(ref _cellHorizontalAlignment, value);
}
}
private CellVerticalAlignment _cellVerticalAlignment;
[Browsable(false)]
public CellVerticalAlignment CellVerticalAlignment
{
get
{
return _cellVerticalAlignment;
}
set
{
SetProperty(ref _cellVerticalAlignment, value);
}
}
private bool _isEditName;
[Browsable(false)]
public bool IsEditName
{
get
{
return _isEditName;
}
set
{
SetProperty(ref _isEditName, value);
}
}
private System.Windows.Point _currentPoint;
[Browsable(false)]
public System.Windows.Point CurrentPoint
{
get
{
return _currentPoint;
}
set
{
SetProperty(ref _currentPoint, value);
}
}
private Color _currentColor;
[Browsable(false)]
public Color CurrentColor
{
get
{
return _currentColor;
}
set
{
SetProperty(ref _currentColor, value);
}
}
public DiagramOption DiagramOption
{
get; set;
} = new DiagramOption();
public bool AllowDrop
{
get; set;
} = true;
private double OffsetX = 10;
private double OffsetY = 10;
#endregion
#region
public SimpleCommand CreateNewDiagramCommand
{
get; private set;
}
public SimpleCommand DirectAddItemCommand
{
get; private set;
}
public SimpleCommand AddItemCommand
{
get; private set;
}
public SimpleCommand DirectRemoveItemCommand
{
get; private set;
}
public SimpleCommand RemoveItemCommand
{
get; private set;
}
public SimpleCommand ClearSelectedItemsCommand
{
get; private set;
}
public SimpleCommand AlignTopCommand
{
get; private set;
}
public SimpleCommand AlignVerticalCentersCommand
{
get; private set;
}
public SimpleCommand AlignBottomCommand
{
get; private set;
}
public SimpleCommand AlignLeftCommand
{
get; private set;
}
public SimpleCommand AlignHorizontalCentersCommand
{
get; private set;
}
public SimpleCommand AlignRightCommand
{
get; private set;
}
public SimpleCommand BringForwardCommand
{
get; private set;
}
public SimpleCommand BringToFrontCommand
{
get; private set;
}
public SimpleCommand SendBackwardCommand
{
get; private set;
}
public SimpleCommand SendToBackCommand
{
get; private set;
}
public SimpleCommand DistributeHorizontalCommand
{
get; private set;
}
public SimpleCommand DistributeVerticalCommand
{
get; private set;
}
public SimpleCommand SelectAllCommand
{
get; private set;
}
public SimpleCommand SelectItemCommand
{
get; private set;
}
public SimpleCommand CopyCommand
{
get; private set;
}
public SimpleCommand PasteCommand
{
get; private set;
}
public SimpleCommand CutCommand
{
get; private set;
}
public SimpleCommand DeleteCommand
{
get; private set;
}
public SimpleCommand LeftMoveCommand
{
get; private set;
}
public SimpleCommand RightMoveCommand
{
get; private set;
}
public SimpleCommand UpMoveCommand
{
get; private set;
}
public SimpleCommand DownMoveCommand
{
get; private set;
}
public SimpleCommand CenterMoveCommand
{
get; private set;
}
public SimpleCommand SameSizeCommand
{
get; private set;
}
public SimpleCommand SameWidthCommand
{
get; private set;
}
public SimpleCommand SameHeightCommand
{
get; private set;
}
public SimpleCommand SameAngleCommand
{
get; private set;
}
public SimpleCommand GroupCommand
{
get; private set;
}
public SimpleCommand UngroupCommand
{
get; private set;
}
public SimpleCommand LockCommand
{
get; private set;
}
public SimpleCommand UnlockCommand
{
get; private set;
}
public SimpleCommand EditCommand
{
get; private set;
}
private SimpleCommand _undoCommand;
public SimpleCommand UndoCommand
{
get
{
return this._undoCommand ?? (this._undoCommand = new SimpleCommand(Undo_Enabled, this.UndoExecuted));
}
}
private SimpleCommand _redoCommand;
public SimpleCommand RedoCommand
{
get
{
return this._redoCommand ?? (this._redoCommand = new SimpleCommand(Redo_Enabled, this.RedoExecuted));
}
}
#endregion
public DoCommandManager DoCommandManager = new DoCommandManager();
public event DiagramEventHandler Event;
private IDisposable ZoomValueChangedSubscription;
public DiagramViewModel()
{
CreateNewDiagramCommand = new SimpleCommand(ExecuteEnable, ExecuteCreateNewDiagramCommand);
AddItemCommand = new SimpleCommand(ExecuteEnable, ExecuteAddItemCommand);
DirectAddItemCommand = new SimpleCommand(ExecuteEnable, ExecuteDirectAddItemCommand);
RemoveItemCommand = new SimpleCommand(ExecuteEnable, ExecuteRemoveItemCommand);
DirectRemoveItemCommand = new SimpleCommand(ExecuteEnable, ExecuteDirectRemoveItemCommand);
ClearSelectedItemsCommand = new SimpleCommand(ExecuteEnable, ExecuteClearSelectedItemsCommand);
AlignTopCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignTopCommand);
AlignVerticalCentersCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignVerticalCentersCommand);
AlignBottomCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignBottomCommand);
AlignLeftCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignLeftCommand);
AlignHorizontalCentersCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignHorizontalCentersCommand);
AlignRightCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignRightCommand);
BringForwardCommand = new SimpleCommand(ExecuteEnable, ExecuteBringForwardCommand);
BringToFrontCommand = new SimpleCommand(ExecuteEnable, ExecuteBringToFrontCommand);
SendBackwardCommand = new SimpleCommand(ExecuteEnable, ExecuteSendBackwardCommand);
SendToBackCommand = new SimpleCommand(ExecuteEnable, ExecuteSendToBackCommand);
DistributeHorizontalCommand = new SimpleCommand(ExecuteEnable, ExecuteDistributeHorizontalCommand);
DistributeVerticalCommand = new SimpleCommand(ExecuteEnable, ExecuteDistributeVerticalCommand);
SelectAllCommand = new SimpleCommand(ExecuteEnable, ExecuteSelectAllCommand);
SelectItemCommand = new SimpleCommand(ExecuteEnable, ExecuteSelectItemCommand);
CopyCommand = new SimpleCommand(ExecuteEnable, ExecuteCopyCommand);
PasteCommand = new SimpleCommand(ExecuteEnable, ExecutePasteCommand);
CutCommand = new SimpleCommand(ExecuteEnable, ExecuteCutCommand);
DeleteCommand = new SimpleCommand(ExecuteEnable, ExecuteDeleteCommand);
LeftMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteLeftMoveCommand);
RightMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteRightMoveCommand);
UpMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteUpMoveCommand);
DownMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteDownMoveCommand);
CenterMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteCenterMoveCommand);
SameSizeCommand = new SimpleCommand(ExecuteEnable, ExecuteSameSizeCommand);
SameWidthCommand = new SimpleCommand(ExecuteEnable, ExecuteSameWidthCommand);
SameHeightCommand = new SimpleCommand(ExecuteEnable, ExecuteSameHeightCommand);
SameAngleCommand = new SimpleCommand(ExecuteEnable, ExecuteSameAngleCommand);
GroupCommand = new SimpleCommand(ExecuteEnable, ExecuteGroupCommand);
UngroupCommand = new SimpleCommand(ExecuteEnable, ExecuteUngroupCommand);
LockCommand = new SimpleCommand(ExecuteEnable, ExecuteLockCommand);
UnlockCommand = new SimpleCommand(ExecuteEnable, ExecuteUnlockCommand);
EditCommand = new SimpleCommand(ExecuteEnable, ExecuteEditCommand);
Mediator.Instance.Register(this);
Items.CollectionChanged += Items_CollectionChanged;
ZoomValueChangedSubscription = WhenPropertyChanged.Where(o => o.ToString() == nameof(ZoomValue)).Throttle(TimeSpan.FromMilliseconds(100)).Subscribe(OnZoomValueChanged);//Sample
}
//提供给标尺计算延迟100ms等布局改变再计算。
private void OnZoomValueChanged(string obj)
{
DelayZoomValue = ZoomValue;
}
public DiagramViewModel(DiagramItem diagramItem) : this()
{
DiagramType = diagramItem.DiagramType;
ShowGrid = diagramItem.ShowGrid;
PhysicalGridCellSize = diagramItem.PhysicalGridCellSize;
CellHorizontalAlignment = diagramItem.CellHorizontalAlignment;
CellVerticalAlignment = diagramItem.CellVerticalAlignment;
PageSizeOrientation = diagramItem.PageSizeOrientation;
PhysicalPageSize = diagramItem.PhysicalPageSize;
PageSizeType = diagramItem.PageSizeType;
PhysicalGridMarginSize = diagramItem.PhysicalGridMarginSize;
GridColor = diagramItem.GridColor;
AllowDrop = diagramItem.AllowDrop;
}
public virtual bool ExecuteEnable(object para)
{
return IsReadOnly == false;
}
#region UnDo ReDo
private void Do(object sender, string propertyName, object newvalue)
{
sender.SetPropertyValue(propertyName, newvalue);
}
private void UnDo(object sender, string propertyName, object oldvalue)
{
sender.SetPropertyValue(propertyName, oldvalue);
}
private void UndoExecuted(object para)
{
Undo(para);
}
private bool Undo(object para)
{
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
DoCommandManager.UnDo();
return true;
}
private void RedoExecuted(object para)
{
Redo(para);
}
private bool Redo(object para)
{
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
DoCommandManager.ReDo();
return true;
}
private bool Undo_Enabled(object para)
{
return DoCommandManager.CanUnDo;
}
private bool Redo_Enabled(object para)
{
return DoCommandManager.CanReDo;
}
#endregion
private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (var item in e.OldItems.OfType<SelectableDesignerItemViewModelBase>())
{
item.PropertyChanged -= Item_PropertyChanged;
item.Dispose();
}
}
if (e.NewItems != null)
{
foreach (var item in e.NewItems.OfType<SelectableDesignerItemViewModelBase>())
{
item.PropertyChanged += Item_PropertyChanged;
}
}
RaisePropertyChanged("Items");
}
private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
RaisePropertyChanged(sender, e.PropertyName);
//连续改变需要特殊处理不单独触发属性改变ReDo
if (sender is DesignerItemViewModelBase designer)
{
if (designer.BeginDo) return;
}
var selectable = sender as SelectableViewModelBase;
if (e is ValuePropertyChangedEventArgs valuePropertyChangedEventArgs)
{
var property = sender.GetType().GetProperty(e.PropertyName);
var attr = property.GetCustomAttributes(typeof(CanDoAttribute), true);
if (attr != null && attr.Length != 0)
{
//加入ReDo
DoCommandManager.DoNewCommand(sender.ToString() + e.PropertyName, () => Do(sender, e.PropertyName, valuePropertyChangedEventArgs.NewValue), () => UnDo(sender, e.PropertyName, valuePropertyChangedEventArgs.OldValue), null, false);
Event?.Invoke(sender, new DiagramEventArgs(valuePropertyChangedEventArgs.PropertyName, valuePropertyChangedEventArgs.NewValue, valuePropertyChangedEventArgs.OldValue, selectable?.Id));
}
}
}
[MediatorMessageSink("DoneDrawingMessage")]
public void OnDoneDrawingMessage(bool dummy)
{
foreach (var item in Items.OfType<DesignerItemViewModelBase>())
{
item.ShowConnectors = false;
}
}
public Func<SelectableDesignerItemViewModelBase, bool> OutAddVerify
{
get; set;
}
public bool AddVerify(SelectableDesignerItemViewModelBase item)
{
if (item.InitData() == false)
return false;
if (OutAddVerify != null && OutAddVerify(item) != true)
return false;
return true;
}
#region ,
private void ExecuteCreateNewDiagramCommand(object parameter)
{
this.Items.Clear();
}
private void ExecuteDirectAddItemCommand(object parameter)
{
if (parameter is SelectableDesignerItemViewModelBase ite)
{
if (AddVerify(ite) != true) return;
ClearSelectedItems();
Add(ite);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> items)
{
if (items.Select(p => AddVerify(p)).Any() != true) return;
ClearSelectedItems();
foreach (var item in items)
{
Add(item);
}
}
}
private void Add(SelectableDesignerItemViewModelBase item)
{
item.Root = this;
item.ZIndex = Items.Any() ? Items.Max(p => p.ZIndex) + 1 : 0;
if (item.Id == Guid.Empty)
{
item.Id = Guid.NewGuid();
}
var logical = item as LogicalGateItemViewModelBase;
if (logical != null && logical.LogicalType > 0)
{
logical.OrderNumber = Items.OfType<LogicalGateItemViewModelBase>().Count(p => (int)p.LogicalType > 0) + 1;
}
var designerItemViewModelBase = item as DesignerItemViewModelBase;
if (designerItemViewModelBase != null)
{
designerItemViewModelBase.SetCellAlignment();
}
Items.Add(item);
item.IsSelected = true;
}
private void ExecuteAddItemCommand(object parameter)
{
if (parameter is SelectableDesignerItemViewModelBase ite)
{
if (AddVerify(ite) != true) return;
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ClearSelectedItems();
Add(ite);
},
() => {
Items.Remove(ite);
});
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> items)
{
if (items.Select(p => AddVerify(p)).Any() != true) return;
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ClearSelectedItems();
foreach (var item in items)
{
Add(item);
}
},
() => {
foreach (var item in items)
{
Items.Remove(item);
}
});
}
}
private void ExecuteDirectRemoveItemCommand(object parameter)
{
if (parameter is SelectableDesignerItemViewModelBase ite)
{
ite.IsSelected = false;
Items.Remove(ite);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> items)
{
foreach (var item in items)
{
item.IsSelected = false;
Items.Remove(item);
}
}
}
private void ExecuteRemoveItemCommand(object parameter)
{
if (parameter is SelectableDesignerItemViewModelBase ite)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ite.IsSelected = false;
Items.Remove(ite);
},
() => {
Items.Add(ite);
});
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> items)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
item.IsSelected = false;
Items.Remove(item);
}
},
() => {
foreach (var item in items)
{
Items.Add(item);
}
});
}
}
private void ExecuteClearSelectedItemsCommand(object parameter)
{
IEnumerable<SelectableDesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
foreach (var item in selectedItems)
{
item.IsSelected = false;
}
}
public void ClearSelectedItems()
{
foreach (var item in this.Items.ToList())
{
item.IsSelected = false;
}
}
private void ExecuteSelectAllCommand(object parameter)
{
foreach (var item in Items)
{
item.IsSelected = true;
}
}
public void ExecuteSelectItemCommand(object parameter)
{
if (parameter is ISelectable selectable)
{
selectable.IsSelected = true;
}
}
#endregion
#region
private void ExecuteAlignTopCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double top = selectedItems.OrderBy(p => p.Top).Select(p => p.Top).FirstOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.SetOldValue(item.Top, nameof(item.Top), guid.ToString());
item.Top = top;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = item.GetOldValue<double>(nameof(item.Top), guid.ToString());
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Top), guid.ToString());
}
});
}
}
private void ExecuteAlignVerticalCentersCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double mid = selectedItems.Select(p => p.Top + p.ItemHeight / 2).Average();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.SetOldValue(item.Top, nameof(item.Top), guid.ToString());
item.Top = mid - item.ItemHeight / 2;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = item.GetOldValue<double>(nameof(item.Top), guid.ToString());
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Top), guid.ToString());
}
});
}
}
private void ExecuteAlignBottomCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double top = selectedItems.OrderBy(p => p.Top + p.ItemHeight).Select(p => p.Top + p.ItemHeight).LastOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.SetOldValue(item.Top, nameof(item.Top), guid.ToString());
item.Top = top - item.ItemHeight;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Top = item.GetOldValue<double>(nameof(item.Top), guid.ToString());
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Top), guid.ToString());
}
});
}
}
private void ExecuteAlignLeftCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double left = selectedItems.OrderBy(p => p.Left).Select(p => p.Left).FirstOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.SetOldValue(item.Left, nameof(item.Left), guid.ToString());
item.Left = left;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = item.GetOldValue<double>(nameof(item.Left), guid.ToString());
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Left), guid.ToString());
}
});
}
}
private void ExecuteAlignHorizontalCentersCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double mid = selectedItems.Select(p => p.Left + p.ItemWidth / 2).Average();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.SetOldValue(item.Left, nameof(item.Left), guid.ToString());
item.Left = mid - item.ItemWidth / 2;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = item.GetOldValue<double>(nameof(item.Left), guid.ToString());
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Left), guid.ToString());
}
});
}
}
private void ExecuteAlignRightCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double right = selectedItems.OrderBy(p => p.Left + p.ItemWidth).Select(p => p.Left + p.ItemWidth).LastOrDefault();
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.SetOldValue(item.Left, nameof(item.Left), guid.ToString());
item.Left = right - item.ItemWidth;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.Left = item.GetOldValue<double>(nameof(item.Left), guid.ToString());
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
item.ClearOldValue<double>(nameof(item.Left), guid.ToString());
}
});
}
}
private void ExecuteBringForwardCommand(object parameter)
{
List<SelectableDesignerItemViewModelBase> ordered;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
ordered = para.OrderByDescending(p => p.ZIndex).ToList();
}
else
{
ordered = SelectedItems.OrderByDescending(p => p.ZIndex).ToList();
}
List<SelectableDesignerItemViewModelBase> changeditems = new List<SelectableDesignerItemViewModelBase>();
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int count = this.Items.Count;
for (int i = 0; i < ordered.Count; i++)
{
var item = ordered[i];
int currentIndex = item.ZIndex;
int newIndex = Math.Min(count - 1 - i, currentIndex + 1);
if (currentIndex != newIndex)
{
item.SetOldValue<int>(item.ZIndex, nameof(item.ZIndex), guid.ToString());
item.ZIndex = newIndex;
changeditems.Add(item);
IEnumerable<SelectableDesignerItemViewModelBase> it = this.Items.Where(p => p.ZIndex == newIndex);
foreach (var elm in it)
{
if (elm != item)
{
elm.SetOldValue<int>(elm.ZIndex, nameof(elm.ZIndex), guid.ToString());
elm.ZIndex = currentIndex;
changeditems.Add(elm);
break;
}
}
}
}
},
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
}
});
}
private void ExecuteBringToFrontCommand(object parameter)
{
List<SelectableDesignerItemViewModelBase> selectionSorted;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectionSorted = para.OrderByDescending(p => p.ZIndex).ToList();
}
else
{
selectionSorted = SelectedItems.OrderByDescending(p => p.ZIndex).ToList();
}
List<SelectableDesignerItemViewModelBase> childrenSorted = Items.OrderByDescending(p => p.ZIndex).ToList();
List<SelectableDesignerItemViewModelBase> changeditems = new List<SelectableDesignerItemViewModelBase>();
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int i = childrenSorted.Count - 1;
int j = childrenSorted.Count - selectionSorted.Count - 1;
foreach (SelectableDesignerItemViewModelBase item in childrenSorted)
{
item.SetOldValue<int>(item.ZIndex, nameof(item.ZIndex), guid.ToString());
if (selectionSorted.Contains(item))
{
item.ZIndex = i--;
}
else
{
item.ZIndex = j--;
}
changeditems.Add(item);
}
},
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
}
});
}
private void ExecuteSendBackwardCommand(object parameter)
{
List<SelectableDesignerItemViewModelBase> ordered;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
ordered = para.OrderBy(p => p.ZIndex).ToList();
}
else
{
ordered = SelectedItems.OrderBy(p => p.ZIndex).ToList();
}
int count = this.Items.Count;
List<SelectableDesignerItemViewModelBase> changeditems = new List<SelectableDesignerItemViewModelBase>();
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() => {
for (int i = 0; i < ordered.Count; i++)
{
var item = ordered[i];
int currentIndex = item.ZIndex;
int newIndex = Math.Max(i, currentIndex - 1);
if (currentIndex != newIndex)
{
item.SetOldValue<int>(item.ZIndex, nameof(item.ZIndex), guid.ToString());
item.ZIndex = newIndex;
changeditems.Add(item);
IEnumerable<SelectableDesignerItemViewModelBase> it = this.Items.Where(p => p.ZIndex == newIndex);
foreach (var elm in it)
{
if (elm != ordered[i])
{
elm.SetOldValue<int>(elm.ZIndex, nameof(elm.ZIndex), guid.ToString());
elm.ZIndex = currentIndex;
changeditems.Add(elm);
break;
}
}
}
}
},
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
}
});
}
private void ExecuteSendToBackCommand(object parameter)
{
List<SelectableDesignerItemViewModelBase> selectionSorted;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectionSorted = para.OrderByDescending(p => p.ZIndex).ToList();
}
else
{
selectionSorted = SelectedItems.OrderByDescending(p => p.ZIndex).ToList();
}
List<SelectableDesignerItemViewModelBase> childrenSorted = Items.OrderByDescending(p => p.ZIndex).ToList();
List<SelectableDesignerItemViewModelBase> changeditems = new List<SelectableDesignerItemViewModelBase>();
var guid = Guid.NewGuid();
DoCommandManager.DoNewCommand(this.ToString(),
() => {
int i = childrenSorted.Count - 1;
int j = selectionSorted.Count - 1;
foreach (SelectableDesignerItemViewModelBase item in childrenSorted)
{
item.SetOldValue<int>(item.ZIndex, nameof(item.ZIndex), guid.ToString());
if (selectionSorted.Contains(item))
{
item.ZIndex = j--;
}
else
{
item.ZIndex = i--;
}
changeditems.Add(item);
}
},
() => {
foreach (var item in changeditems)
{
item.ZIndex = item.GetOldValue<int>(nameof(item.ZIndex), guid.ToString());
}
},
() => {
foreach (var item in changeditems)
{
item.ClearOldValue<double>(nameof(item.ZIndex), guid.ToString());
}
});
}
private void ExecuteDistributeHorizontalCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para.Where(p => p.ParentId == Guid.Empty).OrderBy(p => p.Left);
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>().Where(p => p.ParentId == Guid.Empty).OrderBy(p => p.Left);
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double left = Double.MaxValue;
double right = Double.MinValue;
double sumWidth = 0;
foreach (DesignerItemViewModelBase item in selectedItems)
{
left = Math.Min(left, item.Left);
right = Math.Max(right, item.Left + item.ItemWidth);
sumWidth += item.ItemWidth;
}
double distance = Math.Max(0, (right - left - sumWidth) / (selectedItems.Count() - 1));
double offset = selectedItems.First().Left;
foreach (DesignerItemViewModelBase item in selectedItems)
{
double delta = offset - item.Left;
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
{
di.SetOldValue(di.Left, nameof(di.Left), guid.ToString());
di.Left += delta;
}
offset = offset + item.ItemWidth + distance;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
{
di.Left = di.GetOldValue<double>(nameof(di.Left), guid.ToString());
}
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
{
di.ClearOldValue<double>(nameof(di.Left), guid.ToString());
}
}
});
}
}
private void ExecuteDistributeVerticalCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para.Where(p => p.ParentId == Guid.Empty).OrderBy(p => p.Top);
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>().Where(p => p.ParentId == Guid.Empty).OrderBy(p => p.Top);
}
var guid = Guid.NewGuid();
if (selectedItems.Count() > 1)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
double top = Double.MaxValue;
double bottom = Double.MinValue;
double sumHeight = 0;
foreach (DesignerItemViewModelBase item in selectedItems)
{
top = Math.Min(top, item.Top);
bottom = Math.Max(bottom, item.Top + item.ItemHeight);
sumHeight += item.ItemHeight;
}
double distance = Math.Max(0, (bottom - top - sumHeight) / (selectedItems.Count() - 1));
double offset = selectedItems.First().Top;
foreach (DesignerItemViewModelBase item in selectedItems)
{
double delta = offset - item.Top;
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
{
di.SetOldValue(di.Top, nameof(di.Top), guid.ToString());
di.Top += +delta;
}
offset = offset + item.ItemHeight + distance;
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
{
di.Top = di.GetOldValue<double>(nameof(di.Top), guid.ToString());
}
}
},
() => {
foreach (DesignerItemViewModelBase item in selectedItems)
{
foreach (DesignerItemViewModelBase di in SelectionService.GetGroupMembers(item))
{
di.ClearOldValue<double>(nameof(di.Top), guid.ToString());
}
}
});
}
}
#endregion
#region
private void ExecuteCopyCommand(object parameter)
{
Copy(parameter);
}
private bool Copy(object parameter)
{
List<DesignerItemViewModelBase> selectedDesignerItems;
List<ConnectionViewModel> selectedConnections;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectedDesignerItems = para.OfType<DesignerItemViewModelBase>().ToList();
selectedConnections = para.OfType<ConnectionViewModel>().ToList();
}
else
{
if (SelectedItems.Count == 0)
{
return false;
}
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
selectedDesignerItems = SelectedItems.OfType<DesignerItemViewModelBase>().ToList();
selectedConnections = SelectedItems.OfType<ConnectionViewModel>().ToList();
}
foreach (ConnectionViewModel connection in Items.OfType<ConnectionViewModel>())
{
if (!selectedConnections.Contains(connection))
{
DesignerItemViewModelBase sourceItem = (from item in selectedDesignerItems
where item.Id == connection.SourceConnectorInfo.DataItem.Id
select item).FirstOrDefault();
DesignerItemViewModelBase sinkItem = (from item in selectedDesignerItems
where item.Id == connection.SinkConnectorInfoFully?.DataItem?.Id
select item).FirstOrDefault();
if (sourceItem != null &&
sinkItem != null &&
BelongToSameGroup(sourceItem, sinkItem))
{
selectedConnections.Add(connection);
}
}
}
string json = new SerializableObject
{
DesignerItems = selectedDesignerItems.Select(p => p.ToSerializableItem(".json")).Where(p => p != null).ToList(),
Connections = selectedConnections.Select(p => p.ToSerializableItem(".json")).Where(p => p != null).ToList(),
}.ToJson();
OffsetX = 10;
OffsetY = 10;
System.Windows.Clipboard.Clear();
System.Windows.Clipboard.SetData(System.Windows.DataFormats.Serializable, json);
return true;
}
private void ExecutePasteCommand(object parameter)
{
Paste(parameter);
}
private bool Paste(object parameter)
{
if (System.Windows.Clipboard.ContainsData(System.Windows.DataFormats.Serializable))
{
string clipboardData = System.Windows.Clipboard.GetData(System.Windows.DataFormats.Serializable) as String;
if (string.IsNullOrEmpty(clipboardData))
return false;
try
{
List<SelectableDesignerItemViewModelBase> items = new List<SelectableDesignerItemViewModelBase>();
SerializableObject copyitem = JsonConvert.DeserializeObject<SerializableObject>(clipboardData);
Dictionary<Guid, Guid> mappingOldToNewIDs = new Dictionary<Guid, Guid>();
foreach (var diagramItemData in copyitem.DesignerItems)
{
DesignerItemViewModelBase newItem = null;
Type type = TypeHelper.GetType(diagramItemData.ModelTypeName);
DesignerItemViewModelBase itemBase = Activator.CreateInstance(type, this, diagramItemData, ".json") as DesignerItemViewModelBase;
Guid newID = Guid.NewGuid();
mappingOldToNewIDs.Add(itemBase.Id, newID);
itemBase.Id = newID;
itemBase.Left += OffsetX;
itemBase.Top += OffsetY;
newItem = itemBase;
if (newItem != null)
{
items.Add(newItem);
}
}
OffsetX += 10;
OffsetY += 10;
List<SelectableDesignerItemViewModelBase> connectors = new List<SelectableDesignerItemViewModelBase>();
foreach (var connection in copyitem.Connections)
{
var connectionItem = JsonConvert.DeserializeObject<ConnectionItem>(connection.SerializableString);
Guid newID = Guid.NewGuid();
mappingOldToNewIDs.Add(connectionItem.Id, newID);
connectionItem.SourceId = mappingOldToNewIDs[connectionItem.SourceId];
connectionItem.SinkId = mappingOldToNewIDs[connectionItem.SinkId];
connectionItem.SourceType = System.Type.GetType(connectionItem.SourceTypeName);
connectionItem.SinkType = System.Type.GetType(connectionItem.SinkTypeName);
DesignerItemViewModelBase sourceItem = DiagramViewModelHelper.GetConnectorDataItem(items, connectionItem.SourceId, connectionItem.SourceType);
ConnectorOrientation sourceConnectorOrientation = connectionItem.SourceOrientation;
FullyCreatedConnectorInfo sourceConnectorInfo = sourceItem.GetFullConnectorInfo(connectionItem.Id, sourceConnectorOrientation, connectionItem.SourceXRatio, connectionItem.SourceYRatio, connectionItem.SourceInnerPoint, connectionItem.SourceIsPortless);
DesignerItemViewModelBase sinkItem = DiagramViewModelHelper.GetConnectorDataItem(items, connectionItem.SinkId, connectionItem.SinkType);
ConnectorOrientation sinkConnectorOrientation = connectionItem.SinkOrientation;
FullyCreatedConnectorInfo sinkConnectorInfo = sinkItem.GetFullConnectorInfo(connectionItem.Id, sinkConnectorOrientation, connectionItem.SinkXRatio, connectionItem.SinkYRatio, connectionItem.SinkInnerPoint, connectionItem.SinkIsPortless);
ConnectionViewModel connectionVM = new ConnectionViewModel(this, sourceConnectorInfo, sinkConnectorInfo, connectionItem);
connectors.Add(connectionVM);
}
//修复父级的引用
foreach (var item in items)
{
if (item.ParentId != Guid.Empty)
{
if (mappingOldToNewIDs.ContainsKey(item.ParentId))
item.ParentId = mappingOldToNewIDs[item.ParentId];
}
}
items.AddRange(connectors);
DirectAddItemCommand.Execute(items);
}
catch (Exception e)
{
System.Windows.MessageBox.Show(e.StackTrace, e.Message, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
}
return true;
}
else
{
return false;
}
}
private bool ItemsToDeleteHasConnector(List<SelectableDesignerItemViewModelBase> itemsToRemove, ConnectorInfoBase connector)
{
if (connector is FullyCreatedConnectorInfo fully)
{
return itemsToRemove.Contains(fully.DataItem);
}
return false;
}
private void ExecuteCutCommand(object parameter)
{
Cut(parameter);
}
private bool Cut(object parameter)
{
if (Paste(null) == false)
return false;
OffsetX = 0;
OffsetY = 0;
if (Delete(null) == false)
return false;
return true;
}
private void ExecuteDeleteCommand(object parameter)
{
Delete(parameter);
}
private bool Delete(object parameter)
{
List<SelectableDesignerItemViewModelBase> itemsToRemove;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
itemsToRemove = para.OfType<SelectableDesignerItemViewModelBase>().ToList();
}
else
{
if (SelectedItems.Count == 0)
{
return false;
}
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
itemsToRemove = SelectedItems.OfType<SelectableDesignerItemViewModelBase>().ToList();
}
List<SelectableDesignerItemViewModelBase> connectionsToAlsoRemove = new List<SelectableDesignerItemViewModelBase>();
foreach (var connector in Items.OfType<ConnectionViewModel>())
{
if (ItemsToDeleteHasConnector(itemsToRemove, connector.SourceConnectorInfo))
{
connectionsToAlsoRemove.Add(connector);
}
if (ItemsToDeleteHasConnector(itemsToRemove, connector.SinkConnectorInfo))
{
connectionsToAlsoRemove.Add(connector);
}
}
itemsToRemove.AddRange(connectionsToAlsoRemove);
RemoveItemCommand.Execute(itemsToRemove);
return true;
}
#endregion
#region
private void ExecuteLeftMoveCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
foreach (var item in selectedItems.OfType<DesignerItemViewModelBase>())
{
item.Left -= 0.5;
}
}
private void ExecuteRightMoveCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
foreach (var item in selectedItems.OfType<DesignerItemViewModelBase>())
{
item.Left += 0.5;
}
}
private void ExecuteUpMoveCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
foreach (var item in selectedItems.OfType<DesignerItemViewModelBase>())
{
item.Top -= 0.5;
}
}
private void ExecuteDownMoveCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
foreach (var item in selectedItems.OfType<DesignerItemViewModelBase>())
{
item.Top += 0.5;
}
}
private void ExecuteCenterMoveCommand(object parameter)
{
IEnumerable<DesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
selectedItems = para;
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
}
foreach (var item in selectedItems.OfType<DesignerItemViewModelBase>())
{
item.Left = (PageSize.Width - item.ItemWidth) / 2;
item.Top = (PageSize.Height - item.ItemHeight) / 2;
}
}
public void UpdateZIndex()
{
List<SelectableDesignerItemViewModelBase> ordered = Items.OrderBy(p => p.ZIndex).ToList();
for (int i = 0; i < ordered.Count; i++)
{
ordered[i].ZIndex = i;
}
}
#endregion
#region
private void ExecuteSameSizeCommand(object parameter)
{
if (parameter is DesignerItemViewModelBase designerItem)
{
foreach (var item in SelectedItems.OfType<DesignerItemViewModelBase>())
{
item.ItemWidth = designerItem.ItemWidth;
item.ItemHeight = designerItem.ItemHeight;
}
}
}
private void ExecuteSameWidthCommand(object parameter)
{
if (parameter is DesignerItemViewModelBase designerItem)
{
foreach (var item in SelectedItems.OfType<DesignerItemViewModelBase>())
{
item.ItemWidth = designerItem.ItemWidth;
}
}
}
private void ExecuteSameHeightCommand(object parameter)
{
if (parameter is DesignerItemViewModelBase designerItem)
{
foreach (var item in SelectedItems.OfType<DesignerItemViewModelBase>())
{
item.ItemHeight = designerItem.ItemHeight;
}
}
}
private void ExecuteSameAngleCommand(object parameter)
{
if (parameter is DesignerItemViewModelBase designerItem)
{
foreach (var item in SelectedItems.OfType<DesignerItemViewModelBase>())
{
item.Angle = designerItem.Angle;
}
}
}
#endregion
#region
private void ExecuteGroupCommand(object parameter)
{
List<DesignerItemViewModelBase> items;
GroupDesignerItemViewModel groupItem = null;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
if (para.FirstOrDefault() is GroupDesignerItemViewModel groupDesignerItemViewModel && groupDesignerItemViewModel.Custom)
{
groupDesignerItemViewModel.Custom = false;
groupItem = groupDesignerItemViewModel;
items = para.Skip(1).ToList();
}
else
{
items = para.ToList();
}
}
else
{
items = SelectedItems?.OfType<DesignerItemViewModelBase>().Where(p => p.ParentId == Guid.Empty).ToList();
}
var groups = items.OfType<DesignerItemViewModelBase>().Where(p => p.IsGroup && p.ParentId == Guid.Empty).ToList();
//解除分组
if (groupItem == null && groups.Count > 0)
{
ExecuteUngroupCommand(groups);
return;
}
RectangleBase rect = DiagramViewModelHelper.GetBoundingRectangle(items);
if (groupItem == null)
{
groupItem = new GroupDesignerItemViewModel();
}
DirectAddItemCommand.Execute(groupItem);
foreach (DesignerItemViewModelBase item in items)
item.ParentId = groupItem.Id;
groupItem.Resize();
ClearSelectedItemsCommand.Execute(null);
//groupItem.IsSelected = true;
SelectionService.AddToSelection(groupItem);
}
private void ExecuteUngroupCommand(object parameter)
{
List<DesignerItemViewModelBase> groups;
if (parameter is IEnumerable<DesignerItemViewModelBase> para)
{
groups = para.ToList();
}
else
{
groups = SelectedItems?.OfType<DesignerItemViewModelBase>().Where(p => p.IsGroup && p.ParentId == Guid.Empty).ToList();
}
foreach (DesignerItemViewModelBase groupRoot in groups)
{
var children = from child in SelectedItems.OfType<DesignerItemViewModelBase>()
where child.ParentId == groupRoot.Id
select child;
foreach (DesignerItemViewModelBase child in children)
child.ParentId = Guid.Empty;
RemoveItemCommand.Execute(groupRoot);
UpdateZIndex();
}
}
public bool BelongToSameGroup(IGroupable item1, IGroupable item2)
{
IGroupable root1 = SelectionService.GetGroupRoot(item1);
IGroupable root2 = SelectionService.GetGroupRoot(item2);
return (root1.Id == root2.Id);
}
#endregion
#region
public bool ExecuteShortcut(KeyEventArgs e)
{
if (DiagramOption.ShortcutOption.SelectAll(e))
{
SelectAllCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.Copy(e))
{
return Copy(null);
}
else if (DiagramOption.ShortcutOption.Paste(e))
{
return Paste(null);
}
else if (DiagramOption.ShortcutOption.Cut(e))
{
return Cut(null);
}
else if (DiagramOption.ShortcutOption.Undo(e))
{
return Undo(null);
}
else if (DiagramOption.ShortcutOption.Redo(e))
{
return Redo(null);
}
else if (DiagramOption.ShortcutOption.Delete(e))
{
return Delete(null);
}
else if (DiagramOption.ShortcutOption.LeftMove(e))
{
LeftMoveCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.RightMove(e))
{
RightMoveCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.UpMove(e))
{
UpMoveCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.DownMove(e))
{
DownMoveCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.Group(e))
{
GroupCommand.Execute(null);
return true;
}
return false;
}
#endregion
private void ExecuteLockCommand(object parameter)
{
}
private void ExecuteUnlockCommand(object parameter)
{
}
protected virtual void ExecuteEditCommand(object parameter)
{
if (parameter is SelectableDesignerItemViewModelBase designerItem)
{
designerItem.ShowText = true;
}
else
{
if (SelectedItem != null)
SelectedItem.ShowText = true;
}
}
}
}