Sceen
Sceen

Reputation: 17

WPF Databinding in ControlTemplate not working C#

I try to bind a simple bool to a checkbox and a datatrigger in a controltemplate, but nothing is working. The checkbox is only for test purpose. I already went through the posts here, but most problems are caused by setting a property directly and not in the style, thus overwriting it. The datatrigger using the mouseover property is working just fine. Its only the binding to the bool which doesn't work.

My Code so far: cs:

public partial class HostFrame : UserControl
{
    public bool test { get; set; }

    public HostFrame()
    {
        test = true;
        InitializeComponent();          
    }
}

Xaml:

<UserControl x:Class="OwnDrawingv2.Elements.HostFrame"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:OwnDrawingv2.Elements"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <Style TargetType="{x:Type local:HostFrame}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:HostFrame}">
                        <Grid Background="LightBlue" Name="host_grid">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="20"></RowDefinition>
                                    <RowDefinition Height="Auto"></RowDefinition>
                                </Grid.RowDefinitions>
                            <ContentPresenter Name="content" Grid.Row="1" Grid.Column="1" />
                            <CheckBox Grid.Column="0" Grid.Row="0" IsChecked="{Binding Path=test}"> <!--Test prupose-->
                            </CheckBox>
                            <Image Grid.Column="1" Grid.Row="0" Name="attention" Width="30" Height="30"  Source="/attention_icon.png">
                                <Image.Style>
                                    <Style TargetType="Image">
                                        <Setter Property="Visibility" Value="Visible"></Setter>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding Path=test}" Value="true">

                                                <Setter Property="Visibility" Value="Hidden"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Image.Style>
                            </Image>
                            <Ellipse Grid.Column="0" Grid.Row="1" Width="10" Height="10"  Fill="Black">
                                <Ellipse.Style>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Visibility" Value="Hidden"></Setter>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding ElementName=content, Path=IsMouseOver}" Value="true">
                                                <Setter Property="Visibility" Value="Visible"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Ellipse.Style>
                            </Ellipse>
                            <Ellipse Grid.Column="2" Grid.Row="1" Width="10" Height="10"  Fill="Black">
                                <Ellipse.Style>
                                    <Style TargetType="Ellipse">
                                        <Setter Property="Visibility" Value="Hidden"></Setter>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding ElementName=content, Path=IsMouseOver}" Value="true">
                                                <Setter Property="Visibility" Value="Visible"></Setter>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Ellipse.Style>
                            </Ellipse>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
</UserControl>

UPDATE: I got an answer for my original question and I understand this. But why are there tutorials in the web, which seem to work without the relativesource? UPDATE2: I missed one answers information about Datacontext, thank you. The problem is solved.

Upvotes: 0

Views: 1292

Answers (2)

Med.Amine.Touil
Med.Amine.Touil

Reputation: 1235

if you do the following IsChecked="{Binding Path=test}" that means your UserControl class is the DataContext of it self (or you didn't say that). So you have 2 solutions (I guess)

1- Move your Test property to your ViewModel and do your Binding. 2- Use RelativeResource and FindAncestor method ({Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}})

PS: IF your HostFrame inherits from Control,UIELement..., It would be better to define a DependencyProperty and do a TemplateBinding

Upvotes: 0

Natxo
Natxo

Reputation: 2947

You have not set a Datacontext for your UserControl therefore i assume it will be null. You should see the binding error in your output.

On the other hand, your property test doesnt't notify changes. You should declare it as a dependency property if it belongs to the UserControl (instead of being part of the ViewModel)

Upvotes: 1

Related Questions