Forum Xamarin.Forms

ControlTemplate Triggers

drouleaudrouleau Member ✭✭

I'm trying to use Triggers in my ControlTemplate but the control is not updating. I have tried using both basic property Trigger and DataTrigger. Has anyone used Triggers in a ControlTemplate in Xamarin based on a Parent / TemplatedParent custom control's property? I have tried every variation of binding and Property setting I can think of. I'm starting to think that what I'm trying to do will just not work.

Any insight appreciated. Thanks!

<ControlTemplate x:Key="LabeledFieldTemplate">
            <Grid Margin="3,3,3,3"
              HorizontalOptions="StartAndExpand"
              VerticalOptions="StartAndExpand">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>

                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <!--Default is "Above"-->
                <Label x:Name="LabelText"
                               Grid.Row="0"
                               Grid.Column="0"
                               FontSize="12"
                               TextColor="DarkGoldenrod"
                               Text="Test Text">
                    <Label.Triggers>
                        <Trigger TargetType="Label" Property="controls:LabeledField.LabelPosition" Value="None">
                            <Setter Property="IsVisible" Value="False" />
                        </Trigger>

                        <Trigger TargetType="Label" Property="controls:LabeledField.LabelPosition" Value="Right">
                            <Setter Property="Grid.Column" Value="1"/>
                            <Setter Property="Grid.Row" Value="0"/>
                            <Setter Property="Label.TextColor" Value="Purple"/>
                            <Setter Property="VerticalOptions" Value="Start" />
                            <Setter Property="WidthRequest" Value="{TemplateBinding LabelColumnWidth}" />
                            <Setter Property="Margin" Value="{TemplateBinding LabelPaddingWhenRight}" />
                        </Trigger>


                        <DataTrigger TargetType="Label" Binding="{TemplateBinding BindingContext.LabelPosition}" Value="Left">
                            <Setter Property="Grid.Column" Value="0"/>
                            <Setter Property="Grid.Row" Value="0"/>
                            <Setter Property="Label.TextColor" Value="Green"/>
                            <Setter Property="VerticalOptions" Value="Start" />
                            <Setter Property="WidthRequest" Value="{TemplateBinding LabelColumnWidth}" />
                            <Setter Property="Margin" Value="{TemplateBinding LabelPaddingWhenLeft}" />
                        </DataTrigger>


                        <DataTrigger TargetType="Label" Binding="{Binding LabelPosition}" Value="Above">
                            <Setter Property="Grid.Column" Value="0"/>
                            <Setter Property="Grid.Row" Value="0"/>
                            <Setter Property="Label.TextColor" Value="Orange"/>
                            <Setter Property="VerticalOptions" Value="End" />
                            <Setter Property="HeightRequest" Value="-1" />
                            <Setter Property="WidthRequest" Value="{Binding Width, Source={x:Reference Content}}" />
                            <Setter Property="Margin" Value="{TemplateBinding LabelPaddingWhenAbove}" />
                        </DataTrigger>


                        <DataTrigger TargetType="Label" Binding="{TemplateBinding Parent.LabelPosition}" Value="Below">
                            <Setter Property="Grid.Column" Value="0"/>
                            <Setter Property="Grid.Row" Value="1"/>
                            <Setter Property="Label.TextColor" Value="Blue"/>
                            <Setter Property="VerticalOptions" Value="End" />
                            <Setter Property="HeightRequest" Value="-1" />
                            <Setter Property="WidthRequest" Value="{Binding Width, Source={x:Reference Content}}" />
                            <Setter Property="Margin" Value="{TemplateBinding LabelPaddingWhenBelow}" />
                        </DataTrigger>
                    </Label.Triggers>
                </Label>

                <ContentPresenter x:Name="Content"
                                          Grid.Row="1"
                                          Grid.Column="0"
                                          VerticalOptions="CenterAndExpand">
                    <ContentPresenter.Triggers>
                        <DataTrigger TargetType="ContentPresenter" Binding="{TemplateBinding Parent.LabelPosition}" Value="Right">
                            <Setter Property="Grid.Column" Value="0"/>
                            <Setter Property="Grid.Row" Value="0"/>
                        </DataTrigger>

                        <DataTrigger TargetType="ContentPresenter" Binding="{TemplateBinding Parent.LabelPosition}" Value="Left">
                            <Setter Property="Grid.Column" Value="1"/>
                            <Setter Property="Grid.Row" Value="0"/>
                        </DataTrigger>

                        <DataTrigger TargetType="ContentPresenter" Binding="{TemplateBinding Parent.LabelPosition}" Value="Above">
                            <Setter Property="Grid.Column" Value="0"/>
                            <Setter Property="Grid.Row" Value="1"/>
                        </DataTrigger>

                        <DataTrigger TargetType="ContentPresenter" Binding="{TemplateBinding Parent.LabelPosition}" Value="Below">
                            <Setter Property="Grid.Column" Value="0"/>
                            <Setter Property="Grid.Row" Value="0"/>
                        </DataTrigger>
                    </ContentPresenter.Triggers>
                </ContentPresenter>
            </Grid>
        </ControlTemplate>

Here is a snippet of code that defines the LabelPosition property on the LabeledField class

    public static readonly BindableProperty LabelPositionProperty = BindableProperty.Create(
        "LabelPosition",
        typeof(LabelPosition),
        typeof(LabeledField),
        LabelPosition.Right,
        propertyChanged: UpdateLayout);

    public LabelPosition LabelPosition
    {
        get => (LabelPosition)GetValue(LabelPositionProperty);
        set => SetValue(LabelPositionProperty, LabelPosition);
    }

    public static LabelPosition GetLabelPosition(BindableObject element)
    {
        return (LabelPosition)element.GetValue(LabelColumnWidthProperty);
    }

    public static void SetLabelPosition(BindableObject element, LabelPosition value)
    {
        element.SetValue(LabelPositionProperty, value);
    }

    private static void UpdateLayout(BindableObject bindable, object oldvalue, object newvalue)
    {
        var labeledField = bindable as LabeledField;
        //Calling this method will invalidate the measure and triggers a new layout cycle.
        //labeledField?.InvalidateLayout();

        //labeledField?.UpdateChildrenLayout();
        labeledField?.ForceLayout();
    }

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    By chance did you post this yesterday? I swear I answered an identical question in the last 48 hours - right down to the "I've tried every variation I can think of" remark.

    If not, maybe just browse back a day or two as you're not the first person to have a problem with binding and this has been answered before - recently

  • drouleaudrouleau Member ✭✭
    edited April 2018

    I did post this yesterday and then my post got deleted and I never got to see your response. You sent me a link about formatting the code in a xamarin forum post. Would you mind posting your solution again?

    The link to my post yesterday that says "Post Not Found" - /discussion/comment/327922

Sign In or Register to comment.