From 8d88b14d780e9e854c20e55da6366953c5b5f4e2 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Sun, 30 Aug 2020 13:12:39 +0200 Subject: [PATCH] Profile editor - Fixed tree responsiveness while moving elements --- .../ProfileTree/ProfileTreeViewModel.cs | 20 +++++++-- .../ProfileTree/TreeItem/TreeItemViewModel.cs | 42 ++++++++++++++----- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs index 24f8d0870..aaaea4220 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/ProfileTreeViewModel.cs @@ -84,7 +84,9 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree break; } + Unsubscribe(); _profileEditorService.UpdateSelectedProfile(); + Subscribe(); } // ReSharper disable once UnusedMember.Global - Called from view @@ -152,15 +154,13 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree protected override void OnInitialActivate() { - _profileEditorService.ProfileSelected += OnProfileSelected; - _profileEditorService.ProfileElementSelected += OnProfileElementSelected; + Subscribe(); CreateRootFolderViewModel(); } protected override void OnClose() { - _profileEditorService.ProfileSelected -= OnProfileSelected; - _profileEditorService.ProfileElementSelected -= OnProfileElementSelected; + Unsubscribe(); RootFolder?.Dispose(); RootFolder = null; @@ -169,6 +169,18 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree #region Event handlers + private void Subscribe() + { + _profileEditorService.ProfileSelected += OnProfileSelected; + _profileEditorService.ProfileElementSelected += OnProfileElementSelected; + } + + private void Unsubscribe() + { + _profileEditorService.ProfileSelected -= OnProfileSelected; + _profileEditorService.ProfileElementSelected -= OnProfileElementSelected; + } + private void OnProfileElementSelected(object sender, RenderProfileElementEventArgs e) { if (e.RenderProfileElement == SelectedTreeItem?.ProfileElement) diff --git a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs index 094676aac..0e7f14150 100644 --- a/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs +++ b/src/Artemis.UI/Screens/ProfileEditor/ProfileTree/TreeItem/TreeItemViewModel.cs @@ -41,9 +41,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem Children = new BindableCollection(); - ProfileElement.ChildAdded += ProfileElementOnChildAdded; - ProfileElement.ChildRemoved += ProfileElementOnChildRemoved; - + Subscribe(); UpdateProfileElements(); } @@ -65,9 +63,7 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem public void Dispose() { - ProfileElement.ChildAdded -= ProfileElementOnChildAdded; - ProfileElement.ChildRemoved -= ProfileElementOnChildRemoved; - + Unsubscribe(); Dispose(true); GC.SuppressFinalize(this); } @@ -94,8 +90,12 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem Parent.AddExistingElement(source); } + Parent.Unsubscribe(); Parent.ProfileElement.RemoveChild(source.ProfileElement); Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order); + Parent.Subscribe(); + + Parent.UpdateProfileElements(); } public void SetElementBehind(TreeItemViewModel source) @@ -106,8 +106,12 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem Parent.AddExistingElement(source); } + Parent.Unsubscribe(); Parent.ProfileElement.RemoveChild(source.ProfileElement); Parent.ProfileElement.AddChild(source.ProfileElement, ProfileElement.Order + 1); + Parent.Subscribe(); + + Parent.UpdateProfileElements(); } public void RemoveExistingElement(TreeItemViewModel treeItem) @@ -116,7 +120,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem throw new ArtemisUIException("Cannot remove a child from a profile element of type " + ProfileElement.GetType().Name); ProfileElement.RemoveChild(treeItem.ProfileElement); - Children.Remove(treeItem); treeItem.Parent = null; treeItem.Dispose(); } @@ -127,7 +130,6 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem throw new ArtemisUIException("Cannot add a child to a profile element of type " + ProfileElement.GetType().Name); ProfileElement.AddChild(treeItem.ProfileElement); - Children.Add(treeItem); treeItem.Parent = this; } @@ -187,12 +189,18 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem public void UpdateProfileElements() { + // Remove VMs that are no longer a child + var toRemove = Children.Where(c => c.ProfileElement.Parent != ProfileElement).ToList(); + foreach (var treeItemViewModel in toRemove) + Children.Remove(treeItemViewModel); + // Order the children var vmsList = Children.OrderBy(v => v.ProfileElement.Order).ToList(); for (var index = 0; index < vmsList.Count; index++) { var profileElementViewModel = vmsList[index]; - Children.Move(Children.IndexOf(profileElementViewModel), index); + if (Children.IndexOf(profileElementViewModel) != index) + Children.Move(Children.IndexOf(profileElementViewModel), index); } // Ensure every child element has an up-to-date VM @@ -218,9 +226,11 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem return; // Add the new children in one call, prevent extra UI events - Children.AddRange(newChildren); foreach (var treeItemViewModel in newChildren) + { treeItemViewModel.UpdateProfileElements(); + Children.Add(treeItemViewModel); + } } public void EnableToggled() @@ -235,6 +245,18 @@ namespace Artemis.UI.Screens.ProfileEditor.ProfileTree.TreeItem } } + private void Subscribe() + { + ProfileElement.ChildAdded += ProfileElementOnChildAdded; + ProfileElement.ChildRemoved += ProfileElementOnChildRemoved; + } + + private void Unsubscribe() + { + ProfileElement.ChildAdded -= ProfileElementOnChildAdded; + ProfileElement.ChildRemoved -= ProfileElementOnChildRemoved; + } + private void ProfileElementOnChildRemoved(object sender, EventArgs e) { UpdateProfileElements();