Merge pull request #96 from LukeOrdelmans/bugfix/track-outline-nodes-per-context
track/cache outline nodes per DesignContext, so they can be cleaned up
This commit is contained in:
Коммит
12981b37b5
|
@ -25,9 +25,6 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
{
|
||||
public class OutlineNode: OutlineNodeBase
|
||||
{
|
||||
//TODO: Reset with DesignContext
|
||||
static Dictionary<DesignItem, IOutlineNode> outlineNodes = new Dictionary<DesignItem, IOutlineNode>();
|
||||
|
||||
protected OutlineNode(DesignItem designitem): base(designitem)
|
||||
{
|
||||
UpdateChildren();
|
||||
|
@ -43,22 +40,14 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
DummyPlacementType = PlacementType.Register("DummyPlacement");
|
||||
}
|
||||
|
||||
public static IOutlineNode Create(DesignItem designItem)
|
||||
{
|
||||
IOutlineNode node = null;
|
||||
if (designItem != null && !outlineNodes.TryGetValue(designItem, out node)) {
|
||||
node = new OutlineNode(designItem);
|
||||
outlineNodes[designItem] = node;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
[Obsolete("prefer using DesignItem.CreateOutlineNode()")]
|
||||
public static IOutlineNode Create(DesignItem designItem) => designItem.CreateOutlineNode();
|
||||
|
||||
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e)
|
||||
{
|
||||
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem);
|
||||
}
|
||||
|
||||
|
||||
protected override void UpdateChildren()
|
||||
{
|
||||
Children.Clear();
|
||||
|
@ -68,7 +57,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
{
|
||||
if (prp.Value != null) {
|
||||
var propertyNode = PropertyOutlineNode.Create(prp);
|
||||
var node = OutlineNode.Create(prp.Value);
|
||||
var node = prp.Value.CreateOutlineNode();
|
||||
propertyNode.Children.Add(node);
|
||||
Children.Add(propertyNode);
|
||||
}
|
||||
|
@ -82,7 +71,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
if (content.Value != null) {
|
||||
if (!UpdateChildrenCore(new[] {content.Value})) {
|
||||
var propertyNode = PropertyOutlineNode.Create(content);
|
||||
var node = OutlineNode.Create(content.Value);
|
||||
var node = content.Value.CreateOutlineNode();
|
||||
propertyNode.Children.Add(node);
|
||||
Children.Add(propertyNode);
|
||||
}
|
||||
|
@ -111,7 +100,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
foreach (var item in items) {
|
||||
if (ModelTools.CanSelectComponent(item)) {
|
||||
if (Children.All(x => x.DesignItem != item)) {
|
||||
var node = OutlineNode.Create(item);
|
||||
var node = item.CreateOutlineNode();
|
||||
if (index > -1) {
|
||||
Children.Insert(index++, node);
|
||||
retVal = true;
|
||||
|
@ -139,5 +128,27 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
internal class OutlineNodeService : IOutlineNodeService, IDisposable
|
||||
{
|
||||
readonly Dictionary<DesignItem, IOutlineNode> outlineNodes = new Dictionary<DesignItem, IOutlineNode>();
|
||||
|
||||
public IOutlineNode Create(DesignItem designItem)
|
||||
{
|
||||
IOutlineNode node = null;
|
||||
if (designItem != null && !outlineNodes.TryGetValue(designItem, out node))
|
||||
{
|
||||
node = new OutlineNode(designItem);
|
||||
outlineNodes[designItem] = node;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
outlineNodes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
|||
using (var moveTransaction = DesignItem.Context.OpenGroup("Item moved in outline view", nodes.Select(n => n.DesignItem).ToList()))
|
||||
{
|
||||
if (copy) {
|
||||
nodes = nodes.Select(n => OutlineNode.Create(n.DesignItem.Clone())).ToList();
|
||||
nodes = nodes.Select(n => n.DesignItem.Clone().CreateOutlineNode()).ToList();
|
||||
} else {
|
||||
foreach (var node in nodes) {
|
||||
node.DesignItem.Remove();
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
|
|||
if(control!=null){
|
||||
TypeMappings.TryGetValue(control.GetType(), out _type);
|
||||
if (_type != null) {
|
||||
IOutlineNode node = OutlineNode.Create(item);
|
||||
IOutlineNode node = item.CreateOutlineNode();
|
||||
Outline.Root = node;
|
||||
PropertyGridView.PropertyGrid.SelectedItems = item.Services.Selection.SelectedItems;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
|
|||
this.Services.AddService(typeof(UndoService), new UndoService());
|
||||
this.Services.AddService(typeof(ICopyPasteService), new CopyPasteService());
|
||||
this.Services.AddService(typeof(IErrorService), new DefaultErrorService(this));
|
||||
this.Services.AddService(typeof(IOutlineNodeService), new OutlineNode.OutlineNodeService());
|
||||
this.Services.AddService(typeof(IOutlineNodeNameService), new OutlineNodeNameService());
|
||||
this.Services.AddService(typeof(ViewService), new DefaultViewService(this));
|
||||
this.Services.AddService(typeof(OptionService), new OptionService());
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
|||
public void Intialize()
|
||||
{
|
||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
||||
_outline = OutlineNode.Create(_grid);
|
||||
_outline = _grid.CreateOutlineNode();
|
||||
Assert.IsNotNull(_outline);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
|||
public void Intialize()
|
||||
{
|
||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
||||
_outline = OutlineNode.Create(_grid);
|
||||
_outline = _grid.CreateOutlineNode();
|
||||
Assert.IsNotNull(_outline);
|
||||
|
||||
_gridButton = _grid.ContentProperty.CollectionElements[0];
|
||||
|
@ -176,7 +176,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
|||
public void Intialize()
|
||||
{
|
||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Image/></StackPanel>");
|
||||
_outline = OutlineNode.Create(_grid);
|
||||
_outline = _grid.CreateOutlineNode();
|
||||
Assert.IsNotNull(_outline);
|
||||
|
||||
_gridButton = _grid.ContentProperty.CollectionElements[0];
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
|||
public void Intialize()
|
||||
{
|
||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
||||
_outline = OutlineNode.Create(_grid);
|
||||
_outline = _grid.CreateOutlineNode();
|
||||
Assert.IsNotNull(_outline);
|
||||
|
||||
var selection = _grid.Services.Selection;
|
||||
|
|
|
@ -354,7 +354,12 @@ namespace ICSharpCode.WpfDesign
|
|||
/// Creates a copy of this design item.
|
||||
/// </summary>
|
||||
public abstract DesignItem Clone();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="IOutlineNode"/> for this this design item.
|
||||
/// </summary>
|
||||
public IOutlineNode CreateOutlineNode() => Services.GetRequiredService<IOutlineNodeService>().Create(this);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Transform"/> that represents all transforms applied to the item's view.
|
||||
/// </summary>
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
||||
{
|
||||
public interface IOutlineNode
|
||||
{
|
||||
ISelectionService SelectionService { get; }
|
||||
bool IsExpanded { get; set; }
|
||||
DesignItem DesignItem { get; set; }
|
||||
ServiceContainer Services { get; }
|
||||
bool IsSelected { get; set; }
|
||||
bool IsDesignTimeVisible { get; set; }
|
||||
bool IsDesignTimeLocked { get; }
|
||||
string Name { get; }
|
||||
bool CanInsert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
||||
void Insert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
||||
ObservableCollection<IOutlineNode> Children { get; }
|
||||
}
|
||||
}
|
||||
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace ICSharpCode.WpfDesign
|
||||
{
|
||||
public interface IOutlineNode
|
||||
{
|
||||
ISelectionService SelectionService { get; }
|
||||
bool IsExpanded { get; set; }
|
||||
DesignItem DesignItem { get; set; }
|
||||
ServiceContainer Services { get; }
|
||||
bool IsSelected { get; set; }
|
||||
bool IsDesignTimeVisible { get; set; }
|
||||
bool IsDesignTimeLocked { get; }
|
||||
string Name { get; }
|
||||
bool CanInsert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
||||
void Insert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
||||
ObservableCollection<IOutlineNode> Children { get; }
|
||||
}
|
||||
}
|
|
@ -222,7 +222,20 @@ namespace ICSharpCode.WpfDesign
|
|||
object GetDescription(DesignItemProperty designProperty);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region IOutlineNodeService
|
||||
/// <summary>
|
||||
/// Used to create Outline Nodes.
|
||||
/// </summary>
|
||||
public interface IOutlineNodeService
|
||||
{
|
||||
/// <summary>
|
||||
/// Create Ouline Node for the DesignItem, returns cached item if available.
|
||||
/// </summary>
|
||||
IOutlineNode Create(DesignItem designItem);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IOutlineNodeNameService
|
||||
/// <summary>
|
||||
/// Used to get a description for the Outline Node.
|
||||
|
|
|
@ -247,7 +247,7 @@ namespace ICSharpCode.XamlDesigner
|
|||
DesignSurface.LoadDesigner(xmlReader, settings);
|
||||
}
|
||||
if (DesignContext.RootItem != null) {
|
||||
OutlineRoot = OutlineNode.Create(DesignContext.RootItem);
|
||||
OutlineRoot = DesignContext.RootItem.CreateOutlineNode();
|
||||
UndoService.UndoStackChanged += new EventHandler(UndoService_UndoStackChanged);
|
||||
}
|
||||
RaisePropertyChanged("SelectionService");
|
||||
|
|
Загрузка…
Ссылка в новой задаче