Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/ViewModels/BaseViewModel/DiagramViewModel.cs
2023-03-08 19:45:07 +08:00

2465 lines
82 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
private SimpleCommand _createNewDiagramCommand;
public SimpleCommand CreateNewDiagramCommand
{
get
{
return this._createNewDiagramCommand ?? (this._createNewDiagramCommand = new SimpleCommand(ExecuteEnable, ExecuteCreateNewDiagramCommand));
}
}
private SimpleCommand _directAddItemCommand;
public SimpleCommand DirectAddItemCommand
{
get
{
return this._directAddItemCommand ?? (this._directAddItemCommand = new SimpleCommand(ExecuteEnable, ExecuteDirectAddItemCommand));
}
}
private SimpleCommand _addItemCommand;
public SimpleCommand AddItemCommand
{
get
{
return this._addItemCommand ?? (this._addItemCommand = new SimpleCommand(ExecuteEnable, ExecuteAddItemCommand));
}
}
private SimpleCommand _directRemoveItemCommand;
public SimpleCommand DirectRemoveItemCommand
{
get
{
return this._directRemoveItemCommand ?? (this._directRemoveItemCommand = new SimpleCommand(ExecuteEnable, ExecuteDirectRemoveItemCommand));
}
}
private SimpleCommand _removeItemCommand;
public SimpleCommand RemoveItemCommand
{
get
{
return this._removeItemCommand ?? (this._removeItemCommand = new SimpleCommand(ExecuteEnable, ExecuteRemoveItemCommand));
}
}
private SimpleCommand _clearSelectedItemsCommand;
public SimpleCommand ClearSelectedItemsCommand
{
get
{
return this._clearSelectedItemsCommand ?? (this._clearSelectedItemsCommand = new SimpleCommand(ExecuteEnable, ExecuteClearSelectedItemsCommand));
}
}
private SimpleCommand _alignTopCommand;
public SimpleCommand AlignTopCommand
{
get
{
return this._alignTopCommand ?? (this._alignTopCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignTopCommand));
}
}
private SimpleCommand _alignVerticalCentersCommand;
public SimpleCommand AlignVerticalCentersCommand
{
get
{
return this._alignVerticalCentersCommand ?? (this._alignVerticalCentersCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignVerticalCentersCommand));
}
}
private SimpleCommand _alignBottomCommand;
public SimpleCommand AlignBottomCommand
{
get
{
return this._alignBottomCommand ?? (this._alignBottomCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignBottomCommand));
}
}
private SimpleCommand _alignLeftCommand;
public SimpleCommand AlignLeftCommand
{
get
{
return this._alignLeftCommand ?? (this._alignLeftCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignLeftCommand));
}
}
private SimpleCommand _alignHorizontalCentersCommand;
public SimpleCommand AlignHorizontalCentersCommand
{
get
{
return this._alignHorizontalCentersCommand ?? (this._alignHorizontalCentersCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignHorizontalCentersCommand));
}
}
private SimpleCommand _alignRightCommand;
public SimpleCommand AlignRightCommand
{
get
{
return this._alignRightCommand ?? (this._alignRightCommand = new SimpleCommand(ExecuteEnable, ExecuteAlignRightCommand));
}
}
private SimpleCommand _bringForwardCommand;
public SimpleCommand BringForwardCommand
{
get
{
return this._bringForwardCommand ?? (this._bringForwardCommand = new SimpleCommand(ExecuteEnable, ExecuteBringForwardCommand));
}
}
private SimpleCommand _bringToFrontCommand;
public SimpleCommand BringToFrontCommand
{
get
{
return this._bringToFrontCommand ?? (this._bringToFrontCommand = new SimpleCommand(ExecuteEnable, ExecuteBringToFrontCommand));
}
}
private SimpleCommand _sendBackwardCommand;
public SimpleCommand SendBackwardCommand
{
get
{
return this._sendBackwardCommand ?? (this._sendBackwardCommand = new SimpleCommand(ExecuteEnable, ExecuteSendBackwardCommand));
}
}
private SimpleCommand _sendToBackCommand;
public SimpleCommand SendToBackCommand
{
get
{
return this._sendToBackCommand ?? (this._sendToBackCommand = new SimpleCommand(ExecuteEnable, ExecuteSendToBackCommand));
}
}
private SimpleCommand _distributeHorizontalCommand;
public SimpleCommand DistributeHorizontalCommand
{
get
{
return this._distributeHorizontalCommand ?? (this._distributeHorizontalCommand = new SimpleCommand(ExecuteEnable, ExecuteDistributeHorizontalCommand));
}
}
private SimpleCommand _distributeVerticalCommand;
public SimpleCommand DistributeVerticalCommand
{
get
{
return this._distributeVerticalCommand ?? (this._distributeVerticalCommand = new SimpleCommand(ExecuteEnable, ExecuteDistributeVerticalCommand));
}
}
private SimpleCommand _selectAllCommand;
public SimpleCommand SelectAllCommand
{
get
{
return this._selectAllCommand ?? (this._selectAllCommand = new SimpleCommand(ExecuteEnable, ExecuteSelectAllCommand));
}
}
private SimpleCommand _selectItemCommand;
public SimpleCommand SelectItemCommand
{
get
{
return this._selectItemCommand ?? (this._selectItemCommand = new SimpleCommand(ExecuteEnable, ExecuteSelectItemCommand));
}
}
private SimpleCommand _copyCommand;
public SimpleCommand CopyCommand
{
get
{
return this._copyCommand ?? (this._copyCommand = new SimpleCommand(ExecuteEnable, ExecuteCopyCommand));
}
}
private SimpleCommand _pasteCommand;
public SimpleCommand PasteCommand
{
get
{
return this._pasteCommand ?? (this._pasteCommand = new SimpleCommand(ExecuteEnable, ExecutePasteCommand));
}
}
private SimpleCommand _cutCommand;
public SimpleCommand CutCommand
{
get
{
return this._cutCommand ?? (this._cutCommand = new SimpleCommand(ExecuteEnable, ExecuteCutCommand));
}
}
private SimpleCommand _deleteCommand;
public SimpleCommand DeleteCommand
{
get
{
return this._deleteCommand ?? (this._deleteCommand = new SimpleCommand(ExecuteEnable, ExecuteDeleteCommand));
}
}
private SimpleCommand _leftMoveCommand;
public SimpleCommand LeftMoveCommand
{
get
{
return this._leftMoveCommand ?? (this._leftMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteLeftMoveCommand));
}
}
private SimpleCommand _rightMoveCommand;
public SimpleCommand RightMoveCommand
{
get
{
return this._rightMoveCommand ?? (this._rightMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteRightMoveCommand));
}
}
private SimpleCommand _upMoveCommand;
public SimpleCommand UpMoveCommand
{
get
{
return this._upMoveCommand ?? (this._upMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteUpMoveCommand));
}
}
private SimpleCommand _downMoveCommand;
public SimpleCommand DownMoveCommand
{
get
{
return this._downMoveCommand ?? (this._downMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteDownMoveCommand));
}
}
private SimpleCommand _centerMoveCommand;
public SimpleCommand CenterMoveCommand
{
get
{
return this._centerMoveCommand ?? (this._centerMoveCommand = new SimpleCommand(ExecuteEnable, ExecuteCenterMoveCommand));
}
}
private SimpleCommand _sameSizeCommand;
public SimpleCommand SameSizeCommand
{
get
{
return this._sameSizeCommand ?? (this._sameSizeCommand = new SimpleCommand(ExecuteEnable, ExecuteSameSizeCommand));
}
}
private SimpleCommand _sameWidthCommand;
public SimpleCommand SameWidthCommand
{
get
{
return this._sameWidthCommand ?? (this._sameWidthCommand = new SimpleCommand(ExecuteEnable, ExecuteSameWidthCommand));
}
}
private SimpleCommand _sameHeightCommand;
public SimpleCommand SameHeightCommand
{
get
{
return this._sameHeightCommand ?? (this._sameHeightCommand = new SimpleCommand(ExecuteEnable, ExecuteSameHeightCommand));
}
}
private SimpleCommand _sameAngleCommand;
public SimpleCommand SameAngleCommand
{
get
{
return this._sameAngleCommand ?? (this._sameAngleCommand = new SimpleCommand(ExecuteEnable, ExecuteSameAngleCommand));
}
}
private SimpleCommand _groupCommand;
public SimpleCommand GroupCommand
{
get
{
return this._groupCommand ?? (this._groupCommand = new SimpleCommand(ExecuteEnable, ExecuteGroupCommand));
}
}
private SimpleCommand _ungroupCommand;
public SimpleCommand UngroupCommand
{
get
{
return this._ungroupCommand ?? (this._ungroupCommand = new SimpleCommand(ExecuteEnable, ExecuteUngroupCommand));
}
}
private SimpleCommand _lockCommand;
public SimpleCommand LockCommand
{
get
{
return this._lockCommand ?? (this._lockCommand = new SimpleCommand(ExecuteEnable, ExecuteLockCommand));
}
}
private SimpleCommand _unlockCommand;
public SimpleCommand UnlockCommand
{
get
{
return this._unlockCommand ?? (this._unlockCommand = new SimpleCommand(ExecuteEnable, ExecuteUnlockCommand));
}
}
private SimpleCommand _editCommand;
public SimpleCommand EditCommand
{
get
{
return this._editCommand ?? (this._editCommand = new SimpleCommand(ExecuteEnable, ExecuteEditCommand));
}
}
private SimpleCommand _undoCommand;
public SimpleCommand UndoCommand
{
get
{
return this._undoCommand ?? (this._undoCommand = new SimpleCommand(Undo_Enabled, this.ExecutedUndoCommand));
}
}
private SimpleCommand _redoCommand;
public SimpleCommand RedoCommand
{
get
{
return this._redoCommand ?? (this._redoCommand = new SimpleCommand(Redo_Enabled, this.ExecutedRedoCommand));
}
}
private SimpleCommand _initLayoutCommand;
public SimpleCommand InitLayoutCommand
{
get
{
return this._initLayoutCommand ?? (this._initLayoutCommand = new SimpleCommand(ExecuteEnable, this.ExecutedInitLayoutCommand));
}
}
private SimpleCommand _resetLayoutCommand;
public SimpleCommand ResetLayoutCommand
{
get
{
return this._resetLayoutCommand ?? (this._resetLayoutCommand = new SimpleCommand(ExecuteEnable, this.ExecutedResetLayoutCommand));
}
}
#endregion
public DoCommandManager DoCommandManager = new DoCommandManager();
public event DiagramEventHandler Event;
private IDisposable ZoomValueChangedSubscription;
public DiagramViewModel()
{
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 ExecutedUndoCommand(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 ExecutedRedoCommand(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
protected virtual void ExecutedInitLayoutCommand(object obj)
{
throw new NotImplementedException();
}
protected virtual void ExecutedResetLayoutCommand(object obj)
{
throw new NotImplementedException();
}
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;
}
}
}
}