Wednesday, June 07, 2006

My previous post was about not being able to bind to a named element outside of your scope. With the help of some great people, we figured out a workaround: you can bind to an ancestor. So, this does work:

<StackPanel DataContext="{Binding ElementName=lb, Path=SelectedItem}">
<
ListBox Name="lb" ItemsSource="{Binding Source={StaticResource InventoryData}, XPath='Book'}" IsSynchronizedWithCurrentItem="True" />
<
local:CustomItemsControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type StackPanel}}, Path=DataContext}" />
</StackPanel>

This has a listbox that binds to a datasource (xml this time) and a stackpanel above it binds it's datacontext to the selecteditem of the listbox.
Obviously this has all kinds of nasty smells surrounding it.... Next please!

We might not be able to bind to a named element outside of scope, but if we can bind to an ancestor, chances are good that we can bind to a staticResource as well. So let's introduce a CollectionView around our XML datasource. In the Window.Resources:
<CollectionViewSource x:Key="InventoryView" Source="{Binding Source={StaticResource InventoryData}, XPath='Book'}" />

And then we can bind to the currentitem of this view, instead of the ugly datacontext of the parent stackpanel:

<StackPanel >
<
ListBox Name="lb" ItemsSource="{Binding Source={StaticResource InventoryView}}" IsSynchronizedWithCurrentItem="True" />
<
local:CustomItemsControl ItemsSource="{Binding Source={StaticResource InventoryView}, Path=CurrentItem}" />
</
StackPanel>

This is a good enough workaround for now. ;-)

Wednesday, July 12, 2006 4:33:53 PM (Romance Standard Time, UTC+01:00)
You know that DataContext is an inherited property. Your XAML should be as simple as.

&lt;StackPanel DataContext="{Binding ElementName=lb, Path=SelectedItem}"&gt;
&lt;ListBox Name="lb" ItemsSource="{Binding Source={StaticResource InventoryData},XPath='Book'}"
IsSynchronizedWithCurrentItem="True" /&gt;
&lt;local:CustomItemsControl ItemsSource="{Binding}" /&gt;
&lt;/StackPanel&gt;

If you use just the {Binding} convention, by default it checks the DataContext going up the tree. Actually, the DataContext is inherited by the CustomItemsControl from the stackpanel. It's similar to how the Background brush is inherited by a control from its parent unless explicitly set.
Mike Brown
Friday, July 14, 2006 3:34:55 PM (Romance Standard Time, UTC+01:00)
The whole problem was that the binding you propose (which is the way one would do this normally) does not work in this specific situation. The stackpanel is out of scope, and the inheritance-chain is broken.

Microsoft has acknowledged that this is a problem, but I have not yet checked if they have fixed this in the latest CTP. I do hope so!
Ruurd
Comments are closed.