Reputation: 5724
I'm using the DropDownButton control from the Extended WPF Toolkit. Inside of that, I'm hosting a ListBox which, upon change of selected element, should hide the containing DropDownButton.
My initial approach to do so in conjunction with Microsoft's interactivity framework was:
<xctk:DropDownButton x:Name="WorkspaceSelectorContainer" Content="This is the active workspace">
<xctk:DropDownButton.DropDownContent>
<ListBox ItemsSource="{Binding workspaces}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<ie:ChangePropertyAction PropertyName="IsOpen" Value="False" TargetObject="{Binding ElementName=WorkspaceSelectorContainer}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
</StackPanel>
</xctk:DropDownButton.DropDownContent>
</xctk:DropDownButton>
But this didn't work as WorkspaceSelectorContainer isn't found. Instead of binding by ElementName, I tried finding the ancestor of type DropDownButton, but this did not work either; tracing the binding showed it only resolved ancestors up to the outer most element of DropDownButton.DropDownContent, but not any further; e.g. the DropDownButton itself wasn't part of the ancestor tree.
Ok, so my next approach was
<ie:ChangePropertyAction PropertyName="IsOpen" Value="False" TargetObject="{Binding Source={x:Reference WorkspaceSelectorContainer}}"/>
but that did not work either as it threw an Exception
A first chance exception of type 'System.Xaml.XamlObjectWriterException' occurred in System.Xaml.dll
Additional information: Cannot call MarkupExtension.ProvideValue because of a cyclical dependency. Properties inside a MarkupExtension cannot reference objects that reference the result of the MarkupExtension.
Don't know what else to try anymore. Does anyone have an idea how to solve this?
Would it be possible to somehow reference my root grid that contains everything, and search for the DropDownButton element from there? Something like {Binding Source={x:Reference MyRootGrid}, ElementName=WorkspaceSelectorContainer} (this doesn't work as I can't combine source and ElementName)
Thanks!
Upvotes: 4
Views: 1885
Reputation: 6146
Well I had the same problem (albeit in Silverlight). Solved it by introducing a resource object that has a reference to the DropDownButton and that can easily be bound from within the DropDownContent:
<Foo.Resources>
<BindableObjectReference
x:Key="WorkspaceSelectorContainerReference"
Object="{Binding ElementName=WorkspaceSelectorContainer}"/>
</Foo.Resources>
<DropDownButton x:Name="WorkspaceSelectorContainer" ...>
<DropDownButton.DropDownContent>
...
<ChangePropertyAction
PropertyName="IsOpen"
Value="False"
TargetObject="{Binding Path=Object,
Source={StaticResource WorkspaceSelectorContainerReference}}"/>
...
</DropDownButton.DropDownContent>
</DropDownButton>
...and the magic object
public class BindableObjectReference : DependencyObject
{
public object Object
{
get { return GetValue( ObjectProperty ); }
set { SetValue( ObjectProperty, value ); }
}
public static readonly DependencyProperty ObjectProperty =
DependencyProperty.Register( "Object", typeof( object ),
typeof( BindableObjectReference ), new PropertyMetadata( null ) );
}
Upvotes: 4
Reputation: 27338
<ie:ChangePropertyAction PropertyName="IsOpen" Value="False"
TargetName="WorkspaceSelectorContainer" />
Upvotes: 0