wpfbindingitemscontrolcontentcontrol

Binding inner ContentControl control to parent ItemsControl item


I think I almost got it but struggling with final solution.

As you can see, I tried using RelativeSource but it's taking me to an actual ItemsControl, not an item itself. It's probably something stupid I'm missing but I just can't get it. Any help appreciated. Thanks!

<!--List of "Board" items-->
<ItemsControl ItemsSource="{Binding BoardList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <GroupBox>
                <!--Eeprom is an object within "Board" item-->
                <ContentControl Content="{Binding Eeprom}">
                    <ContentControl.ContentTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <TextBox Text="{Binding IdPage}"/>
                                <Button Tag="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}}" Click="Button_Click"/>
                            </StackPanel>
                        </DataTemplate>
                    </ContentControl.ContentTemplate>
                </ContentControl>
            </GroupBox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Complete version (I unintentionally left of important containers):

<!--List of "Board" items-->
<ItemsControl ItemsSource="{Binding ContrSysAccessor.IBoardList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!--Eeprom is an object within "Board" item-->
            <ContentControl Content="{Binding Eeprom}">
                <ContentControl.ContentTemplate>
                    <DataTemplate>
                        <materialDesign:ColorZone>
                            <materialDesign:PopupBox>
                                <StackPanel>
                                    <TextBox Text="{Binding IdPage}"/>
                                    <Button Tag="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=DataContext}" Click="Button_Click"/>
                                </StackPanel>
                            </materialDesign:PopupBox>
                        </materialDesign:ColorZone>
                    </DataTemplate>
                </ContentControl.ContentTemplate>
            </ContentControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Solution

  • There are multiple controls derived from ContentControl in the control hierarchy:

    That is why your binding does not work. It will return the data context of the first control while traversing the parent controls. This control is materialDesign:Card and its data context Eeprom.

    You can make your binding work, if you specify which ContentControl in the hierarchy you want. This is defined by the AncestorLevel. Your target ContentControl is the fourth in the parent hierarchy, so specify 4.

    <Button Tag="{Binding RelativeSource={RelativeSource AncestorType=ContentControl, AncestorLevel=4}, Path=DataContext}" Click="Button_Click"/>
    

    An alternative to a RelativeSource binding, that works here, is setting an x:Name on your target ContentControl and referring to it in the binding with ElementName.

    <ItemsControl ItemsSource="{Binding Parent}">
       <ItemsControl.ItemTemplate>
          <DataTemplate>
             <!--Eeprom is an object within "Board" item-->
             <ContentControl x:Name="MyContentControl" Content="{Binding Text}">
                <ContentControl.ContentTemplate>
                   <DataTemplate>
                      <materialDesign:ColorZone>
                         <materialDesign:PopupBox>
                            <StackPanel>
                               <TextBox Text="{Binding Mode=OneWay}"/>
                               <Button Tag="{Binding DataContext, ElementName=MyContentControl}" Click="Button_Click"/>
                            </StackPanel>
                         </materialDesign:PopupBox>
                      </materialDesign:ColorZone>
                   </DataTemplate>
                </ContentControl.ContentTemplate>
             </ContentControl>
          </DataTemplate>
       </ItemsControl.ItemTemplate>
    </ItemsControl>