Home > Software engineering >  What do curly braces in XAML actually mean?
What do curly braces in XAML actually mean?

Time:11-12

I'm a long-time C# programmer but I'm completely new to WPF and XAML. I can find plenty of tutorials that say "this is how to achieve this specific thing" but not "this is why you do this to achieve this specific thing". I'm seriously struggling to understand the meaning of various syntax in XAML.

In this case, what do curly braces in attributes actually mean? What do they get translated to in terms of code? How do I reason about them? How do they get interpreted? Why does there seem to be multiple syntaxes (Binding="{Binding someProperty}" vs Binding="{Binding path=someProperty}")?

I must be missing something obvious, but I've spent literally days reading tutorials, watching tutorials, even fighting my way through the immensely dry and difficult-to-understand Microsoft documentation and I still can't seem to figure it out.


Let me try to illustrate where I'm getting stuck.

For example, say I was given this:

int result = SomeUnknownFunction(42, 79);

I don't have to know what SomeUnknownFunction does to reason about what's happening here. I can say, ok, the first part defines a new variable of type int, the second part runs some function with two inputs, and the equals sign assigns the result of that function to the variable.

Now say I was given this:

<TextBox Text="{Binding Name}">

I can say, ok, when the XAML parser gets to this bit, the C# code it spits out creates an object instance of type TextBox. That class has (or inherits) a property called Text, and we're setting it to... uh... some magic syntax inside curly braces...

This is where I'm stuck. I think some part of this is called a "markup extension" (which is the most incredibly generic and meaningless name possible), but I can't even figure out if that means "the curly braces and everything inside" or just "the Binding part". Sometimes there's an equals sign inside the curly braces, sometimes not. What's the difference? The word Binding is a... something? Is it a function and we're passing in Name, and it returns a new Binding object that is somehow assigned to the Binding property?

CodePudding user response:

This is part of the syntax of a XAML file, you can read all the gory details here

Markup Extensions

XAML defines a markup extension programming entity that enables an escape from the normal XAML processor handling of string attribute values or object elements, and defers the processing to a backing class. The character that identifies a markup extension to a XAML processor when using attribute syntax is the opening curly brace ({), followed by any character other than a closing curly brace (}). The first string following the opening curly brace must reference the class that provides the particular extension behavior, where the reference may omit the substring "Extension" if that substring is part of the true class name. Thereafter, a single space may appear, and then each succeeding character is used as input by the extension implementation, up until the closing curly brace is encountered.

More information here

Overview of markup extensions for XAML

Also another good link tendered by @Charlieface

Basic Markup Extension Syntax

A markup extension can be implemented to provide values for properties in an attribute usage, properties in a property element usage, or both.

When used to provide an attribute value, the syntax that distinguishes a markup extension sequence to a XAML processor is the presence of the opening and closing curly braces ({ and }). The type of markup extension is then identified by the string token immediately following the opening curly brace.

When used in property element syntax, a markup extension is visually the same as any other element used to provide a property element value: a XAML element declaration that references the markup extension class as an element, enclosed within angle brackets (<>).

CodePudding user response:

I guess this explains the syntactic meaning of the braces:

"Markup extensions are a XAML technique for obtaining a value that's not a primitive or a specific XAML type. For attribute usage, markup extensions use the known character sequence of an opening curly brace { to enter the markup extension scope, and a closing curly brace } to exit." (Overview of markup extensions for XAML)


"I think some part of this is called a "markup extension" (which is the most incredibly generic and meaningless name possible), but I can't even figure out if that means "the curly braces and everything inside" or just "the Binding part" "

An attempt to explain it while keeping it simple:

XAML is a markup language that is underlying certain semantic rules. Becaise of the very advanced processor, XAML has a dynamic set of tags/objects. Using declared namespaces, the XAML processor is able to map XAML elements to actual C# objects. XAML allows to implement some simple logic using special objects like Trigger. But the language, or a markup language in general, is very limited when it comes to complex logic and dynamic values.

Markup languages are static as they require static values. For example in C# you can implement an algorithm based on variables (acting like placeholders for data) that are dynamically calculated during runtime. In markup, all values are provided statically, the moment you compose the markup.
The idea is to use markup extensions to enable dynamic value calculation.

For example, there is no way you could implement a complex and dynamic logic like the binding engine by using markup alone. Data binding is a concept that allows to "inject" dynamic data values into the markup (to put it simple).

The XAML way to extend the markup functionality is to introduce the concept of markup extensions. From this point of view the name "Markup Extension" is very good. Other languages try something similar by adding more functionality to the processor (extend the language syntax and semantics) or by dynamically modifying/overwriting the actual markup. In comparison markup extensions are more powerful as they truely extend the markup beyond the limitations of the processor. The rules are now dictated by the .NET compiler and not the markup processor.

To implement a markup extension, the object must extend the abstract class MarkupExtension. The implementation usually has a constructor and can provide additional public properties. MarkupExtension exposes a single abstract method MarkupExtension.ProvideValue which is called by the XAML processor in order to obtain the dynamically calculated value, provided by the implementor.
One famous extension is the Binding class. Binding extends MarkupExtension and exposes additional properties like Source, Converter, Path etc.

The syntax for the XAML processor is

{<markup_extension_class_name> constructor_value, <markup_extension_property>=property_value}

Like <TextBlock Text="{Binding Username, ElementName=MyControl}":

  • The processor is processing the markup <TextBlock.

  • The curly braces tell the processor that the content is an object that extends MarkupExtension.

  • The XAML engine will create an instance of the Binding class using the constructor parameter Username and initializes the property ElementName with the value "MyControl".

  • The XAML engine will then use the constructed instance to call the MarkupExtension.ProvideValue method and use the result value to resolve the markup that the extension is extending. In this case the XAML engine will create a TextBlock instance and assign the dynamically calculated result of the Binding markup extension to the TextBlock.Text property

A special rule of the XAML processor is that in case the extension's class name is suffixed with "Extension", the processor would also be able to identify the class if the actual markup omits the "Extension" suffix". For example, if the class is named BindingExpression you can simplify the name and write Binding in the markup.

By implementing the Binding markup extension, the rather simple markup code extents into the highly sophisticated WPF framework to "connect" the binding engine to the XAML language.

Sadly I can't recommend a good source other than the official Microsoft documentation. In addition to the link you have provided in your question or those suggested by other answers, you can read the useful remarks on the MarkupExtension.ProvideValue property and the MarkupExtension class.
I also suggest to implement your own very simple markup extension or to take a look at existing implementations you can find on the net to get the idea. Markup extensions are quite simple to use.

  • Related