Search code examples
wpfwpf-style

In WPF style how to correct bind parent checkbox property to a child?


I'm new to WPF styling and I cannot make next thing to work: I've got a custom checkbox style with another checkbox in it. I need parent "IsChecked" value to change as "contolCheckBox" child in ControlTemplate changes. Tryed different triggers but can't get to parent property. For now I've got next xaml code:

<Style x:Key="CustomCheckBox" TargetType="{x:Type CheckBox}">
    <Setter Property="Height" Value="27" />
    <Setter Property="Foreground" Value="#FFBABAC7" />
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <Grid>
                    <CheckBox x:Name="contolCheckBox" HorizontalAlignment="Right" VerticalAlignment="Center"/>
                    <ContentPresenter  HorizontalAlignment="Left" VerticalAlignment="Center"/>
                </Grid>
            </ControlTemplate>

        </Setter.Value>
    </Setter>

    <Setter Property="IsChecked" Value="{Binding IsChecked, ElementName=contolCheckBox}"/>
    <!---->
    <Style.Triggers>
        <Trigger Property="IsChecked" Value="True">
            <Setter Property="Foreground" Value="#FF29E200"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="False">
            <Setter Property="Foreground" Value="Firebrick"/>
        </Trigger>
    </Style.Triggers>
</Style>

"IsChecked" value of control doesn`t changes. What am I doing wrong?

Binding ElementName=contolCheckBox, Path=IsChecked

not working too.


Solution

  • I don't think controlCheckBox is within the name scope since it's declared within the ControlTemplate. So your binding isn't working. Instead, invert your binding and bind from the bottom up. What you're looking for in a sitation like this is template binding. Try this in yourControlTemplate ..

    <CheckBox x:Name="contolCheckBox" HorizontalAlignment="Right" VerticalAlignment="Center"
              IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked, Mode=TwoWay}" />
    

    Note the RelativeSoucebinding. This indicates that I want to bind to the parent of the template. This is the common way to bind underlying ControlTemplate controls to parent properties.