Why Binding Syntax Differs when we are writing in nested XAML - wpf

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.

Related

Simple WPF Databinding syntax for 'Path' property

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.

What do parentheses in binding paths mean?

Recently i've read 'Databinding overview' article at MSDN and there is such sample code:
<TextBox.ToolTip>
<Binding RelativeSource="{RelativeSource Self}" Path="(Validation.Errors)[0].ErrorContent"/>
</TextBox.ToolTip>
I know that {} means markup extensions but what mean () parentheses here? It would be nice someone share link to explanation such syntax. Thanks!
Path="(Validation.Errors)[0].ErrorContent"
The () parentheses refer to Attached Properties.
Binding to an Attached Property
Quoting the MSDN library (I'm quoting MSDN here because I couldn't have written it down better):
This syntax is generally used for one of the following cases:
The path is specified in XAML that is in a style or template that does not have a specified TargetType. A qualified usage is generally not valid for cases other than this, because in non-style, non-template cases, the property exists on an instance, not a type.
The property is an attached property.
You are binding to a static property.
For use as storyboard target, the property specified as propertyName must be a DependencyProperty.
(Validation.Errors) references the attached property Errors in the Validation class. Since the binding has a RelativeSource = Self, it's gonna look for the value of that attached property with respect to the TextBox itself.
This below msdn link is neatly explaining about the validation rule and sequences as well as how to use.
http://msdn.microsoft.com/en-us/library/system.windows.controls.validation.errors.aspx

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).

Current binding value

I'm writing markup extension. I have XAML like this
<TextBlock Text="{ui:Test SomeInfo}" />
and TestExtension with constructor taking one string argument. I'm getting "SomeInfo" string so everything is find. Now I want to nest extensions and write something like
<TextBlock Text="{ui:Test {Binding PropName}}" />
and it does not work as is. I had to add constructor which takes one argument of System.Windows.Data.Binding type.
Now I need to know
How should I retrieve a current value from the Binding object?
When should I do this? Should I subscribe to changes some way or ask for that value every time in ProvideValue method?
Update1 PropName should be resolved against DataContext of TextBlock.
Update2 Just found related question: How do I resolve the value of a databinding?
Bindings like this will not work because your MarkupExtension has no DataContext and it does not appear in the visual tree and i do not think you are supposed to interact with binding objects directly. Do you really need this extension? Maybe you could make do with the binding alone and a converter?
If not you could create a dedicated class which has bindable properties (by inheriting from DependencyObject), this however would still not give you a DataContext or namescope needed for ElementName or a visual tree needed for RelativeSource, so the only way to make a binding work in that situation is by using a Source (e.g. set it to a StaticResource). This is hardly ideal.
Also note that if you do not directly set a binding the ProvideValue method will only be called once, this means that even if you have a binding in your extension it may not prove very useful (with some exceptions, e.g. when returning complex content, like e.g. an ItemsControl which uses the binding, but you set the extension on TextBlock.Text which is just a string), so i really doubt that you want to use a MarkupExtension like this if the value should change dynamically based on the binding. As noted earlier: Consider converters or MultiBindings for various values instead.

How does a XAML definition get turned into an object instance?

XAML allows you to specify an attribute value using a string that contains curly braces. Here is an example that creates a Binding instance and assigns it to the Text property of the TextBox element.
<TextBox Text="{Binding ElementName=Foo, Path=Bar}"/>
I want to extend XAML so that the developer could enter this as valid...
<TextBox Text="{MyCustomObject Field1=Foo, Field2=Bar}"/>
This would create an instance of my class and set the Field1/Field2 properties as appropriate. Is this possible? If so how do you do it?
If this is possible I have a followup question. Can I take a string "{Binding ElementName=Foo, Path=Bar}" and ask the framework to process it and return the Binding instance it specified? This must be done somewhere already to make the above XAML work and so there must be a way to ask for the same thing to be processed.
The Binding class is a Markup Extension. You can write your own by deriving from System.Windows.Markup.MarkupExtension.
ElementName and Path are simply properties on the Binding object.
As for the followup you can create a new Binding in code by instantiating the Binding object. I do not know of a way to process a string through.
take a look at markupextensions
http://blogs.msdn.com/wpfsdk/archive/2007/03/22/blogpost-text-creatingasimplecustommarkupextension.aspx

Resources