整理Redo和Undo命令

This commit is contained in:
艾竹
2023-04-05 23:40:22 +08:00
parent c513bd0f64
commit e0a26a76d2
4 changed files with 314 additions and 197 deletions

View File

@@ -390,6 +390,8 @@ namespace AIStudio.Wpf.DiagramDesigner
if (_viewModel.IsReadOnly) return;
this.Focus();
Point currentPoint = e.GetPosition(this);
_viewModel.CurrentPoint = new Point(ScreenHelper.WidthToMm(currentPoint.X), ScreenHelper.WidthToMm(currentPoint.Y));
var point = CursorPointManager.GetCursorPosition();
@@ -445,8 +447,9 @@ namespace AIStudio.Wpf.DiagramDesigner
adornerLayer.Add(adorner);
}
}
}
}
}
//e.Handled = true;
}
@@ -456,6 +459,8 @@ namespace AIStudio.Wpf.DiagramDesigner
if (_viewModel.IsReadOnly) return;
this.Focus();
if (_service.DrawModeViewModel.GetDrawMode() == DrawMode.DirectLine)
{
return;

View File

@@ -639,12 +639,12 @@ namespace AIStudio.Wpf.DiagramDesigner
#endregion
#region
private ICommand _createNewDiagramCommand;
public ICommand CreateNewDiagramCommand
private ICommand _clearCommand;
public ICommand ClearCommand
{
get
{
return this._createNewDiagramCommand ?? (this._createNewDiagramCommand = new SimpleCommand(ExecuteEnable, ExecuteCreateNewDiagramCommand));
return this._clearCommand ?? (this._clearCommand = new SimpleCommand(ExecuteEnable, ExecuteClearCommand));
}
}
@@ -1050,7 +1050,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
Mediator.Instance.Register(this);
Items.CollectionChanged += Items_CollectionChanged;
var zoomValueChangedSubscription = WhenPropertyChanged.Where(o => o.ToString() == nameof(ZoomValue)).Throttle(TimeSpan.FromMilliseconds(100)).Subscribe(OnZoomValueChanged);//Sample
this.PropertyChanged += DiagramViewModel_PropertyChanged;
BuildMenuOptions();
@@ -1123,12 +1123,6 @@ namespace AIStudio.Wpf.DiagramDesigner
private bool Undo(object para)
{
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
DoCommandManager.UnDo();
return true;
@@ -1141,11 +1135,6 @@ namespace AIStudio.Wpf.DiagramDesigner
private bool Redo(object para)
{
var first = SelectedItems.OfType<DesignerItemViewModelBase>().FirstOrDefault();
if (first != null && first.IsEditing == true)
{
return false;
}
DoCommandManager.ReDo();
return true;
@@ -1165,7 +1154,7 @@ namespace AIStudio.Wpf.DiagramDesigner
#region
protected virtual void DiagramViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
}
private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
@@ -1213,7 +1202,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
//提供给标尺计算延迟100ms等布局改变再计算。
private void OnZoomValueChanged(string obj)
@@ -1232,45 +1221,44 @@ namespace AIStudio.Wpf.DiagramDesigner
}
#region ,
protected virtual void ExecuteCreateNewDiagramCommand(object parameter)
protected virtual void ExecuteClearCommand(object parameter)
{
this.Items.Clear();
}
var items = this.Items.ToList();
DoCommandManager.DoNewCommand(this.ToString(),
() => {
this.Items.Clear();
},
() => {
foreach (var item in items)
{
Add(item);
}
});
}
private void ExecuteAddItemCommand(object parameter)
{
List<SelectableDesignerItemViewModelBase> newitems = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase ite)
{
if (AddVerify(ite) != true) return;
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ClearSelectedItems();
Add(ite);
},
() => {
Items.Remove(ite);
});
newitems.Add(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);
}
});
newitems.AddRange(items);
}
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ClearSelectedItems();
Add(newitems);
},
() => {
foreach (var item in newitems)
{
Items.Remove(item);
}
});
}
public bool AddVerify(SelectableDesignerItemViewModelBase item)
@@ -1282,13 +1270,13 @@ namespace AIStudio.Wpf.DiagramDesigner
}
//使用程序添加对象比如Demo初始化
public void Add(object parameter)
public void Add(object parameter, bool? isSelected = false)
{
if (parameter is SelectableDesignerItemViewModelBase ite)
{
if (AddVerify(ite) != true) return;
Add(ite, false);
Add(ite, isSelected);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> items)
{
@@ -1296,12 +1284,12 @@ namespace AIStudio.Wpf.DiagramDesigner
foreach (var item in items)
{
Add(item, false);
Add(item, isSelected);
}
}
}
private void Add(SelectableDesignerItemViewModelBase item, bool isSelected = true)
private void Add(SelectableDesignerItemViewModelBase item, bool? isSelected = true)
{
item.Root = this;
item.ZIndex = Items.Any() ? Items.Max(p => p.ZIndex) + 1 : 0;
@@ -1322,8 +1310,11 @@ namespace AIStudio.Wpf.DiagramDesigner
designerItemViewModelBase.SetCellAlignment();
}
Items.Add(item);
item.IsSelected = isSelected;
}
if (isSelected != null)
{
item.IsSelected = isSelected.Value;
}
}
public void Remove(object parameter)
{
@@ -1344,54 +1335,72 @@ namespace AIStudio.Wpf.DiagramDesigner
private void ExecuteRemoveItemCommand(object parameter)
{
if (parameter is SelectableDesignerItemViewModelBase ite)
List<SelectableDesignerItemViewModelBase> olditems = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase node)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ite.IsSelected = false;
Items.Remove(ite);
},
() => {
Items.Add(ite);
});
olditems.Add(node);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> items)
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
olditems.AddRange(para);
}
else
{
olditems.AddRange(SelectedItems);
}
if (olditems.Any())
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
item.IsSelected = false;
Items.Remove(item);
}
},
() => {
foreach (var item in items)
{
Items.Add(item);
}
});
() => {
foreach (var item in olditems)
{
Items.Remove(item);
}
},
() => {
foreach (var item in olditems)
{
Items.Add(item);
}
});
}
}
private void ExecuteClearSelectedItemsCommand(object parameter)
{
IEnumerable<SelectableDesignerItemViewModelBase> selectedItems;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
List<SelectableDesignerItemViewModelBase> selectedItems = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase node)
{
selectedItems = para;
selectedItems.Add(node);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectedItems.AddRange(para);
}
else
{
selectedItems = this.SelectedItems.OfType<DesignerItemViewModelBase>();
selectedItems.AddRange(SelectedItems);
}
foreach (var item in selectedItems)
if (selectedItems.Any())
{
item.IsSelected = false;
Dictionary<SelectableDesignerItemViewModelBase, bool> infos = selectedItems.ToDictionary(p => p, p => p.IsSelected);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in selectedItems)
{
item.IsSelected = false;
}
},
() => {
foreach (var item in infos)
{
item.Key.IsSelected = item.Value;
}
});
}
}
public void ClearSelectedItems()
@@ -1404,39 +1413,93 @@ namespace AIStudio.Wpf.DiagramDesigner
private void ExecuteSelectAllCommand(object parameter)
{
foreach (var item in Items)
List<SelectableDesignerItemViewModelBase> selectedItems = Items.ToList();
if (selectedItems.Any())
{
item.IsSelected = true;
Dictionary<SelectableDesignerItemViewModelBase, bool> infos = selectedItems.ToDictionary(p => p, p => p.IsSelected);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in selectedItems)
{
item.IsSelected = true;
}
},
() => {
foreach (var item in infos)
{
item.Key.IsSelected = item.Value;
}
});
}
}
private void ExecuteSelectInverseCommand(object parameter)
{
foreach (var item in SelectedItems)
List<SelectableDesignerItemViewModelBase> selectedItems = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase node)
{
item.IsSelected = false;
selectedItems.Add(node);
}
foreach (var item in Items.Except(SelectedItems))
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
item.IsSelected = true;
selectedItems.AddRange(para);
}
else
{
selectedItems.AddRange(Items);
}
if (selectedItems.Any())
{
Dictionary<SelectableDesignerItemViewModelBase, bool> infos = selectedItems.ToDictionary(p => p, p => p.IsSelected);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in selectedItems)
{
item.IsSelected = !item.IsSelected;
}
},
() => {
foreach (var item in infos)
{
item.Key.IsSelected = item.Value;
}
});
}
}
public void ExecuteSelectItemCommand(object parameter)
{
if (parameter is ISelectable selectable)
List<SelectableDesignerItemViewModelBase> selectedItems = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase node)
{
foreach (var item in this.Items.ToList())
{
if (object.Equals(selectable, item))
{
item.IsSelected = true;
}
else
{
item.IsSelected = false;
}
}
selectedItems.Add(node);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectedItems.AddRange(para);
}
else
{
selectedItems.AddRange(Items);
}
if (selectedItems.Any())
{
Dictionary<SelectableDesignerItemViewModelBase, bool> infos = selectedItems.ToDictionary(p => p, p => p.IsSelected);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in selectedItems)
{
item.IsSelected = true;
}
},
() => {
foreach (var item in infos)
{
item.Key.IsSelected = item.Value;
}
});
}
}
#endregion
@@ -1447,58 +1510,52 @@ namespace AIStudio.Wpf.DiagramDesigner
Copy(parameter);
}
private bool Copy(object parameter)
private List<SelectableDesignerItemViewModelBase> Copy(object parameter)
{
List<DesignerItemViewModelBase> selectedDesignerItems;
List<ConnectionViewModel> selectedConnections;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
List<SelectableDesignerItemViewModelBase> selectedItems = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase node)
{
selectedDesignerItems = para.OfType<DesignerItemViewModelBase>().ToList();
selectedConnections = para.OfType<ConnectionViewModel>().ToList();
selectedItems.Add(node);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
selectedItems.AddRange(para);
}
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();
selectedItems.AddRange(SelectedItems);
}
foreach (ConnectionViewModel connection in Items.OfType<ConnectionViewModel>())
if (selectedItems.Any())
{
if (!selectedConnections.Contains(connection))
var selectedDesignerItems = selectedItems.OfType<DesignerItemViewModelBase>().ToList();
var selectedConnections = selectedItems.OfType<ConnectionViewModel>().ToList();
foreach (ConnectionViewModel connection in Items.OfType<ConnectionViewModel>())
{
DesignerItemViewModelBase sourceItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SourceConnectorInfo.DataItem.Id);
DesignerItemViewModelBase sinkItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SinkConnectorInfoFully?.DataItem?.Id);
if (sourceItem != null && sinkItem != null && BelongToSameGroup(sourceItem, sinkItem))
if (!selectedConnections.Contains(connection))
{
selectedConnections.Add(connection);
DesignerItemViewModelBase sourceItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SourceConnectorInfo.DataItem.Id);
DesignerItemViewModelBase sinkItem = selectedDesignerItems.FirstOrDefault(p => p.Id == connection.SinkConnectorInfoFully?.DataItem?.Id);
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 = 0;
OffsetY = 0;
System.Windows.Clipboard.Clear();
System.Windows.Clipboard.SetData(System.Windows.DataFormats.Serializable, json);
}
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 = 0;
OffsetY = 0;
System.Windows.Clipboard.Clear();
System.Windows.Clipboard.SetData(System.Windows.DataFormats.Serializable, json);
return true;
return selectedItems;
}
private void ExecutePasteCommand(object parameter)
@@ -1506,20 +1563,21 @@ namespace AIStudio.Wpf.DiagramDesigner
Paste(parameter);
}
protected virtual bool Paste(object parameter)
protected virtual List<SelectableDesignerItemViewModelBase> Paste(object parameter, bool paste = true)
{
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;
return null;
List<SelectableDesignerItemViewModelBase> items = new List<SelectableDesignerItemViewModelBase>();
try
{
OffsetX += 10;
OffsetY += 10;
OffsetY += 10;
List<SelectableDesignerItemViewModelBase> items = new List<SelectableDesignerItemViewModelBase>();
SerializableObject copyitem = JsonConvert.DeserializeObject<SerializableObject>(clipboardData);
Dictionary<Guid, Guid> mappingOldToNewIDs = new Dictionary<Guid, Guid>();
@@ -1543,7 +1601,7 @@ namespace AIStudio.Wpf.DiagramDesigner
{
items.Add(newItem);
}
}
}
List<SelectableDesignerItemViewModelBase> connectors = new List<SelectableDesignerItemViewModelBase>();
foreach (var connection in copyitem.Connections)
@@ -1578,27 +1636,45 @@ namespace AIStudio.Wpf.DiagramDesigner
if (mappingOldToNewIDs.ContainsKey(item.ParentId))
item.ParentId = mappingOldToNewIDs[item.ParentId];
}
}
items.AddRange(connectors);
Add(items);
FixOtherInfo(items);
}
items.AddRange(connectors);
}
catch (Exception e)
{
System.Windows.MessageBox.Show(e.StackTrace, e.Message, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
return null;
}
return true;
if (items.Any())
{
if (paste)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ClearSelectedItems();
Add(items, true);
FixOtherInfo(items);
},
() => {
foreach (var item in items)
{
Items.Remove(item);
}
});
}
}
return items;
}
else
{
return false;
return null;
}
}
protected virtual void FixOtherInfo(List<SelectableDesignerItemViewModelBase> items)
{
}
private bool ItemsToDeleteHasConnector(List<SelectableDesignerItemViewModelBase> itemsToRemove, ConnectorInfoBase connector)
@@ -1616,42 +1692,70 @@ namespace AIStudio.Wpf.DiagramDesigner
Cut(parameter);
}
private bool Cut(object parameter)
private List<SelectableDesignerItemViewModelBase> Cut(object parameter, bool cut = true)
{
if (Paste(null) == false)
return false;
if (Delete(null) == false)
return false;
if (Copy(null) == null)
return null;
return true;
var items = Delete(parameter, false);
if (items.Any())
{
if (cut)
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
Items.Remove(item);
}
},
() => {
foreach (var item in items)
{
Items.Add(item);
}
});
}
}
return items;
}
protected void ExecuteDeleteCommand(object parameter)
{
Delete(parameter);
var items = Delete(parameter, false);
if (items.Any())
{
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
Items.Remove(item);
}
},
() => {
foreach (var item in items)
{
Items.Add(item);
}
});
}
}
protected virtual bool Delete(object parameter)
protected virtual List<SelectableDesignerItemViewModelBase> Delete(object parameter, bool delete = true)
{
List<SelectableDesignerItemViewModelBase> itemsToRemove;
if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
List<SelectableDesignerItemViewModelBase> itemsToRemove = new List<SelectableDesignerItemViewModelBase>();
if (parameter is SelectableDesignerItemViewModelBase node)
{
itemsToRemove = para.OfType<SelectableDesignerItemViewModelBase>().ToList();
itemsToRemove.Add(node);
}
else if (parameter is IEnumerable<SelectableDesignerItemViewModelBase> para)
{
itemsToRemove.AddRange(para);
}
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();
itemsToRemove.AddRange(SelectedItems);
}
List<SelectableDesignerItemViewModelBase> connectionsToAlsoRemove = new List<SelectableDesignerItemViewModelBase>();
@@ -1671,9 +1775,17 @@ namespace AIStudio.Wpf.DiagramDesigner
}
itemsToRemove.AddRange(connectionsToAlsoRemove);
RemoveItemCommand.Execute(itemsToRemove);
return true;
if (itemsToRemove.Any())
{
if (delete)
{
foreach (var item in itemsToRemove)
{
Items.Remove(item);
}
}
}
return itemsToRemove;
}
#endregion
@@ -2477,7 +2589,7 @@ namespace AIStudio.Wpf.DiagramDesigner
groupItem = new GroupDesignerItemViewModel();
}
Add(groupItem);
Add(groupItem, true);
foreach (DesignerItemViewModelBase item in items)
item.ParentId = groupItem.Id;
@@ -2524,22 +2636,27 @@ namespace AIStudio.Wpf.DiagramDesigner
#region
public bool ExecuteShortcut(KeyEventArgs e)
{
if (SelectedItem?.IsEditing == true)
{
return false;
}
if (DiagramOption.ShortcutOption.SelectAll(e))
{
SelectAllCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.Copy(e))
{
return Copy(null);
{
return Copy(null) != null;
}
else if (DiagramOption.ShortcutOption.Paste(e))
{
return Paste(null);
return Paste(null) != null;
}
else if (DiagramOption.ShortcutOption.Cut(e))
{
return Cut(null);
return Cut(null) != null;
}
else if (DiagramOption.ShortcutOption.Undo(e))
{
@@ -2551,7 +2668,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
else if (DiagramOption.ShortcutOption.Delete(e))
{
return Delete(null);
return Delete(null) != null;
}
else if (DiagramOption.ShortcutOption.LeftMove(e))
{
@@ -2611,7 +2728,7 @@ namespace AIStudio.Wpf.DiagramDesigner
}
private void ExecutedSearchUpCommand(object obj)
{
{
if (obj != null)
{
var selecteddesign = SelectedItem as DesignerItemViewModelBase;

View File

@@ -31,7 +31,7 @@ namespace AIStudio.Wpf.DiagramDesigner
get;
}
ICommand CreateNewDiagramCommand
ICommand ClearCommand
{
get;
}
@@ -335,7 +335,7 @@ namespace AIStudio.Wpf.DiagramDesigner
void Init(bool initNew);
void Add(object parameter);
void Add(object parameter, bool? isSelected = false);
void Remove(object parameter);

View File

@@ -774,7 +774,7 @@ namespace AIStudio.Wpf.Mind.ViewModels
items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.UpdatedLayout());
}
protected override bool Delete(object parameter)
protected override List<SelectableDesignerItemViewModelBase> Delete(object parameter, bool delete = true)
{
List<MindNode> items = new List<MindNode>();
List<SelectableDesignerItemViewModelBase> others = new List<SelectableDesignerItemViewModelBase>();
@@ -793,11 +793,6 @@ namespace AIStudio.Wpf.Mind.ViewModels
others = SelectedItems.Where(p => !(p is MindNode)).ToList();
}
if (items.FirstOrDefault()?.IsEditing != false)
{
return false;
}
if (items.Any())
{
//把子节点都加上
@@ -842,10 +837,10 @@ namespace AIStudio.Wpf.Mind.ViewModels
items.Select(p => p.RootNode).Distinct().ToList().ForEach(p => p.UpdatedLayout());
});
return true;
return items.OfType<SelectableDesignerItemViewModelBase>().ToList();
}
else
return false;
return null;
}
#endregion