Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi All,

I was wondering if there exists a way to bind a DatagridComboBoxColumn's ItemsSource to the Datagrid to which it belongs.

I have a table in a SQL server database which is recursive and I want to display it in WPF with MVVM, but I'm having some trouble with making it work recursively.

thanks in advance

Some more info:

My datagrid's itemssource is bound to the property 'MyDataGridItems' of the 'MyViewModel' I used as my DataContext.

'MyDataGridItems' is an Observable collection of class 'MyModel' which has several properties: X, Y and Z.

The idea is to have the three properties X, Y and Z as columns on my datagrid (duh) with X and Y being normal textbox columns and Z as the combobox column, who's ItemsSource should list all the X's in the datagrid.

I have tried using Relative Source and FindAncestor, but this gives me:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''. BindingExpression:Path=MyDataGridItems.X; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=13390141); target property is 'ItemsSource' (type 'IEnumerable')

What am I doing wrong?

Here is the XAML:

XAML
<datagrid>
        VerticalScrollBarVisibility="Auto"
        x:Name="dtgDocuments"
        ItemsSource="{Binding DocumentsList, Mode=OneWay}" 
        AutoGenerateColumns="False" 
        HorizontalAlignment="Stretch" 
        VerticalAlignment="Top"
        Padding="5">
<datagrid.columns>
	<datagridtextcolumn>
        	Header="Document Number" 
                Width="Auto" 
                Binding="{Binding DocumentNumber, Mode=TwoWay}" 
                />
	<datagridtemplatecolumn header="Document Date">
		<datagridtemplatecolumn.celltemplate>
                	<datatemplate>
                        	<textblock>
                                Text="{Binding Path=DocumentDate, StringFormat={}{0:dd/MM/yyyy}}"
                                />
                        </textblock></datatemplate>
                    </datagridtemplatecolumn.celltemplate>
	<datagridtemplatecolumn.celleditingtemplate>
		<datatemplate>
			<datepicker>
                       	SelectedDate="{Binding Path=DocumentDate, Mode=TwoWay}" DataContext="{Binding}" 
			/>
                </datepicker></datatemplate>
        </datagridtemplatecolumn.celleditingtemplate>        
        </datagridtemplatecolumn>

	<datagridcomboboxcolumn>
		Header="Related Document" 
		Width="Auto" 
		ItemsSource="{Binding ElementName=dtgDocuments, Path=DocumentNumber}"
		/> <!-- This column should list all the DocumentNumbers on the DataGrid -->
</datagridcomboboxcolumn></datagridtextcolumn></datagrid.columns>
</datagrid>
Posted
Updated 29-Nov-11 2:21am
v4

Quote:
a way to bind a DatagridComboBoxColumn's ItemsSource to the Datagrid to which it belongs

Does a FindAncestor binding work?

ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=MyCollectionProperty}"
 
Share this answer
 
v2
Comments
PJ du Preez 29-Nov-11 0:48am    
Hi. thanks for the suggestion. I have tried this before (it seems like the logic thing to do), but it did not work. I'll try it again and see. Maybe I missed something.

The thing is the datagrid starts off empty and then when data is added, it should look back to itself, but I'll give your code a try and let you know.
thanks
PJ du Preez 29-Nov-11 1:15am    
Mmm. I get the same error as the previous time I tried:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''.

Have I chosen the correct Path? I've some more detail to my question (some info on the underlying model)

You can bind it using RelativeSource like Mark wrote. But, why do you use the AncestorLevel property? Try to omit it.


Another way is to bind it using ElementName. Just set a name to the DataGrid and, bind to it using this name, like the following:


XML
<DataGrid x:Name="myDataGrid">
    <DataGrid.Columns>
        <DataGridComboBoxColumn ItemsSource="{Binding ElementName=myDataGrid, Path=MyCollectionProperty}" />
    </DataGrid.Columns>
</DataGrid>
 
Share this answer
 
Comments
PJ du Preez 29-Nov-11 3:52am    
Thanks. I tried what you suggested and I received the following error:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element.

Is it not seeing my DataContext?
Shmuel Zang 29-Nov-11 5:15am    
I didn't get that error. Can you post your XAML?
PJ du Preez 29-Nov-11 8:22am    
I've added it to my question

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900