7
7
using System . ComponentModel ;
8
8
using System . Diagnostics ;
9
9
using System . Diagnostics . CodeAnalysis ;
10
- using System . IO ;
11
10
using System . Linq ;
12
11
using System . Reflection ;
13
12
using System . Xml . Linq ;
14
13
14
+ using Microsoft . Toolkit . Uwp . Design . Types ;
15
+
16
+ #if VS_DESIGNER_PROCESS_ISOLATION
17
+ using Microsoft . Windows . Design ;
15
18
using Microsoft . Windows . Design . Metadata ;
19
+ #endif
16
20
17
21
namespace Microsoft . Toolkit . Uwp . Design . Common
18
22
{
19
- public class MetadataRegistrationBase
23
+ public abstract class MetadataRegistrationBase : IProvideAttributeTable
20
24
{
21
25
private AttributeTable masterMetadataTable ;
22
26
@@ -28,15 +32,25 @@ internal MetadataRegistrationBase() { }
28
32
/// <returns>Custom attribute table.</returns>
29
33
protected virtual AttributeTable BuildAttributeTable ( )
30
34
{
31
- AttributeTableBuilder builder = new AttributeTableBuilder ( ) ;
35
+ var builder = new AttributeTableBuilder ( ) ;
32
36
33
37
AddDescriptions ( builder ) ;
34
38
AddAttributes ( builder ) ;
35
39
AddTables ( builder , this ) ;
40
+
36
41
masterMetadataTable = builder . CreateTable ( ) ;
37
42
return masterMetadataTable ;
38
43
}
39
44
45
+ #region IProvideAttributeTable Members
46
+
47
+ /// <summary>
48
+ /// Gets the AttributeTable for design time metadata.
49
+ /// </summary>
50
+ public AttributeTable AttributeTable => BuildAttributeTable ( ) ;
51
+
52
+ #endregion
53
+
40
54
/// <summary>
41
55
/// Find all AttributeTableBuilder subclasses in the assembly
42
56
/// and add their attributes to the assembly attribute table.
@@ -54,7 +68,7 @@ private void AddTables(AttributeTableBuilder builder, object parent)
54
68
{
55
69
try
56
70
{
57
- AttributeTableBuilder atb = ( AttributeTableBuilder ) Activator . CreateInstance ( t ) ;
71
+ var atb = ( AttributeTableBuilder ) Activator . CreateInstance ( t ) ;
58
72
builder . AddTable ( atb . CreateTable ( ) ) ;
59
73
}
60
74
catch ( Exception )
@@ -76,44 +90,44 @@ private void AddTables(AttributeTableBuilder builder, object parent)
76
90
protected string AssemblyFullName { get ; set ; }
77
91
78
92
/// <summary>
79
- /// Create description attribute from run time assembly xml file.
93
+ /// Create description attribute from run time assembly XML file.
80
94
/// </summary>
81
95
/// <param name="builder">The assembly attribute table builder.</param>
82
96
[ SuppressMessage ( "Microsoft.Design" , "CA1031:DoNotCatchGeneralExceptionTypes" , Justification = "Design time dll should not fail." ) ]
83
97
private void AddDescriptions ( AttributeTableBuilder builder )
84
98
{
85
99
Debug . Assert ( builder != null , "AddDescriptions is called with null parameter!" ) ;
86
100
87
- if ( string . IsNullOrEmpty ( XmlResourceName ) ||
88
- string . IsNullOrEmpty ( AssemblyFullName ) )
89
- {
90
- return ;
91
- }
92
- XDocument xdoc = null ;
101
+ if ( string . IsNullOrEmpty ( XmlResourceName ) || string . IsNullOrEmpty ( AssemblyFullName ) ) return ;
102
+
103
+ XDocument xdoc ;
93
104
try
94
105
{
95
- xdoc = XDocument . Load ( new StreamReader (
96
- Assembly . GetExecutingAssembly ( ) . GetManifestResourceStream ( XmlResourceName ) ) ) ;
106
+ xdoc = XDocument . Load ( Assembly . GetExecutingAssembly ( ) . GetManifestResourceStream ( XmlResourceName ) ) ;
97
107
}
98
- catch { return ; }
99
- if ( xdoc == null )
108
+ catch
100
109
{
101
110
return ;
102
111
}
103
112
113
+ if ( xdoc == null ) return ;
114
+
104
115
foreach ( XElement member in xdoc . Descendants ( "member" ) )
105
116
{
106
117
try
107
118
{
108
119
string name = ( string ) member . Attribute ( "name" ) ;
109
- if ( name == null )
110
- continue ;
120
+
121
+ if ( name == null ) continue ;
122
+
111
123
bool isType = name . StartsWith ( "T:" , StringComparison . OrdinalIgnoreCase ) ;
112
- if ( isType ||
113
- name . StartsWith ( "P:" , StringComparison . OrdinalIgnoreCase ) )
124
+ bool isProperty = name . StartsWith ( "P:" , StringComparison . OrdinalIgnoreCase ) ;
125
+
126
+ if ( isType || isProperty )
114
127
{
115
128
int lastDot = name . Length ;
116
129
string typeName ;
130
+
117
131
if ( isType )
118
132
{
119
133
typeName = name . Substring ( 2 ) ; // skip leading "T:"
@@ -123,86 +137,74 @@ private void AddDescriptions(AttributeTableBuilder builder)
123
137
lastDot = name . LastIndexOf ( '.' ) ;
124
138
typeName = name . Substring ( 2 , lastDot - 2 ) ;
125
139
}
126
- typeName += AssemblyFullName ;
127
140
128
- Type t = Type . GetType ( typeName ) ;
129
- if ( t != null && t . IsPublic && t . IsClass &&
130
- t . IsSubclassOf ( Types . PlatformTypes . DependencyObjectType ) )
141
+ var type = Type . GetType ( typeName + ", " + AssemblyFullName ) ;
142
+
143
+ if ( type != null && type . IsPublic && type . IsClass && type . IsSubclassOf ( PlatformTypes . DependencyObject ) )
131
144
{
132
145
string desc = ParseDescription ( member ) ;
133
- if ( desc == null )
134
- continue ;
135
146
136
- desc = desc . Trim ( ) ;
137
- desc = string . Join ( " " , desc . Split ( new char [ ] { ' ' , '\t ' , '\n ' , '\r ' } , StringSplitOptions . RemoveEmptyEntries ) ) ;
147
+ if ( desc == null ) continue ;
148
+
149
+ desc = string . Join ( " " , desc . Trim ( ) . Split ( new char [ ] { ' ' , '\t ' , '\n ' , '\r ' } , StringSplitOptions . RemoveEmptyEntries ) ) ;
150
+
138
151
if ( isType )
139
152
{
140
- bool isBrowsable = true ;
141
- try
153
+ if ( IsBrowsable ( type ) )
142
154
{
143
- isBrowsable = IsBrowsable ( t ) ;
155
+ builder . AddCustomAttributes ( type , new DescriptionAttribute ( desc ) ) ;
144
156
}
145
- catch { isBrowsable = false ; }
146
- if ( isBrowsable )
147
- builder . AddCallback ( t , b => b . AddCustomAttributes ( new DescriptionAttribute ( desc ) ) ) ;
148
157
else //Hide from intellisense
149
158
{
150
- builder . AddCallback ( t , b => b . AddCustomAttributes (
159
+ builder . AddCustomAttributes ( type ,
151
160
new BrowsableAttribute ( false ) ,
152
- new Microsoft . Windows . Design . ToolboxBrowsableAttribute ( false ) ,
153
- new ToolboxItemAttribute ( false ) ) ) ;
161
+ new ToolboxBrowsableAttribute ( false ) ,
162
+ new ToolboxItemAttribute ( false ) ) ;
154
163
}
155
164
}
156
165
else
157
166
{
158
- string propName = name . Substring ( lastDot + 1 ) ;
159
- PropertyInfo pi = t . GetProperty ( propName , BindingFlags . Public | BindingFlags . Instance | BindingFlags . DeclaredOnly ) ;
167
+ var propertyName = name . Substring ( lastDot + 1 ) ;
168
+ PropertyInfo pi = type . GetProperty ( propertyName , BindingFlags . Public | BindingFlags . Instance | BindingFlags . DeclaredOnly ) ;
160
169
if ( pi != null )
161
170
{
162
- bool isBrowsable = true ;
163
- try
171
+ if ( IsBrowsable ( type ) )
164
172
{
165
- isBrowsable = IsBrowsable ( pi ) ;
173
+ builder . AddCustomAttributes ( type , propertyName , new DescriptionAttribute ( desc ) ) ;
166
174
}
167
- catch { isBrowsable = false ; }
168
- if ( isBrowsable )
169
- builder . AddCallback ( t , b => b . AddCustomAttributes ( propName , new DescriptionAttribute ( desc ) ) ) ;
170
175
else //Hide from intellisense
171
- builder . AddCallback ( t , b => b . AddCustomAttributes ( new BrowsableAttribute ( false ) ) ) ;
176
+ {
177
+ builder . AddCustomAttributes ( type , new BrowsableAttribute ( false ) ) ;
178
+ }
172
179
}
173
180
}
174
181
}
175
182
}
176
183
}
177
- catch ( Exception )
184
+ catch
178
185
{
179
186
}
180
187
}
181
188
}
182
- private static bool IsBrowsable ( Type t )
189
+
190
+ private static bool IsBrowsable ( MemberInfo typeOrMember )
183
191
{
184
- var attrs = t . GetCustomAttributes ( Types . PlatformTypes . EditorBrowsableAttributeType , false ) ;
185
- foreach ( var attr in attrs )
192
+ EditorBrowsableAttribute attribute ;
193
+ try
186
194
{
187
- return Types . PlatformTypes . IsBrowsable ( attr ) ;
195
+ attribute = typeOrMember . GetCustomAttribute < EditorBrowsableAttribute > ( false ) ;
188
196
}
189
- return true ;
190
- }
191
-
192
- private static bool IsBrowsable ( System . Reflection . PropertyInfo pi )
193
- {
194
- var attrs = pi . GetCustomAttributes ( Types . PlatformTypes . EditorBrowsableAttributeType , false ) ;
195
- foreach ( var attr in attrs )
197
+ catch
196
198
{
197
- return Types . PlatformTypes . IsBrowsable ( attr ) ;
199
+ return true ; // If there is no [EditorBrowsable] attribute present, we'll show it by default.
198
200
}
199
- return true ;
201
+ return attribute . State != EditorBrowsableState . Never ;
200
202
}
201
203
202
204
/// <summary>
203
- /// Create description string from xml doc summary tag.
205
+ /// Create description string from XML doc summary tag.
204
206
/// </summary>
205
- /// <param name="member">A single node of the xml doc.</param>
207
+ /// <param name="member">A single node of the XML doc.</param>
206
208
/// <returns>Description string.</returns>
207
209
private static string ParseDescription ( XElement member )
208
210
{
0 commit comments