diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/NodeFormatter.cs b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/NodeFormatter.cs
index 24adbd4d23..d384e9861a 100644
--- a/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/NodeFormatter.cs
+++ b/dnSpy/dnSpy.Contracts.DnSpy/Documents/TreeView/NodeFormatter.cs
@@ -33,6 +33,9 @@ namespace dnSpy.Contracts.Documents.TreeView {
public readonly struct NodeFormatter {
static bool IsExe(ModuleDef? mod) => mod is not null && (mod.Characteristics & Characteristics.Dll) == 0;
static bool IsExe(IPEImage? peImage) => peImage is not null && (peImage.ImageNTHeaders.FileHeader.Characteristics & Characteristics.Dll) == 0;
+ static string? GetDisplayName(IDecompiler decompiler, IMemberRef member) => (decompiler as IDecompilerMemberNameProvider)?.GetDisplayName(member);
+ static void WriteDisplayName(ITextColorWriter output, IDecompiler decompiler, IMemberRef member, object color, string metadataName) =>
+ output.Write(color, NameUtilities.CleanIdentifier(GetDisplayName(decompiler, member) ?? metadataName));
static string GetFilename(IDsDocument document) {
string? filename = null;
@@ -197,7 +200,7 @@ public void Write(ITextColorWriter output, IDecompiler decompiler, ITypeDefOrRef
/// Event
/// true to write tokens
public void Write(ITextColorWriter output, IDecompiler decompiler, EventDef @event, bool showToken) {
- output.Write(decompiler.MetadataTextColorProvider.GetColor(@event), NameUtilities.CleanIdentifier(@event.Name));
+ WriteDisplayName(output, decompiler, @event, decompiler.MetadataTextColorProvider.GetColor(@event), @event.Name);
output.WriteSpace();
output.Write(BoxedTextColor.Punctuation, ":");
output.WriteSpace();
@@ -239,7 +242,7 @@ public void Write(ITextColorWriter output, IDecompiler decompiler, PropertyDef p
/// Field
/// true to write tokens
public void WriteField(ITextColorWriter output, IDecompiler decompiler, IField field, bool showToken) {
- output.Write(decompiler.MetadataTextColorProvider.GetColor(field), NameUtilities.CleanIdentifier(field.Name));
+ WriteDisplayName(output, decompiler, field, decompiler.MetadataTextColorProvider.GetColor(field), field.Name);
output.WriteSpace();
output.Write(BoxedTextColor.Punctuation, ":");
output.WriteSpace();
@@ -270,7 +273,7 @@ void Write(ITextColorWriter output, IDecompiler decompiler, MethodDef? md, IMeth
if (name == ".ctor")
output.Write(decompiler.MetadataTextColorProvider.GetColor(method.DeclaringType), NameUtilities.CleanIdentifier(method.DeclaringType.Name));
else
- output.Write(decompiler.MetadataTextColorProvider.GetColor(method), NameUtilities.CleanIdentifier(name));
+ WriteDisplayName(output, decompiler, method, decompiler.MetadataTextColorProvider.GetColor(method), name);
if (showGenericParams) {
if (m is MethodSpec ms && ms.GenericInstMethodSig is GenericInstMethodSig gis) {
diff --git a/dnSpy/dnSpy.Contracts.Logic/Decompiler/IDecompilerMemberNameProvider.cs b/dnSpy/dnSpy.Contracts.Logic/Decompiler/IDecompilerMemberNameProvider.cs
new file mode 100644
index 0000000000..a4f0bdc567
--- /dev/null
+++ b/dnSpy/dnSpy.Contracts.Logic/Decompiler/IDecompilerMemberNameProvider.cs
@@ -0,0 +1,34 @@
+/*
+ Copyright (C) 2026 geocine
+
+ This file is part of dnSpy
+
+ dnSpy is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ dnSpy is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with dnSpy. If not, see .
+*/
+
+using dnlib.DotNet;
+
+namespace dnSpy.Contracts.Decompiler {
+ ///
+ /// Optional member display name provider used by UI formatters outside normal decompiler output.
+ ///
+ public interface IDecompilerMemberNameProvider {
+ ///
+ /// Returns a custom display name for , or null to use its metadata name.
+ ///
+ /// Member reference
+ ///
+ string? GetDisplayName(IMemberRef member);
+ }
+}