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
|
public class OutlineNode: OutlineNodeBase
|
||||||
{
|
{
|
||||||
//TODO: Reset with DesignContext
|
|
||||||
static Dictionary<DesignItem, IOutlineNode> outlineNodes = new Dictionary<DesignItem, IOutlineNode>();
|
|
||||||
|
|
||||||
protected OutlineNode(DesignItem designitem): base(designitem)
|
protected OutlineNode(DesignItem designitem): base(designitem)
|
||||||
{
|
{
|
||||||
UpdateChildren();
|
UpdateChildren();
|
||||||
|
@ -43,22 +40,14 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
||||||
DummyPlacementType = PlacementType.Register("DummyPlacement");
|
DummyPlacementType = PlacementType.Register("DummyPlacement");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IOutlineNode Create(DesignItem designItem)
|
[Obsolete("prefer using DesignItem.CreateOutlineNode()")]
|
||||||
{
|
public static IOutlineNode Create(DesignItem designItem) => designItem.CreateOutlineNode();
|
||||||
IOutlineNode node = null;
|
|
||||||
if (designItem != null && !outlineNodes.TryGetValue(designItem, out node)) {
|
|
||||||
node = new OutlineNode(designItem);
|
|
||||||
outlineNodes[designItem] = node;
|
|
||||||
}
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e)
|
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e)
|
||||||
{
|
{
|
||||||
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem);
|
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void UpdateChildren()
|
protected override void UpdateChildren()
|
||||||
{
|
{
|
||||||
Children.Clear();
|
Children.Clear();
|
||||||
|
@ -68,7 +57,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
||||||
{
|
{
|
||||||
if (prp.Value != null) {
|
if (prp.Value != null) {
|
||||||
var propertyNode = PropertyOutlineNode.Create(prp);
|
var propertyNode = PropertyOutlineNode.Create(prp);
|
||||||
var node = OutlineNode.Create(prp.Value);
|
var node = prp.Value.CreateOutlineNode();
|
||||||
propertyNode.Children.Add(node);
|
propertyNode.Children.Add(node);
|
||||||
Children.Add(propertyNode);
|
Children.Add(propertyNode);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +71,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
||||||
if (content.Value != null) {
|
if (content.Value != null) {
|
||||||
if (!UpdateChildrenCore(new[] {content.Value})) {
|
if (!UpdateChildrenCore(new[] {content.Value})) {
|
||||||
var propertyNode = PropertyOutlineNode.Create(content);
|
var propertyNode = PropertyOutlineNode.Create(content);
|
||||||
var node = OutlineNode.Create(content.Value);
|
var node = content.Value.CreateOutlineNode();
|
||||||
propertyNode.Children.Add(node);
|
propertyNode.Children.Add(node);
|
||||||
Children.Add(propertyNode);
|
Children.Add(propertyNode);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +100,7 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
||||||
foreach (var item in items) {
|
foreach (var item in items) {
|
||||||
if (ModelTools.CanSelectComponent(item)) {
|
if (ModelTools.CanSelectComponent(item)) {
|
||||||
if (Children.All(x => x.DesignItem != item)) {
|
if (Children.All(x => x.DesignItem != item)) {
|
||||||
var node = OutlineNode.Create(item);
|
var node = item.CreateOutlineNode();
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
Children.Insert(index++, node);
|
Children.Insert(index++, node);
|
||||||
retVal = true;
|
retVal = true;
|
||||||
|
@ -139,5 +128,27 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
||||||
|
|
||||||
return retVal;
|
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()))
|
using (var moveTransaction = DesignItem.Context.OpenGroup("Item moved in outline view", nodes.Select(n => n.DesignItem).ToList()))
|
||||||
{
|
{
|
||||||
if (copy) {
|
if (copy) {
|
||||||
nodes = nodes.Select(n => OutlineNode.Create(n.DesignItem.Clone())).ToList();
|
nodes = nodes.Select(n => n.DesignItem.Clone().CreateOutlineNode()).ToList();
|
||||||
} else {
|
} else {
|
||||||
foreach (var node in nodes) {
|
foreach (var node in nodes) {
|
||||||
node.DesignItem.Remove();
|
node.DesignItem.Remove();
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace ICSharpCode.WpfDesign.Designer.PropertyGrid.Editors
|
||||||
if(control!=null){
|
if(control!=null){
|
||||||
TypeMappings.TryGetValue(control.GetType(), out _type);
|
TypeMappings.TryGetValue(control.GetType(), out _type);
|
||||||
if (_type != null) {
|
if (_type != null) {
|
||||||
IOutlineNode node = OutlineNode.Create(item);
|
IOutlineNode node = item.CreateOutlineNode();
|
||||||
Outline.Root = node;
|
Outline.Root = node;
|
||||||
PropertyGridView.PropertyGrid.SelectedItems = item.Services.Selection.SelectedItems;
|
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(UndoService), new UndoService());
|
||||||
this.Services.AddService(typeof(ICopyPasteService), new CopyPasteService());
|
this.Services.AddService(typeof(ICopyPasteService), new CopyPasteService());
|
||||||
this.Services.AddService(typeof(IErrorService), new DefaultErrorService(this));
|
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(IOutlineNodeNameService), new OutlineNodeNameService());
|
||||||
this.Services.AddService(typeof(ViewService), new DefaultViewService(this));
|
this.Services.AddService(typeof(ViewService), new DefaultViewService(this));
|
||||||
this.Services.AddService(typeof(OptionService), new OptionService());
|
this.Services.AddService(typeof(OptionService), new OptionService());
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
||||||
public void Intialize()
|
public void Intialize()
|
||||||
{
|
{
|
||||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
||||||
_outline = OutlineNode.Create(_grid);
|
_outline = _grid.CreateOutlineNode();
|
||||||
Assert.IsNotNull(_outline);
|
Assert.IsNotNull(_outline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
||||||
public void Intialize()
|
public void Intialize()
|
||||||
{
|
{
|
||||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
||||||
_outline = OutlineNode.Create(_grid);
|
_outline = _grid.CreateOutlineNode();
|
||||||
Assert.IsNotNull(_outline);
|
Assert.IsNotNull(_outline);
|
||||||
|
|
||||||
_gridButton = _grid.ContentProperty.CollectionElements[0];
|
_gridButton = _grid.ContentProperty.CollectionElements[0];
|
||||||
|
@ -176,7 +176,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
||||||
public void Intialize()
|
public void Intialize()
|
||||||
{
|
{
|
||||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Image/></StackPanel>");
|
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Image/></StackPanel>");
|
||||||
_outline = OutlineNode.Create(_grid);
|
_outline = _grid.CreateOutlineNode();
|
||||||
Assert.IsNotNull(_outline);
|
Assert.IsNotNull(_outline);
|
||||||
|
|
||||||
_gridButton = _grid.ContentProperty.CollectionElements[0];
|
_gridButton = _grid.ContentProperty.CollectionElements[0];
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace ICSharpCode.WpfDesign.Tests.Designer.OutlineView
|
||||||
public void Intialize()
|
public void Intialize()
|
||||||
{
|
{
|
||||||
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
_grid = CreateGridContextWithDesignSurface("<Button/><StackPanel><Button/></StackPanel>");
|
||||||
_outline = OutlineNode.Create(_grid);
|
_outline = _grid.CreateOutlineNode();
|
||||||
Assert.IsNotNull(_outline);
|
Assert.IsNotNull(_outline);
|
||||||
|
|
||||||
var selection = _grid.Services.Selection;
|
var selection = _grid.Services.Selection;
|
||||||
|
|
|
@ -354,7 +354,12 @@ namespace ICSharpCode.WpfDesign
|
||||||
/// Creates a copy of this design item.
|
/// Creates a copy of this design item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract DesignItem Clone();
|
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>
|
/// <summary>
|
||||||
/// Gets a <see cref="Transform"/> that represents all transforms applied to the item's view.
|
/// Gets a <see cref="Transform"/> that represents all transforms applied to the item's view.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
|
// Copyright (c) 2019 AlphaSierraPapa for the SharpDevelop Team
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
// 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
|
// software and associated documentation files (the "Software"), to deal in the Software
|
||||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
// 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
|
// 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:
|
// 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
|
// The above copyright notice and this permission notice shall be included in all copies or
|
||||||
// substantial portions of the Software.
|
// substantial portions of the Software.
|
||||||
//
|
//
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
// 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
|
// 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
|
// 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
|
// 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
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
|
||||||
namespace ICSharpCode.WpfDesign.Designer.OutlineView
|
namespace ICSharpCode.WpfDesign
|
||||||
{
|
{
|
||||||
public interface IOutlineNode
|
public interface IOutlineNode
|
||||||
{
|
{
|
||||||
ISelectionService SelectionService { get; }
|
ISelectionService SelectionService { get; }
|
||||||
bool IsExpanded { get; set; }
|
bool IsExpanded { get; set; }
|
||||||
DesignItem DesignItem { get; set; }
|
DesignItem DesignItem { get; set; }
|
||||||
ServiceContainer Services { get; }
|
ServiceContainer Services { get; }
|
||||||
bool IsSelected { get; set; }
|
bool IsSelected { get; set; }
|
||||||
bool IsDesignTimeVisible { get; set; }
|
bool IsDesignTimeVisible { get; set; }
|
||||||
bool IsDesignTimeLocked { get; }
|
bool IsDesignTimeLocked { get; }
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
bool CanInsert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
bool CanInsert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
||||||
void Insert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
void Insert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy);
|
||||||
ObservableCollection<IOutlineNode> Children { get; }
|
ObservableCollection<IOutlineNode> Children { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -222,7 +222,20 @@ namespace ICSharpCode.WpfDesign
|
||||||
object GetDescription(DesignItemProperty designProperty);
|
object GetDescription(DesignItemProperty designProperty);
|
||||||
}
|
}
|
||||||
#endregion
|
#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
|
#region IOutlineNodeNameService
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to get a description for the Outline Node.
|
/// Used to get a description for the Outline Node.
|
||||||
|
|
|
@ -247,7 +247,7 @@ namespace ICSharpCode.XamlDesigner
|
||||||
DesignSurface.LoadDesigner(xmlReader, settings);
|
DesignSurface.LoadDesigner(xmlReader, settings);
|
||||||
}
|
}
|
||||||
if (DesignContext.RootItem != null) {
|
if (DesignContext.RootItem != null) {
|
||||||
OutlineRoot = OutlineNode.Create(DesignContext.RootItem);
|
OutlineRoot = DesignContext.RootItem.CreateOutlineNode();
|
||||||
UndoService.UndoStackChanged += new EventHandler(UndoService_UndoStackChanged);
|
UndoService.UndoStackChanged += new EventHandler(UndoService_UndoStackChanged);
|
||||||
}
|
}
|
||||||
RaisePropertyChanged("SelectionService");
|
RaisePropertyChanged("SelectionService");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче