Browse Source

Allow plugins to extend the context menus of the tree views.

pull/105/head
Daniel Grunwald 14 years ago
parent
commit
a7309a3a37
  1. 122
      ILSpy/ContextMenuEntry.cs
  2. 4
      ILSpy/ExportCommandAttribute.cs
  3. 3
      ILSpy/ILSpy.csproj
  4. 5
      ILSpy/MainWindow.xaml.cs
  5. 57
      ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs
  6. 6
      ILSpy/TreeNodes/Analyzer/AnalyzedFieldNode.cs
  7. 6
      ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs
  8. 36
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  9. 7
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  10. 8
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  11. 6
      ILSpy/TreeNodes/EventTreeNode.cs
  12. 15
      ILSpy/TreeNodes/FieldTreeNode.cs
  13. 33
      ILSpy/TreeNodes/IMemberTreeNode.cs
  14. 16
      ILSpy/TreeNodes/MethodTreeNode.cs
  15. 6
      ILSpy/TreeNodes/PropertyTreeNode.cs
  16. 6
      ILSpy/TreeNodes/TypeTreeNode.cs
  17. 5
      SharpTreeView/SharpTreeNode.cs
  18. 10
      SharpTreeView/SharpTreeViewItem.cs

122
ILSpy/ContextMenuEntry.cs

@ -0,0 +1,122 @@
// Copyright (c) 2011 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;
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows.Controls;
using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy
{
public interface IContextMenuEntry
{
bool IsVisible(SharpTreeNode[] selectedNodes);
bool IsEnabled(SharpTreeNode[] selectedNodes);
void Execute(SharpTreeNode[] selectedNodes);
}
public interface IContextMenuEntryMetadata
{
string Icon { get; }
string Header { get; }
string Category { get; }
double Order { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportContextMenuEntryAttribute : ExportAttribute, IContextMenuEntryMetadata
{
public ExportContextMenuEntryAttribute()
: base(typeof(IContextMenuEntry))
{
}
public string Icon { get; set; }
public string Header { get; set; }
public string Category { get; set; }
public double Order { get; set; }
}
internal class ContextMenuProvider
{
/// <summary>
/// Enables extensible context menu support for the specified tree view.
/// </summary>
public static void Add(SharpTreeView treeView)
{
var provider = new ContextMenuProvider(treeView);
treeView.ContextMenuOpening += provider.treeView_ContextMenuOpening;
treeView.ContextMenuClosing -= provider.treeView_ContextMenuClosing;
}
readonly SharpTreeView treeView;
[ImportMany(typeof(IContextMenuEntry))]
Lazy<IContextMenuEntry, IContextMenuEntryMetadata>[] entries;
private ContextMenuProvider(SharpTreeView treeView)
{
this.treeView = treeView;
App.CompositionContainer.ComposeParts(this);
}
void treeView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
SharpTreeNode[] selectedNodes = treeView.GetTopLevelSelection().ToArray();
if (selectedNodes.Length == 0)
return;
ContextMenu menu = new ContextMenu();
foreach (var category in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.Category)) {
if (menu.Items.Count > 0) {
menu.Items.Add(new Separator());
}
foreach (var entryPair in category) {
IContextMenuEntry entry = entryPair.Value;
if (entry.IsVisible(selectedNodes)) {
MenuItem menuItem = new MenuItem();
menuItem.Header = entryPair.Metadata.Header;
if (!string.IsNullOrEmpty(entryPair.Metadata.Icon)) {
menuItem.Icon = new Image {
Width = 16,
Height = 16,
Source = Images.LoadImage(entry, entryPair.Metadata.Icon)
};
}
if (entryPair.Value.IsEnabled(selectedNodes)) {
menuItem.Click += delegate {
entry.Execute(selectedNodes);
};
}
menu.Items.Add(menuItem);
}
}
}
if (menu.Items.Count > 0)
treeView.ContextMenu = menu;
}
void treeView_ContextMenuClosing(object sender, ContextMenuEventArgs e)
{
treeView.ContextMenu = null;
}
}
}

4
ILSpy/ExportCommandAttribute.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.ILSpy
[MetadataAttribute] [MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportToolbarCommandAttribute : ExportAttribute public class ExportToolbarCommandAttribute : ExportAttribute, IToolbarCommandMetadata
{ {
public ExportToolbarCommandAttribute() public ExportToolbarCommandAttribute()
: base("ToolbarCommand", typeof(ICommand)) : base("ToolbarCommand", typeof(ICommand))
@ -46,7 +46,7 @@ namespace ICSharpCode.ILSpy
[MetadataAttribute] [MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class ExportMainMenuCommandAttribute : ExportAttribute public class ExportMainMenuCommandAttribute : ExportAttribute, IMainMenuCommandMetadata
{ {
public ExportMainMenuCommandAttribute() public ExportMainMenuCommandAttribute()
: base("MainMenuCommand", typeof(ICommand)) : base("MainMenuCommand", typeof(ICommand))

3
ILSpy/ILSpy.csproj

@ -103,6 +103,7 @@
<Compile Include="Fusion.cs" /> <Compile Include="Fusion.cs" />
<Compile Include="GacInterop.cs" /> <Compile Include="GacInterop.cs" />
<Compile Include="GuessFileType.cs" /> <Compile Include="GuessFileType.cs" />
<Compile Include="ContextMenuEntry.cs" />
<Compile Include="ILAstLanguage.cs" /> <Compile Include="ILAstLanguage.cs" />
<Compile Include="ILLanguage.cs" /> <Compile Include="ILLanguage.cs" />
<Compile Include="ILSpySettings.cs" /> <Compile Include="ILSpySettings.cs" />
@ -120,6 +121,8 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzeContextMenuEntry.cs" />
<Compile Include="TreeNodes\IMemberTreeNode.cs" />
<Compile Include="XamlResourceNode.cs" /> <Compile Include="XamlResourceNode.cs" />
<EmbeddedResource Include="..\README.txt"> <EmbeddedResource Include="..\README.txt">
<Link>README.txt</Link> <Link>README.txt</Link>

5
ILSpy/MainWindow.xaml.cs

@ -18,7 +18,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
@ -30,8 +29,6 @@ using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.FlowAnalysis;
using ICSharpCode.ILSpy.TextView; using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes; using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.TreeNodes.Analyzer; using ICSharpCode.ILSpy.TreeNodes.Analyzer;
@ -96,6 +93,8 @@ namespace ICSharpCode.ILSpy
InitMainMenu(); InitMainMenu();
InitToolbar(); InitToolbar();
ContextMenuProvider.Add(treeView);
ContextMenuProvider.Add(analyzerTree);
this.Loaded += new RoutedEventHandler(MainWindow_Loaded); this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
} }

57
ILSpy/TreeNodes/Analyzer/AnalyzeContextMenuEntry.cs

@ -0,0 +1,57 @@
// Copyright (c) 2011 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;
using System.Linq;
using ICSharpCode.TreeView;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{
[ExportContextMenuEntry(Header = "Analyze", Icon = "images/Search.png")]
sealed class AnalyzeContextMenuEntry : IContextMenuEntry
{
public bool IsVisible(SharpTreeNode[] selectedNodes)
{
return selectedNodes.All(n => n is IMemberTreeNode);
}
public bool IsEnabled(SharpTreeNode[] selectedNodes)
{
foreach (IMemberTreeNode node in selectedNodes) {
if (!(node.Member is FieldDefinition || node.Member is MethodDefinition))
return false;
}
return true;
}
public void Execute(SharpTreeNode[] selectedNodes)
{
// TODO: figure out when equivalent nodes are already present
// and focus those instead.
foreach (IMemberTreeNode node in selectedNodes) {
FieldDefinition field = node.Member as FieldDefinition;
if (field != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedFieldNode(field));
MethodDefinition method = node.Member as MethodDefinition;
if (method != null)
MainWindow.Instance.AddToAnalyzer(new AnalyzedMethodTreeNode(method));
}
}
}
}

6
ILSpy/TreeNodes/Analyzer/AnalyzedFieldNode.cs

@ -6,7 +6,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{ {
class AnalyzedFieldNode : AnalyzerTreeNode class AnalyzedFieldNode : AnalyzerTreeNode, IMemberTreeNode
{ {
FieldDefinition analyzedField; FieldDefinition analyzedField;
@ -41,5 +41,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (!analyzedField.IsLiteral) if (!analyzedField.IsLiteral)
this.Children.Add(new AnalyzedFieldAccessNode(analyzedField, true)); this.Children.Add(new AnalyzedFieldAccessNode(analyzedField, true));
} }
MemberReference IMemberTreeNode.Member {
get { return analyzedField; }
}
} }
} }

6
ILSpy/TreeNodes/Analyzer/AnalyzedMethodTreeNode.cs

@ -21,7 +21,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes.Analyzer namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
{ {
class AnalyzedMethodTreeNode : AnalyzerTreeNode class AnalyzedMethodTreeNode : AnalyzerTreeNode, IMemberTreeNode
{ {
MethodDefinition analyzedMethod; MethodDefinition analyzedMethod;
@ -55,5 +55,9 @@ namespace ICSharpCode.ILSpy.TreeNodes.Analyzer
if (analyzedMethod.IsVirtual && !analyzedMethod.IsFinal && !analyzedMethod.DeclaringType.IsInterface) // interfaces are temporarly disabled if (analyzedMethod.IsVirtual && !analyzedMethod.IsFinal && !analyzedMethod.DeclaringType.IsInterface) // interfaces are temporarly disabled
this.Children.Add(new AnalyzerMethodOverridesTreeNode(analyzedMethod)); this.Children.Add(new AnalyzerMethodOverridesTreeNode(analyzedMethod));
} }
MemberReference IMemberTreeNode.Member {
get { return analyzedMethod; }
}
} }
} }

36
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -94,21 +94,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
} }
public override ContextMenu GetContextMenu()
{
// specific to AssemblyTreeNode
var menu = new ContextMenu();
MenuItem item = new MenuItem() {
Header = "Remove assembly",
Icon = new Image() { Source = Images.Delete }
};
item.Click += delegate { Delete(); };
menu.Items.Add(item);
return menu;
}
Dictionary<TypeDefinition, TypeTreeNode> typeDict = new Dictionary<TypeDefinition, TypeTreeNode>(); Dictionary<TypeDefinition, TypeTreeNode> typeDict = new Dictionary<TypeDefinition, TypeTreeNode>();
protected override void LoadChildren() protected override void LoadChildren()
@ -235,4 +220,25 @@ namespace ICSharpCode.ILSpy.TreeNodes
return true; return true;
} }
} }
[ExportContextMenuEntry(Header = "_Remove", Icon = "images/Delete.png")]
sealed class RemoveAssembly : IContextMenuEntry
{
public bool IsVisible(SharpTreeNode[] selectedNodes)
{
return selectedNodes.All(n => n is AssemblyTreeNode);
}
public bool IsEnabled(SharpTreeNode[] selectedNodes)
{
return true;
}
public void Execute(SharpTreeNode[] selectedNodes)
{
foreach (var node in selectedNodes) {
node.Delete();
}
}
}
} }

7
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -17,7 +17,6 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Windows.Threading; using System.Windows.Threading;
@ -71,7 +70,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
} }
sealed class BaseTypesEntryNode : ILSpyTreeNode sealed class BaseTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{ {
TypeReference tr; TypeReference tr;
TypeDefinition def; TypeDefinition def;
@ -139,5 +138,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
language.WriteCommentLine(output, language.TypeToString(tr, true)); language.WriteCommentLine(output, language.TypeToString(tr, true));
} }
MemberReference IMemberTreeNode.Member {
get { return tr; }
}
} }
} }

8
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -3,9 +3,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.Utils; using ICSharpCode.NRefactory.Utils;
using Mono.Cecil; using Mono.Cecil;
@ -88,7 +88,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
} }
class DerivedTypesEntryNode : ILSpyTreeNode class DerivedTypesEntryNode : ILSpyTreeNode, IMemberTreeNode
{ {
TypeDefinition def; TypeDefinition def;
AssemblyDefinition[] assemblies; AssemblyDefinition[] assemblies;
@ -138,5 +138,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
language.WriteCommentLine(output, language.TypeToString(def, true)); language.WriteCommentLine(output, language.TypeToString(def, true));
} }
MemberReference IMemberTreeNode.Member {
get { return def; }
}
} }
} }

6
ILSpy/TreeNodes/EventTreeNode.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary> /// <summary>
/// Represents an event in the TreeView. /// Represents an event in the TreeView.
/// </summary> /// </summary>
public sealed class EventTreeNode : ILSpyTreeNode public sealed class EventTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
readonly EventDefinition ev; readonly EventDefinition ev;
@ -73,5 +73,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
language.DecompileEvent(ev, output, options); language.DecompileEvent(ev, output, options);
} }
MemberReference IMemberTreeNode.Member {
get { return ev; }
}
} }
} }

15
ILSpy/TreeNodes/FieldTreeNode.cs

@ -17,9 +17,7 @@
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System; using System;
using System.Windows.Controls;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.TreeNodes.Analyzer;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes namespace ICSharpCode.ILSpy.TreeNodes
@ -27,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary> /// <summary>
/// Represents a field in the TreeView. /// Represents a field in the TreeView.
/// </summary> /// </summary>
public sealed class FieldTreeNode : ILSpyTreeNode public sealed class FieldTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
readonly FieldDefinition field; readonly FieldDefinition field;
@ -71,15 +69,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
language.DecompileField(field, output, options); language.DecompileField(field, output, options);
} }
public override System.Windows.Controls.ContextMenu GetContextMenu() MemberReference IMemberTreeNode.Member {
{ get { return field; }
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem() { Header = "Analyze", Icon = new Image() { Source = Images.Search } };
item.Click += delegate { MainWindow.Instance.AddToAnalyzer(new AnalyzedFieldNode(field)); };
menu.Items.Add(item);
return menu;
} }
} }
} }

33
ILSpy/TreeNodes/IMemberTreeNode.cs

@ -0,0 +1,33 @@
// Copyright (c) 2011 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;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes
{
/// <summary>
/// Interface implemented by all tree nodes
/// (both in main tree view and in analyzer)
/// that represent Cecil members.
/// </summary>
public interface IMemberTreeNode
{
MemberReference Member { get; }
}
}

16
ILSpy/TreeNodes/MethodTreeNode.cs

@ -18,10 +18,9 @@
using System; using System;
using System.Text; using System.Text;
using System.Windows.Controls;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.TreeNodes.Analyzer;
using Mono.Cecil; using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes namespace ICSharpCode.ILSpy.TreeNodes
@ -29,7 +28,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary> /// <summary>
/// Tree Node representing a field, method, property, or event. /// Tree Node representing a field, method, property, or event.
/// </summary> /// </summary>
public sealed class MethodTreeNode : ILSpyTreeNode public sealed class MethodTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
MethodDefinition method; MethodDefinition method;
@ -96,15 +95,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
return FilterResult.Hidden; return FilterResult.Hidden;
} }
public override System.Windows.Controls.ContextMenu GetContextMenu() MemberReference IMemberTreeNode.Member {
{ get { return method; }
ContextMenu menu = new ContextMenu();
MenuItem item = new MenuItem() { Header = "Analyze", Icon = new Image() { Source = Images.Search } };
item.Click += delegate { MainWindow.Instance.AddToAnalyzer(new AnalyzedMethodTreeNode(method)); };
menu.Items.Add(item);
return menu;
} }
} }
} }

6
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// <summary> /// <summary>
/// Represents a property in the TreeView. /// Represents a property in the TreeView.
/// </summary> /// </summary>
public sealed class PropertyTreeNode : ILSpyTreeNode public sealed class PropertyTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
readonly PropertyDefinition property; readonly PropertyDefinition property;
readonly bool isIndexer; readonly bool isIndexer;
@ -73,5 +73,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
{ {
language.DecompileProperty(property, output, options); language.DecompileProperty(property, output, options);
} }
MemberReference IMemberTreeNode.Member {
get { return property; }
}
} }
} }

6
ILSpy/TreeNodes/TypeTreeNode.cs

@ -26,7 +26,7 @@ using Mono.Cecil;
namespace ICSharpCode.ILSpy.TreeNodes namespace ICSharpCode.ILSpy.TreeNodes
{ {
public sealed class TypeTreeNode : ILSpyTreeNode public sealed class TypeTreeNode : ILSpyTreeNode, IMemberTreeNode
{ {
readonly TypeDefinition type; readonly TypeDefinition type;
readonly AssemblyTreeNode parentAssemblyNode; readonly AssemblyTreeNode parentAssemblyNode;
@ -207,5 +207,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
} }
} }
#endregion #endregion
MemberReference IMemberTreeNode.Member {
get { return type; }
}
} }
} }

5
SharpTreeView/SharpTreeNode.cs

@ -157,11 +157,6 @@ namespace ICSharpCode.TreeView
} }
} }
public virtual ContextMenu GetContextMenu()
{
return null;
}
#endregion #endregion
#region OnChildrenChanged #region OnChildrenChanged

10
SharpTreeView/SharpTreeViewItem.cs

@ -44,16 +44,6 @@ namespace ICSharpCode.TreeView
} }
} }
protected override void OnContextMenuOpening(ContextMenuEventArgs e)
{
ContextMenu = Node.GetContextMenu();
}
protected override void OnContextMenuClosing(ContextMenuEventArgs e)
{
ClearValue(ContextMenuProperty);
}
#region Mouse #region Mouse
Point startPoint; Point startPoint;

Loading…
Cancel
Save