I’ve been getting some inquires about the BindableApplicationBar sample from the Cimbalino Windows Phone Toolkit, specifically about what is the NamescopeBinding
resource appearing on the top of the MainPage.xaml file.
Here is the specific bit:
<phone:PhoneApplicationPage.Resources>
<cimbalinoHelpers:NamescopeBinding x:Key="ItemsMultiselectList" Source="{Binding ElementName=ItemsMultiselectList}" />
</phone:PhoneApplicationPage.Resources>
This special class has a single property called Source
that can be set to any object; in this sample, it’s pointing to a named control inside the pages LayoutRoot (hence the single Binding.ElementName
property set)
If you look a bit down the code, you’ll find the ApplicationBarIconButton.CommandParameter
where this resource is getting referenced:
<cimbalinoBehaviors:ApplicationBarIconButton
Command="{Binding DeleteItemsCommand, Mode=OneTime}"
CommandParameter="{Binding Source.SelectedItems, Source={StaticResource ItemsMultiselectList}}"
IconUri="/Images/appbar.delete.rest.png"
Text="delete" />
If we just put the two parts together, we can see that the whole objective is to bind the ApplicationBarIconButton.CommandParameter
property to ItemsMultiselectList.SelectedItems
property.
Obviously you’d expect to just do it directly, like this:
<cimbalinoBehaviors:ApplicationBarIconButton
Command="{Binding DeleteItemsCommand, Mode=OneTime}"
CommandParameter="{Binding SelectedItems, ElementName=ItemsMultiselectList}"
IconUri="/Images/appbar.delete.rest.png"
Text="delete" />
In reality, this approach doesn’t work from the PhoneApplicationPage
point of view, due to the different XAML Namescope.
Here is the XAML Namescope definition found in this MSDN article:
…a XAML namescope stores relationships between the XAML-defined names of objects and their instance equivalents. This is similar to the wider meaning of the term “namescope” in other programming languages and technologies.
So think of the XAML Namescope as a hash-table with each control name and it’s instance (something like IDictionary<string, FrameworkElement>
).
The problem is that the page’s LayoutRoot control gets a different XAML Namescope from the page itself, so searching for a child control from inside the page just won’t work!
The following image illustrates the Namescope boundaries for a default new page:
This is where the NamescopeBinding
helper class makes its entry: just register an instance of this class as a page resource and bind the NamescopeBinding.Source
property to the control you require outside the LayoutRoot XAML Namescope as shown in the sample code, and that’s it!
In the BindableApplicationBar sample, if you actually attach the MultiApplicationBarBehavior
to the LayoutRoot instead of the page, it will work perfectly without the need for the NamescopeBinding
helper class.
But my advice is to always bind the ApplicationBarBehavior
and MultiApplicationBarBehavior
to the page as it will provide better integration and more fluid animation, and use the NamescopeBinding
helper class if needed.
I’ve created a small sample app that demonstrates the XAML Namescope behavior and how it affects your applications, which you can download from here.