Simple WPF Databinding syntax for 'Path' property - wpf

Can anyone explain why, when setting a binding, sometimes you do it with quotes around the binding path -
<myObject.myProperty>
<Binding Path="myData" />
<myObject.myProperty/>
and sometimes without -
<myObject myProperty="{Binding Path=myData}" />
?
Microsoft (http://msdn.microsoft.com/en-us/library/ms752059.aspx#xaml_syntax_in_brief) state -
"An attribute syntax names the property that is
being set in attribute syntax, followed by the
assignment operator (=). The value of an attribute
is always specified as a string that is contained
within quotation marks."
But here we always specify the Path attribute of the Binding element without quotes. Am I not understanding something about the {} syntax?

This isn't a feature of data binding per se. The same applies to any markup extension. For example, the quotes/no quotes variation you describe can also be found with the StaticResource markup extension as this example shows:
<StackPanel>
<StackPanel.Resources>
<SolidColorBrush x:Key="b" Color="Red" />
</StackPanel.Resources>
<TextBlock
Foreground="{StaticResource b}"
Text="Foo"/>
<TextBlock
Text="Foo">
<TextBlock.Foreground>
<StaticResource ResourceKey="b" />
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
It boils down to this: if you're using an XML element to instantiate a markup extension (such as Binding or StaticResource) and if you set the properties as attributes, the syntax rules of XML require quotes. This is outside of XAML's control - XML syntax requires quotes around all attribute values.
But if you use the markup syntax extension (i.e. {...}), quotes are optional for properties you set inside those braces. That's because the markup extension syntax is not a feature of XML. It's a feature of XAML, and Microsoft therefore has control over the syntax. One goal of markup extensions is to reduce verbosity, and since it was possible for Microsoft to make quotes optional, they did so. (In fact, requiring quotes would have been messy, because you then tend to get into escaping issues - when a markup extension is the value of an attribute it's already encased in quotes, so requiring nested quotes could get messy.)
There's a third syntax, by the way:
<myObject.myProperty>
<Binding>
<Binding.Path>myData</Binding.Path>
</Binding>
<myObject.myProperty/>
A Binding is just an object like anything else in XAML, so you can set its properties using either attributes or property elements. By setting Path as a property element, I get to supply its value as the content of that property element. XML syntax rules don't require quotes around the content of an element, so once again I get to omit the quotes.
So it all really comes down to XML's rules for where data needs quotes. It doesn't have much to do with XAML, and isn't at all specific to data binding.

Related

Write markup extension as nested element

Is it possible to write markup extension as nested element rather than attribute? I am trying to use Boolean as key for ResourceDictionary entries.
Current code where ResourceDictionary key type is string:
<UserControl.Resources>
<my:ObjectToResourceConverter x:Key="StatusConverter">
<ResourceDictionary>
<BitmapImage x:Key="True" UriSource="/TestProject;/Resources/Open.png"/>
<BitmapImage x:Key="False" UriSource="/TestProject;/Resources/Closed.png" />
</ResourceDictionary>
</my:ObjectToResourceConverter>
</UserControl.Resources>
Desired code but doesn't compile due to:
Unrecognized tag x:Key
XAML
...
<BitmapImage UriSource="/TestProject;/Resources/Open.png">
<x:Key>
<x:Boolean>True</x:Boolean>
</x:Key>
</BitmapImage>
...
Well, yes, you usually can declare markup extensions with element syntax, but x:Key is actually a directive, not a markup extension. As described here, x:Key does not support element syntax in XAML 2006. If you use XAML 2009 it does, but it's unlikely that you are (or would want to).
But even if you could that, it wouldn't help, because (in XAML 2006; XAML 2009 might be different, didn't check) the key of a resource dictionary can only be set using string, x:Type, or x:Static. So for your case, you would need to define a static property that produces false, and set that as the key using x:Static.
Edit The part about only supporting string, x:Type, and x:Static is not completely true. I was too trusting of the compiler error message (which says 'Only String, TypeExtension, and StaticExtension are supported.'). There is at least one other supported key type: ComponentResourceKey. There may be more I'm forgetting or of which I am unaware. But in any case, arbitrary markup extensions (like a custom-defined one that returns a boolean) are not supported.

Why Binding Syntax Differs when we are writing in nested XAML

Why Binding Syntax Differs when we are writing in nested XAML . For Example :
<extensibility:CommandBehavior
Command="{Binding SelectionChanged}"
CommandParameter="{Binding ElementName=modeItemsListBox,Path=SelectedItems}" >
In above example I have CommandParameter have ElementName and Path without any quotes.
But the same can be written as:
<extensibility:CommandBehavior
Command="{Binding SelectionChanged}">
<extensibility:CommandBehavior.CommandParameter>
<Binding ElementName="modeItemsListBox"="SelectedItems" />
</extensibility:CommandBehavior.CommandParameter>
</extensibility:CommandBehavior>
Where ElementName and Pathboth are inside quotes. Is that just an inconsistency or I am missing some hierarchy?
The two snippets of code you're showing both instantiate the Binding class as a MarkupExtension and allow it to provide the value for the CommandParameter property of your CommandBehaviour.
The second variant (the one you call "nested XAML") could be called the canonical way of instantiating the Binding class and providing values for properties: The class name is the element name, each property is an attribute and it follows all the conventions of XML: all attribute values must be quoted.
This canonical syntax is, of course, kind of heavy if you need to set lots of properties using markup extensions, so an alternative short-hand syntax was introduced: If you need to set the value of a property named CommandParameter using the markup extension Binding, you can do that using the simple CommandParameter="{Binding ...}" XML syntax. The curly braces in the value are very important, they tell the XAML parser to treat that attribute value differently. You'll need to set property values for the newly instantiated Binding class, and you can't use the usual XAML syntax of name="value" because you're writing this inside an attribute value, so the quotations are skipped.
Hope this explains it all.

What are XAML markup extensions?

I tried reading the MSDN article on markup extensions, but I can’t find out what they are (the article discusses what they do).
I cannot find a clear explanation of why we need markup extensions. If we can access a control object directly, why would we need a markup extension to access a binding object?
Do we need markup extensions so XAML is aware of the code behind (otherwise there is no way to get access any of the built in classes)? But then how can we access all the control types?
Markup extensions are not about access but extending functionality of markup (as the name implies) by doing whatever you want them to, like creating associations (Binding, x:Reference) or getting the type of a class (x:Type).
They can be used for just about anything, they are only necessary where the markup does not suffice on its own.
Rationale for markup extensions:
XAML is simple, which is a good thing. It is just an XML-based
language used to declare objects and the relationships between them.
One side effect of being simple is that it can be verbose. This
cumbersome verbosity was one of the main reasons why the concept of
markup extensions was introduced. A markup extension can be used to
turn many lines of XAML into one concise expression...
Another side effect of XAML’s simplicity is that it does not have any
“built in” knowledge of common artifacts used by WPF or the CLR; such
as resource references, data binding, a null value, arrays, static
members of a class, etc. Since XAML can be an integral part of
application development there needs to be some way for developers to
express those ideas in it.
<TextBox >
<TextBox.Text>A text in TextBox</TextBox.Text>
</TextBox>
<TextBox Text="{x:Static system:Environment.UserName}" />
This latter syntax also provides a way to use values other than a literal string (i.e., which is a new object) such as an already constructed object or a static object in our assembly. In this sense markup extensions are objects which decide
how a property's going to be set at runtime.
From https://wpftutorial.net/XAML.html:
Markup extensions are dynamic placeholders for attribute values in
XAML. They resolve the value of a property at runtime.
Markup
extensions are surrouded by curly braces (Example:
Background="{StaticResource NormalBackgroundBrush}").
WPF has some
built-in markup extensions, but you can write your own, by deriving
from MarkupExtension. These are the built-in markup extensions:
Binding
To bind the values of two properties together.
StaticResource
One time lookup of a resource entry
DynamicResource
Auto updating lookup of a resource entry
TemplateBinding
To bind a property of a control template to a dependency property of
the control
x:Static
Resolve the value of a static property.
x:Null
Return null
The first identifier within a pair of curly braces is the name of the extension. All preciding identifiers are named parameters in the
form of Property=Value. The following example shows a label whose
Content is bound to the Text of the textbox. When you type a text into
the text box, the text property changes and the binding markup
extension automatically updates the content of the label.
<TextBox x:Name="textBox"/>
<Label Content="{Binding Text, ElementName=textBox}"/>
Regarding what a markup extension is composed of:
All markup extensions derive from the abstract MarkupExtension class
and override its ProvideValue method. The naming convention is to
append the word Extension to the subclass’s name (only the Binding
class does not follow the pattern).
The XAML parser allows markup
extensions to be created within {curly braces} and it also allows you
to omit the Extension suffix when using a markup extension, if you
want to.
Example code:
<!--- Configure a binding markup extension via the special curly brace syntax --->
<TextBox Text="{Binding Path=Name}" Width="120"/>
<!--- Configure a binding markup extension via the standard element syntax --->
<Checkbox Content="Is person alive?">
<Checkbox.IsChecked>
<Binding Path="IsAlive"/>
</Checkbox.IsChecked>
</Checkbox>
In the XAML above, take a look at the TextBox’s Text property, and the
CheckBox’s IsChecked property. They both use the Binding markup
extension to bind their values to a property on the data context (a
Person object).

difficulty understanding and using xaml markup extentions

I am learning on to the concepts of WPF such as data binding, commands, resources, element bindings, styles etc, which use markup extensions extensively, and i am having problem understanding the meaning behind the Markup classes, as they are being used beyond what i understand they should be used for. So here are a few points i need to clear:
(all code snippets are from Pro WPF in C# 2010 book)
What is the meaning and use of Static extension? It can be used to
declare static resources, which can be declared in as
, but this xaml confuses me:
<Button ... Foreground="{x:Static SystemColors.ActiveCaptionBrush}" >
In {x:Static SystemColors.ActiveCaptionBrush}, what is the role
of static here, and what will change if i use x:Dynamic here? The
book says this xaml is equivalent to this codebehind:
cmdAnswer.Foreground = SystemColors.ActiveCaptionBrush;
This means that if i have a class with static properties, i should
be able to use something like this:
<Button ... Foreground="{x:Static MyClass.SomeStaticProperty}" >
But it didn't work, despite i had created a class, i tried using
local:Static (referring to the local namespace) but VisualStudio
didn't allow me to use it. What is the proper method of achieving
this?
What is the meaning of Binding (beyond obvious meaning, what is
happening when i am binding)? It is used for resource binding, or
data or element binding. I was able to understand element binding,
but binding to objects that are not elements caused problems. For
example:
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},
Path=Source}"></TextBlock>
Here it is binding to the text to the SystemFonts.IconFontFamily
property, what is the use of x:static in this case, and how to bind
it to a property in a class that i have created? Also how to update
the text property of the textfield if the value of the binding
target changes? Due to binding, it should update by itself, is this
the case?
All the examples in the book make use of SystemFonts.IconFontFamily,
none that i have seen explains the use of such binding, and how to
do it for the classes that i create? Some help in this regard is
needed. I want to ask more about binding, but i will do so in a
separate question about binding only.
Finally, recommend a book or resource that explains what is
happening, instead of how to do this and that?
Answers....
1)
You said ...
... This means that if i have a class with static properties, i should be
able to use something like this:
<Button ... Foreground="{x:Static MyClass.SomeStaticProperty}" >
But it didn't work, despite i had created a class, i tried using
local:Static (referring to the local namespace) but VisualStudio
didn't allow me to use it. What is the proper method of achieving
this?
Well your trial attempt was correct but it was incorrect to what term you have applied that namespace token to.... local namespace token applies to the class that is declared under it so...
<Button ... Foreground="{x:Static local:MyClass.SomeStaticProperty}" >
Should work just fine provided that SomeStaticProperty is a valid Brush.
In this example, the whole markup was internally equivalent to Binding as ...
Binding.Source = {x:Type local:MyClass}
Binding.Path = SomeStaticProperty.
2)
You had an example...
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},
Path=Source}">
</TextBlock>
So use the same equivalence from example 1 and apply it to this example...
<TextBlock Text="{Binding Source={x:Type SystemFonts},
Path=IconFontFamily.Source}">
</TextBlock>
3)
I learned this whole thing from MSDN... I dont think we can have any other legitimate source than that.

What does this WPF binding mean?

I have this sample code:
<ControlTemplate Content="{Binding .}"/>
What does the point mean here relating to the binding?
The . (period) of the binding refers to the binding path, and simply tells it to bind to the current source (i.e. inherited DataContext).
From the MSDN page:
Optionally, a period (.) path can be used to bind to the current source. For example, Text=”{Binding}” is equivalent to Text=”{Binding Path=.}”.
Also note that Path= can be omitted if Path is the first parameter, so your code means exactly the same. I tend to prefer just the {Binding} syntax, though it's up to you.

Resources