using System; using System.Collections.Generic; using System.Linq; using System.Windows.Input; using System.Windows.Media; using AIStudio.Wpf.DiagramDesigner; using AIStudio.Wpf.DiagramDesigner.Geometrys; using AIStudio.Wpf.Mind.Helpers; namespace AIStudio.Wpf.Mind.ViewModels { public class MindDiagramViewModel : DiagramViewModel, IMindDiagramViewModel { #region private MindType _mindType = Mind.MindType.Mind; public MindType MindType { get { return _mindType; } set { if (SetProperty(ref _mindType, value)) { ExecutedChangeMindTypeCommand(value); } } } private MindThemeModel _mindThemeModel = MindThemeHelper.GetTheme("天空蓝"); public MindThemeModel MindThemeModel { get { return _mindThemeModel; } set { SetProperty(ref _mindThemeModel, value); } } public List RootItems { get { return Items.OfType().Where(p => p.NodeLevel == 0).ToList(); } } public MindNode MindSelectedItem { get { return SelectedItem as MindNode; } } #endregion #region 命令 private ICommand _addRootCommand; public ICommand AddRootCommand { get { return this._addRootCommand ?? (this._addRootCommand = new SimpleCommand(ExecuteEnable, this.ExecuteAddRootCommand)); } } private ICommand _addParentCommand; public ICommand AddParentCommand { get { return this._addParentCommand ?? (this._addParentCommand = new SimpleCommand(MindLevelEnable, this.ExecuteAddParentCommand)); } } private ICommand _addChildCommand; public ICommand AddChildCommand { get { return this._addChildCommand ?? (this._addChildCommand = new SimpleCommand(MindExecuteEnable, this.ExecuteAddChildCommand)); } } private ICommand _AddPearCommand; public ICommand AddPearCommand { get { return this._AddPearCommand ?? (this._AddPearCommand = new SimpleCommand(MindLevelEnable, this.ExecuteAddPearCommand)); } } private ICommand _moveForwardCommand; public ICommand MoveForwardCommand { get { return this._moveForwardCommand ?? (this._moveForwardCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveForwardCommand)); } } private ICommand _moveBackCommand; public ICommand MoveBackCommand { get { return this._moveBackCommand ?? (this._moveBackCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveBackCommand)); } } private ICommand _deleteCommand; public override ICommand DeleteCommand { get { return this._deleteCommand ?? (this._deleteCommand = new SimpleCommand(MindLevelEnable, ExecuteDeleteCommand)); } } private ICommand _selectBrotherCommand; public ICommand SelectBrotherCommand { get { return this._selectBrotherCommand ?? (this._selectBrotherCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectBrotherCommand)); } } private ICommand _selectPearCommand; public ICommand SelectPearCommand { get { return this._selectPearCommand ?? (this._selectPearCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectPearCommand)); } } private ICommand _selectRouteCommand; public ICommand SelectRouteCommand { get { return this._selectRouteCommand ?? (this._selectRouteCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectRouteCommand)); } } private ICommand _selectChildCommand; public ICommand SelectChildCommand { get { return this._selectChildCommand ?? (this._selectChildCommand = new SimpleCommand(MindLevelEnable, ExecuteSelectChildCommand)); } } private ICommand _addLinkCommand; public ICommand AddLinkCommand { get { return this._addLinkCommand ?? (this._addLinkCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddLinkCommand)); } } private ICommand _removeLinkCommand; public ICommand RemoveLinkCommand { get { return this._removeLinkCommand ?? (this._removeLinkCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveLinkCommand)); } } private ICommand _addImageCommand; public ICommand AddImageCommand { get { return this._addImageCommand ?? (this._addImageCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddImageCommand)); } } private ICommand _removeImageCommand; public ICommand RemoveImageCommand { get { return this._removeImageCommand ?? (this._removeImageCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveImageCommand)); } } private ICommand _addRemarkCommand; public ICommand AddRemarkCommand { get { return this._addRemarkCommand ?? (this._addRemarkCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddRemarkCommand)); } } private ICommand _removeRemarkCommand; public ICommand RemoveRemarkCommand { get { return this._removeRemarkCommand ?? (this._removeRemarkCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveRemarkCommand)); } } private ICommand _addPriorityCommand; public ICommand AddPriorityCommand { get { return this._addPriorityCommand ?? (this._addPriorityCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddPriorityCommand)); } } private ICommand _addRatioCommand; public ICommand AddRatioCommand { get { return this._addRatioCommand ?? (this._addRatioCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddRatioCommand)); } } private ICommand _addTagCommand; public ICommand AddTagCommand { get { return this._addTagCommand ?? (this._addTagCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddTagCommand)); } } private ICommand _removeTagCommand; public ICommand RemoveTagCommand { get { return this._removeTagCommand ?? (this._removeTagCommand = new SimpleCommand(MindExecuteEnable, ExecuteRemoveTagCommand)); } } private ICommand _changeMindTypeCommand; public ICommand ChangeMindTypeCommand { get { return this._changeMindTypeCommand ?? (this._changeMindTypeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedChangeMindTypeCommand)); } } private ICommand _changeMindThemeCommand; public ICommand ChangeMindThemeCommand { get { return this._changeMindThemeCommand ?? (this._changeMindThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedChangeMindThemeCommand)); } } private ICommand _clearThemeCommand; public ICommand ClearThemeCommand { get { return this._clearThemeCommand ?? (this._clearThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedClearThemeCommand)); } } private ICommand _copyThemeCommand; public ICommand CopyThemeCommand { get { return this._copyThemeCommand ?? (this._copyThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedCopyThemeCommand)); } } private ICommand _pasteThemeCommand; public ICommand PasteThemeCommand { get { return this._pasteThemeCommand ?? (this._pasteThemeCommand = new SimpleCommand(ExecuteEnable, this.ExecutedPasteThemeCommand)); } } private ICommand _expand2LevelCommand; public ICommand Expand2LevelCommand { get { return this._expand2LevelCommand ?? (this._expand2LevelCommand = new SimpleCommand(ExecuteEnable, this.ExecutedExpand2LevelCommand)); } } #endregion #region ctor和初始化 public MindDiagramViewModel() { } public override void Init() { if (Items.Count == 0) { InitRootItem(); } ResetChildren(RootItems); RootItems?.ForEach(p => p.LayoutUpdated()); base.Init(); } public void InitRootItem() { ClearSelectedItemsCommand.Execute(null); MindNode level1node = new MindNode(this) { Root = this, Id = Guid.NewGuid(), Text = "思维导图" }; level1node.InitLayout(true); Items.Add(level1node); level1node.IsSelected = true; CenterMoveCommand.Execute(level1node); } protected override void ExecutedResetLayoutCommand(object obj) { foreach (var item in Items.OfType()) { item.Offset = new DiagramDesigner.Geometrys.PointBase(); } RootItems?.ForEach(p => p.LayoutUpdated()); } private void ResetChildren(IEnumerable parents) { if (parents == null) return; foreach (var parent in parents) { parent.Children = new System.Collections.ObjectModel.ObservableCollection(Items.OfType().Where(p => p.ParentId == parent.Id)); foreach (var item in Items.OfType().Where(p => p.ParentId == parent.Id).ToList()) { item.Parent = parent; item.InitLayout(false); item.InitConnectLayout(); } ResetChildren(parent.Children); } } private List GetParent(MindNode node) { List mindnode = new List(); while (node.ParentNode != null) { mindnode.Add(node.ParentNode); node = node.ParentNode; } return mindnode; } private List GetChildren(MindNode parent) { List mindnode = new List(); if (parent.Children != null) { foreach (var child in parent.Children) { mindnode.Add(child); mindnode.AddRange(GetChildren(child)); } } return mindnode; } #endregion #region 命令使能 public bool MindExecuteEnable(object para) { if (ExecuteEnable(para) == false) return false; if (SelectedItem is MindNode) return true; return false; } private bool MindLevelEnable(object obj) { if (MindExecuteEnable(obj) == false) return false; return (SelectedItem as MindNode).NodeLevel != 0; } #endregion #region 新增,删除 public void ExecuteAddRootCommand(object parameter) { InitRootItem(); } public void ExecuteAddChildCommand(object parameter) { List items = new List(); if (parameter is MindNode parent) { } else if (parameter is IEnumerable para) { parent = para.FirstOrDefault();//第一个固定为父节点 items = para.Skip(1).ToList(); } else { parent = SelectedItem as MindNode; } if (items?.Count == 0) { var node = new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" }; items.Add(node); } DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var item in items) { parent.AddChild(item); } parent.LayoutUpdated(); }, () => { foreach (var item in items) { parent.RemoveChild(item); } parent.LayoutUpdated(); }); } public void ExecuteAddParentCommand(object parameter) { List items = new List(); if (parameter is MindNode node) { } else if (parameter is IEnumerable para) { node = para.FirstOrDefault();//第一个固定为父节点 items = para.Skip(1).ToList(); } else { node = SelectedItem as MindNode; } if (node.Parent is MindNode parent) { if (items?.Count == 0) { items.Add(new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" }); } DoCommandManager.DoNewCommand(this.ToString(), () => { int index = parent.Children.IndexOf(node); parent.AddChild(items[0], index + 1); parent.RemoveChild(node); items[0].AddChild(node); parent.LayoutUpdated(); }, () => { int index = parent.Children.IndexOf(items[0]); items[0].RemoveChild(node); parent.AddChild(node, index + 1); parent.LayoutUpdated(); }); } } public void ExecuteAddPearCommand(object parameter) { List items = new List(); if (parameter is MindNode pear) { } else if (parameter is IEnumerable para) { pear = para.FirstOrDefault();//第一个固定为同级节点 items = para.Skip(1).ToList(); } else { pear = SelectedItem as MindNode; } if (pear.Parent is MindNode parent) { if (items?.Count == 0) { var node = new MindNode(this) { Text = $"分支主题{parent.Children.Count + 1}" }; items.Add(node); } DoCommandManager.DoNewCommand(this.ToString(), () => { int index = parent.Children.IndexOf(pear); for (int i = 0; i < items.Count; i++) { parent.AddChild(items[i], index + i + 1); } parent.LayoutUpdated(); }, () => { for (int i = 0; i < items.Count; i++) { parent.RemoveChild(items[i]); } parent.LayoutUpdated(); }); } } private void ExecuteMoveBackCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node.Parent is MindNode parent) { DoCommandManager.DoNewCommand(this.ToString(), () => { int index = parent.Children.IndexOf(node); if (index < parent.Children.Count - 1) { parent.RemoveChild(node); parent.AddChild(node, index + 1); parent.LayoutUpdated(); } }, () => { int index = parent.Children.IndexOf(node); if (index > 0) { parent.RemoveChild(node); parent.AddChild(node, index - 1); parent.LayoutUpdated(); } }); } } private void ExecuteMoveForwardCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node.Parent is MindNode parent) { DoCommandManager.DoNewCommand(this.ToString(), () => { int index = parent.Children.IndexOf(node); if (index > 0) { parent.RemoveChild(node); parent.AddChild(node, index - 1); parent.LayoutUpdated(); } }, () => { int index = parent.Children.IndexOf(node); if (index < parent.Children.Count - 1) { parent.RemoveChild(node); parent.AddChild(node, index + 1); parent.LayoutUpdated(); } }); } } protected override bool Delete(object parameter) { List nodes = new List(); List others = new List(); if (parameter is MindNode node1) { nodes.Add(node1); } else if (parameter is IEnumerable para) { nodes.AddRange(para); } else { nodes.AddRange(SelectedItems.OfType()); others = SelectedItems.Where(p => !(p is MindNode)).ToList(); } if (nodes.FirstOrDefault()?.IsEditing != false) { return false; } if (nodes.Any()) { Dictionary indexs = nodes.ToDictionary(p => p, p => p.ParentNode != null ? p.ParentNode.Children.IndexOf(p) : 0); DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var node in nodes) { node.Remove(true); } RootItems.ForEach(p => p.LayoutUpdated()); if (others.Any()) { base.Delete(others); } }, () => { foreach (var node in nodes) { node.ParentNode.AddChild(node, indexs[node]); } RootItems.ForEach(p => p.LayoutUpdated()); }); return true; } else return false; } #endregion #region 复制,粘贴 protected override void FixOtherInfo(List items) { List parents = new List(); foreach (var item in items.OfType()) { //item.DesiredPosition = new PointBase(item.DesiredPosition?.X ?? 0 + OffsetX, item.DesiredPosition?.Y ?? 0 + OffsetY); var parent = Items.OfType().FirstOrDefault(p => p.Id == item.ParentId); if (parent != null && !items.Contains(parent)) { parents.Add(parent); } else if (item.ParentId == Guid.Empty) { item.Offset = new PointBase(OffsetX, OffsetX); parents.Add(item); item.InitLayout(false); } } ResetChildren(parents); parents.ForEach(p => p.LayoutUpdated()); } #endregion #region 附加信息 private void ExecuteAddLinkCommand(object obj) { if (obj is object[] array && array.Length == 2) { SelectedItems.OfType().ToList().ForEach(p => { if (p.LinkInfo == null) p.LinkInfo = new LinkInfo(); p.LinkInfo.Link = array[0]?.ToString(); p.LinkInfo.Text = array[1]?.ToString(); }); } } private void ExecuteRemoveLinkCommand(object obj) { SelectedItems.OfType().ToList().ForEach(p => { if (p.LinkInfo != null) { p.LinkInfo.Link = null; p.LinkInfo.Text = null; } }); } private void ExecuteAddImageCommand(object obj) { if (obj is object[] array && array.Length == 2) { SelectedItems.OfType().ToList().ForEach(p => { if (p.ImageInfo == null) p.ImageInfo = new ImageInfo(); p.ImageInfo.Url = array[0]?.ToString(); p.ImageInfo.Text = array[1]?.ToString(); }); } } private void ExecuteRemoveImageCommand(object obj) { SelectedItems.OfType().ToList().ForEach(p => { if (p.ImageInfo != null) { p.ImageInfo.Url = null; p.ImageInfo.Text = null; } }); } private void ExecuteAddRemarkCommand(object obj) { SelectedItems.OfType().ToList().ForEach(p => p.Remark = obj?.ToString()); } private void ExecuteRemoveRemarkCommand(object obj) { SelectedItems.OfType().ToList().ForEach(p => p.Remark = null); } private void ExecuteAddPriorityCommand(object obj) { if (double.TryParse(obj.ToString(), out var priority)) { SelectedItems.OfType().ToList().ForEach(p => p.Priority = priority); } else { SelectedItems.OfType().ToList().ForEach(p => p.Priority = null); } } private void ExecuteAddRatioCommand(object obj) { if (double.TryParse(obj.ToString(), out var rate)) { SelectedItems.OfType().ToList().ForEach(p => p.Rate = rate); } else { SelectedItems.OfType().ToList().ForEach(p => p.Rate = null); } } private void ExecuteAddTagCommand(object obj) { SelectedItems.OfType().ToList().ForEach(p => { p.Tags.Add(obj?.ToString()); }); } private void ExecuteRemoveTagCommand(object obj) { SelectedItems.OfType().ToList().ForEach(p => { p.Tags.Remove(obj?.ToString()); }); } #endregion #region 改变模式,主题 private void ExecutedChangeMindTypeCommand(object obj) { if (obj is MindType mindType) { Items.OfType().ToList().ForEach(item => { item.InitLayout(true); }); Items.OfType().ToList().ForEach(item => { item.InitConnectLayout(); }); RootItems?.ForEach(p => p.LayoutUpdated()); } } private void ExecutedChangeMindThemeCommand(object obj) { if (obj is string mindThemeModel) { MindThemeModel = MindThemeHelper.GetTheme(mindThemeModel); if (MindThemeModel?.Dark == true) { PageBackground = Colors.Black; } else { PageBackground = Colors.White; } Items.OfType().ToList().ForEach(item => { item.ThemeChange(); }); } } private void ExecutedClearThemeCommand(object parameter) { List nodes = new List(); if (parameter is MindNode node1) { nodes.Add(node1); } else if (parameter is IEnumerable para) { nodes.AddRange(para); } else { nodes.AddRange(SelectedItems.OfType()); } if (nodes.Any()) { DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var node in nodes) { node.ThemeChange(); } }, () => { //ToDo }); } } private MindNode _formatNode; private void ExecutedCopyThemeCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node != null) { _formatNode = node; } } private void ExecutedPasteThemeCommand(object parameter) { if (_formatNode != null) { List nodes = new List(); if (parameter is MindNode node1) { nodes.Add(node1); } else if (parameter is IEnumerable para) { nodes.AddRange(para); } else { nodes.AddRange(SelectedItems.OfType()); } if (nodes.Any()) { DoCommandManager.DoNewCommand(this.ToString(), () => { foreach (var node in nodes) { CopyHelper.CopyPropertyValue(_formatNode.ColorViewModel, node.ColorViewModel); CopyHelper.CopyPropertyValue(_formatNode.FontViewModel, node.FontViewModel); } }, () => { //ToDo }); } } } #endregion #region 操作 protected override void ExecuteCenterMoveCommand(object parameter) { var rootitem = MindSelectedItem?.RootNode; if (rootitem != null) { rootitem.Left = (PageSize.Width - rootitem.ItemWidth) / 2; rootitem.Top = (PageSize.Height - rootitem.ItemHeight) / 2; rootitem?.LayoutUpdated(); FitViewModel = new FitViewModel() { BoundingRect = rootitem.GetBounds() }; } } private void ExecutedExpand2LevelCommand(object obj) { int level = 0; int.TryParse(obj?.ToString(), out level); foreach (var item in Items.OfType()) { if (item.NodeLevel == 0) { continue; } else if (item.NodeLevel < level) { item.IsExpanded = true; } else { item.IsExpanded = false; } } } protected void ExecuteSelectBrotherCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node != null && node.ParentNode != null) { foreach (var child in node.ParentNode.Children) { child.IsSelected = true; } } } protected void ExecuteSelectPearCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node != null) { foreach (var item in Items.OfType().Where(p => p.NodeLevel == node.NodeLevel)) { item.IsSelected = true; } } } protected void ExecuteSelectRouteCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node != null) { GetParent(node).ForEach(p => p.IsSelected = true); } } protected void ExecuteSelectChildCommand(object parameter) { if (parameter is MindNode node) { } else { node = SelectedItem as MindNode; } if (node != null) { GetChildren(node).ForEach(p => p.IsSelected = true); } } #endregion } }