SplitButton drop down content and relative data binding

Feb 4, 2013 at 9:38 AM
Good day,

I am trying to populate a listview which is contained within a SplitButton.DropDownContent element to a list of columns in a DataGrid. After some playing around with {Binding ElementName=libraryDataGrid} i see that there are 'visual tree issues' similar to what is encountered when referencing elements from a context menu. Typically, to overcome this issue I use the 'Tag' property of the parent element which IS within the visual tree to hold the objects I want to bind with. However, this does not seem to work with a split button and I cannot figure out why. Anyone have any ideas?

Example:
this is a greatly simplified example so its easy to read. In reality, the SplitButton is contained within a ToolbarItem within a ToolbarTray and the DataGrid is contained within a TabControl located underneath this toolbar. Im fairly sure this wont make a difference to any proposed solution but...worth a mention just in case.
<Window>
    <xctk:SplitButton x:Name="ColumnControl" Content="Columns" Tag="{Binding Columns, ElementName=LibraryDataGrid}">
                    <xctk:SplitButton.DropDownContent>
                        <ListView ItemsSource="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource TemplatedParent}}" />                 
                    </xctk:SplitButton.DropDownContent>
                </xctk:SplitButton>

<xcdg:DataGridControl x:Name=LibraryDataGrid />

</Window>
I have tried many different permutations of the ListViews ItemsSource expression but they either give "no value found" errors or the ListView renders entirely empty. If I take the ListView element out of the SplitButton and use {Binding Columns, ElementName=LibraryDataGrid} as the expression for the ItemsSource property, all works well.

Thank you for your time and any ideas you may have on this matter.
Feb 5, 2013 at 2:07 PM
Edited Feb 5, 2013 at 2:08 PM
Maybe binding using the "FindAncestor" approach to reach the DataGrid ?
The DataGrid may not be the "ancestor" of the split button, but one of it may have a property that point to it..
Feb 6, 2013 at 5:48 PM
This was my first consideration, I have done something similar with ContextMenu's before. The taxonomy of the page is thus:

Window
----Grid
--------ToolbarTray
------------ToolBar
--------------- SplitButton
--------TabControl
------------TabItem
----------------Grid
------------------- DataGridControl

With the SplitButton defined as:
<xctk:SplitButton x:Name="ColumnControl" Content="Columns" Tag="{Binding Columns, ElementName=LibraryDataGrid}">
     <xctk:SplitButton.DropDownContent>
        <ListView ItemsSource="{Binding Path=Tag, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xctk:SplitButton}}}" />                 
    </xctk:SplitButton.DropDownContent>
</xctk:SplitButton>
But receive the following message in the output window as the Window loads:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Xceed.Wpf.Toolkit.SplitButton', AncestorLevel='1''. BindingExpression:Path=Tag; DataItem=null; target element is 'ListView' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
Have tried with various AnsestorLevels but still the same error. Am I using this method incorrectly?
Feb 7, 2013 at 5:52 PM
Edited Feb 8, 2013 at 12:00 PM
Same issue than the one described in this thread,
Adding an item to the "DropDownContent" property does not add it to the visual tree

http://wpftoolkit.codeplex.com/discussions/431886
Feb 11, 2013 at 6:28 AM
So after reading the content in the linked article(s), the conclusion is that this is not possible with straightforward xaml syntax and some kind of 'visual tree' helper methods are required in the code-files ? Why then does the {RelativeSource} method work in the ContextMenu environment as these are not added to the visual tree either yet, I am able to bind data to them using nothing but xaml.
Feb 11, 2013 at 2:03 PM
Edited Feb 11, 2013 at 2:08 PM
Yes you can, using the Reference syntax like:

{Binding Source={x:Reference _myElement}, Path=MyValue}

This issue has been created based on this tread
Feb 11, 2013 at 5:54 PM
Apologies for my ignorance here but, it does not appear as if I can use this x:Reference. After some Googling it would seem I cannot use x:Reference with xaml 2006 and I dont have any 2009 equivalents. At design-time I get "Object reference not set to instance of an object" errors and at run-time I get an error about cyclical dependencies not being allowed.

Is there a way to use x:Reference and have it not err? My WPF project is compiled in .Net 4.
Dec 6, 2013 at 1:26 PM
Actually - DataContext, RoutedEvents, RoutedCommands don't cross Popup's boundary by default. However this problem can be solved somehow by adding Popup as a logical child of it's parent control which is done in ComboBox and also in another SplitButton implementation http://blogs.msdn.com/b/delay/archive/2010/07/06/banana-splitbutton-a-wpf-specific-fix-for-splitbutton-and-some-code-analysis-improvements-for-the-silverlight-version-too.aspx.