Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding doesn't work without specifying the ancestor

The combobox binding below works if I specify the ancestor, but otherwise not. Why doesn't it work if I don't specify the ancestor?

<wpftoolkit:DataGrid Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2"
                         Margin="5"
                         BorderBrush="#A6A6A6"
                         BorderThickness="1"
                         ItemsSource="{Binding DebitListing}"
                         AutoGenerateColumns="False"
                         SelectionMode="Single">
        <wpftoolkit:DataGrid.Columns>
            <wpftoolkit:DataGridComboBoxColumn
                Header="{Resx ResxName=MyBooks.Properties.Strings, Key=PartyListing_Party_Label}"
                SelectedItemBinding="{Binding Party, ValidatesOnDataErrors=True}"
                DisplayMemberPath="Name">

                <wpftoolkit:DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CreditedAccounts, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                    </Style>
                </wpftoolkit:DataGridComboBoxColumn.ElementStyle>
                <wpftoolkit:DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CreditedAccounts, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                    </Style>
                </wpftoolkit:DataGridComboBoxColumn.EditingElementStyle>

            </wpftoolkit:DataGridComboBoxColumn>

            <wpftoolkit:DataGridTextColumn
                Header="{Resx ResxName=MyBooks.Properties.Strings, Key=PartyListing_Amount_Label}"
                Binding="{Binding Amount, ValidatesOnDataErrors=True}"/>
        </wpftoolkit:DataGrid.Columns>
    </wpftoolkit:DataGrid>
like image 815
pratikjgandhi Avatar asked Sep 07 '26 08:09

pratikjgandhi


1 Answers

The reason you need to reference the ancestor from which to get your desired DataContext is because the wpftoolkit changes the datacontext on its rendered child elements. You'll find that this is true of almost all ListView/DataGrid controls - the child element DataContext is changed to reference the collection item the current row or column is representing. If you want something in the Template or Style of those child elements to be based on a property off the control's DataContext, you need to use RelativeSource Ancestor to get to it.

I understand that this is confusing, since in basic XAML, child elements always automatically inherit the data context of their parent element, but the DataContext is just like any other DependencyProperty, and complex controls can set it differently as they see fit.

You can simplify your syntax if you like by giving your parent control (or whatever element the DataContext is set on) a name, like x:Name='ControlRoot'. Then when you need to get back to your root datacontext, you need only go:

Value="{Binding ElementName=ControlRoot, Path=DataContext.CreditedAccounts}"
like image 74
Alain Avatar answered Sep 11 '26 16:09

Alain



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!