A profile is a set of rules and settings that apply to XAML Generation.
Mappings are the encapsulation of the logic for turning the properties in C# or VB code into XAML. Each profile will contain multiple mappings. Each mapping is the specific rule for the generation of XAML for a specific property. A profile includes a configurable list of mappings for different combinations of type, name, and accessibility.
A mapping can match multiple property types. To specify multiple types, separate them with the pipe (|) character. To match any type specify T
.
A mapping can be made to only apply to properties that are read-only. This is useful if you want different output for properties that can be edited.
A mapping can be made to apply to properties based on the property name. If name filters are provided, mapping will only be used if the name of the property contains the value specified. To specify multiple types, separate them with the pipe (|) character. Note that this check is case insensitive.
Mappings are matched in the following order:
- Property Type.
- If the property is Read-Only.
- Property Name.
If a property matches multiple mappings, there is no guarantee on which will be used.
It is possible to create a mapping to generate XAML based on a method.
To do this specify the type as method()
, method(T)
, or method(T,T)
. These will match methods that take zero, one, or two parameters of any type. The T
value can also be replaced with a specific type name to further limit the methods it applies to.
Filtering by name or applied attribute works in the same way as for properties.
The following special considerations apply to mappings for methods.
- A mapping type for a method cannot contain multiple method specifications, nor be combined with property types.
- Only public methods that return
void
can be mapped. - Only methods that take fewer than three parameters can be used for XAML generation.
- The 'Read-Only' setting is ignored for method mappings.
- The fallback mapping is not applied to methods. XAML will only be generated for methods if a specific mapping is matched.
- The name of the first argument passed to a method can be output with the placeholder
$arg1$
. Forvoid LogOut(User user) {}
this would beuser
. - The name of the second argument passed to a method can be output with the placeholder
$arg2$
. Forvoid DoSomething(User user, int operationId) {}
this would beoperationId
.
It's possible to use attributes applied to properties to determine what to output. (Attributes can also be used in the output--see below.)
To specify that a property should produce different output when a specific attribute is applied, include [attribute-name]
before the property type. For example, to create a mapping for a property that is a string
and has the HiddenAttribute
applied, specify the type as [Hidden]string
.
To create a mapping for a property of any type that has a specific attribute applied, specify the type as [attribute-name]T
.
In addition to the mappings for properties, there are also three special mappings that must be configured.
- Fallback
- Sub-Property
- Enum Members
The mapping used when a property does not match any other mapping.
The mapping used for properties included from the
The mapping used for properties included from the
Profile settings and mappings can include placeholders. A placeholder is something that will be replaced in the generated code. The following placeholders are defined.
-
$name$ Property name. -
$safename$ Property name formatted for use as anx:Name
within XAML. -
$namewithspaces$ Property name with spaces inserted between words if the name is camelCase or PascalCase. -
$type$ Property type. If a generic type this will be the inner type. -
$incint$ Incrementing integer. A number (starting at zero) that will increase with each property that is matched in a class. -
$repint$ Repeating integer. The same number that was last used, repeated without increment. Useful when you want output with multiple items in the same row. -
$subprops$ Sub-properties. Is replaced with output from the sub-property mapping for each property of the matched type. Useful when outputting collections of items. -
$members$ Enum members. Is replaced with output from the enum member mapping for each property of the matched type. -
$element$ Enum element. Is replaced with the name of an individual enum element. -
$elementwithspaces$ Enum element. Is replaced with the name of an individual enum element and spaces are inserted between words if the name is camelCase or PascalCase. -
$enumname$ Enum property name. Is replaced with the name of the enum property. -
$nooutput$ No Output. Nothing will be included in the generated XAML when this is in the mapping output. -
$xname$ A generated value based on the property name and the XAML element this is used within. -
$repxname$ Repeat the last generated$xname$ value. If no$xname$ value has been generated, the attribute this is used within will be omitted from the output. -
$method$ The name of the method. -
$arg1$ The name of the first argument passed to a method (if any). -
$arg2$ The name of the second argument passed to a method (if any).
It is also possible to generate XAML based on the attributes attached to a property. This can be useful if the property name isn't what you want displayed but you have an attribute attached that does hold a preferred value. You may also use attributes to store additional information related to a property that can be useful to have in the XAML as well. (e.g. max field length.)
Attribute based placeholders take the form $att:<attribute-name>:<output-if-attribute-on-property>[::<fallback-value>]$
This is the name of the attribute to look for. In the following code snippet this woudl be Display
. (Use of DisplayAttribute
also works.)
[Display(Name = ShortName)]
public string UserName { get; set; }
These can be regular strings to treat as XAML. It can also include values in square brackets which have special meaning with regard the properties of the attribute.
- [PropertName] can be used to access the values of named items passed to the attribute constructor. e.g.
Name
in the above example. - [1] can be used to access values passed to the attribute constructor in numeric order. Order starts with '1'. (
[1]
and[Name]
produce the same output in the above example.)
This is the value to output if the attribute has not been applied to the property. This is optional. If no fallback is provided and the attribute is not applied to the property nothing is added to the output. This may contain above listed placeholders but with at-signs ('@') instead of dollar-signs ('$') at the start and end of the placeholder.
Consider the following: $att:Display:[Name]::@namewithspaces@$
-
$att:
indicates the start of an embedded attribute. -
Display
name of the attribute. -
:
indicates the end of the name. -
[Name]
the content to display in the output -
::
(optional) indicator of fallback if attribute isn't applied to the property -
@namewithspaces@
the content to output instead. '@' signs are replaced with '$' and then any embedded placeholders are also evaluated. -
$
end of the embedded attribute placeholder.
If a mapping output is defined as:
<TextBlock Text="$att:Display:[Name]::@namewithspaces@$" />
these properties:
[Display(Name = "ShortName")]
public string UserName { get; set; }
public string FullName { get; set; }
will produce:
<TextBlock Text="ShortName" />
<TextBlock Text="Full Name" />