0

I'm making a customcontrol to act like a filter you can enable with a checkbox and when you do, some fields apprears for the user to fill. So my customcontrol has a checkbox and a contentcontrol, I use contentcontrol because I want the fields to be what ever I want. When I check the checkbox, I set the contentcontrol's heigh to Auto and when it is not checked I set it to 0. That much works. I also need to know in my viewmodel if that checkbox is checked or not. My issue is there, the templatebinding doesn't seems to work on that IsChecked property of the checkbox. I tried making a dependencyproperty called IsSelected for example and I templatebind the checkbox's IsChecked to that IsSelected dependencyproperty but it doesn't work. When I check the checkbox, the IsSelected doesn't change... That is my customcontrol generic XAML

<Style TargetType="{x:Type local:FilterItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:FilterItem}">
                <Border Padding="{TemplateBinding Padding}"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <StackPanel>
                        <CheckBox Name="cbcheck" IsChecked="{TemplateBinding IsSelected}" Content="{TemplateBinding Title}" VerticalContentAlignment="Center"/>
                        <ContentControl Content="{TemplateBinding Content}" Margin="20 0 5 10">
                            <ContentControl.Style>
                                <Style TargetType="ContentControl">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding ElementName=cbcheck, Path=IsChecked}" Value="False">
                                            <Setter Property="Height" Value="0.0"/>
                                        </DataTrigger>
                                        <DataTrigger Binding="{Binding ElementName=cbcheck, Path=IsChecked}" Value="True">
                                            <Setter Property="Height" Value="Auto"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </ContentControl.Style>
                        </ContentControl>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Here is the .cs for that customcontrol, nothing special, only dependencyproperties

public class FilterItem: Control
{
    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TitleProperty =
        DependencyProperty.Register("Title", typeof(string), typeof(FilterItem), new PropertyMetadata(null));




    public bool IsSelected
    {
        get { return (bool)GetValue(IsSelectedProperty); }
        set { SetValue(IsSelectedProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsSelected.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsSelectedProperty =
        DependencyProperty.Register("IsSelected", typeof(bool), typeof(FilterItem), new PropertyMetadata(false));





    public FrameworkElement Content
    {
        get { return (FrameworkElement)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Content.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(FrameworkElement), typeof(FilterItem), new PropertyMetadata(null));



    static FilterItem()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(FilterItem), new FrameworkPropertyMetadata(typeof(FilterItem)));
    }
}

And I use it like that:

               <filtercontrol:FilterItem Title="Diamond Coil" IsSelected="{Binding IsDiamondCoil}">
                    <filtercontrol:FilterItem.Content>
                        <StackPanel>
                            <TextBlock Text="Max Lenght:"/>
                            <TextBox Text="{Binding MaxCoilOverallLenght}"/>
                            <TextBlock Text="Min width:"/>
                            <TextBox/>
                            <TextBlock Text="Max Width:"/>
                            <TextBox/>
                            <TextBlock Text="Max Vertical Section:"/>
                            <TextBox/>
                            <TextBlock Text="Max Horizontal Section:"/>
                            <TextBox/>
                        </StackPanel>
                    </filtercontrol:FilterItem.Content>
                </filtercontrol:FilterItem>

The templatebinding for the dependencyproperty Title which I use to set the checkbox's content works just fine. I don't get it why one works and the other one doesn't.

Thank you.

Philippe
  • 13
  • 5

1 Answers1

1

You can replace your TemplateBinding by a Binding to the TemplatedParent:

<CheckBox Name="cbcheck" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}" Content="{TemplateBinding Title}" VerticalContentAlignment="Center"/>

And declare your DependencyProperty as TwoWay:

public static readonly DependencyProperty IsSelectedProperty =
        DependencyProperty.Register("IsSelected", typeof(bool), typeof(FilterItem), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
Léo SALVADOR
  • 754
  • 2
  • 3
  • 17
  • 1
    Thanks for the reply, your suggestion works. Do you know any reason why the normal templatebinding to the propdp isn't working as we'd expect? Because in the end I think the templatebinding is working but in a different or something... I tried to just bind a simple checkbox, that is not part of a customcontrol, to the same property in the viewmodel, IsDiamondCoil. And when I check this checkbox, the IsDiamondCoil change as expected, but it also change the state of the checkbox in my customcontrol, so the templatebinding kinda work... it just doesn't works when I press it. – Philippe Feb 05 '22 at 03:00
  • In my opinion, it's related to the notion of "TwoWay" in the scenario of a TemplateBinding (in your case the "Model => View" link is updated but not the "View => Model" link). The answers to this question, which mainly differentiate these two options by the fact that one is evaluated at Compile Time, ans the other at RunTime, seem to point in that direction as well: https://stackoverflow.com/questions/1131222/wpf-templatebinding-vs-relativesource-templatedparent – Léo SALVADOR Feb 05 '22 at 03:23
  • Understood, thanks for the clarification and the link to the clarification. – Philippe Feb 05 '22 at 04:06