Xamarin ControlTemplate 触发器应用于模板内的内部控件

Xamarin ControlTemplate Trigger applied to inner control within template

Coming from my original post, I was trying to create a custom control and build a control template for it much like in WPF, but it failed on triggers. I was provided a link that indicated that Control Templates are not allowed on all controls, but only certain ones via another Stack Overflow link provided by Raimo 关于我的另一个问题。

现在进入第 2 部分。我已将控件从“Entry”类型更改为“ContentView”类型,以便可以应用控件模板。所以这是唯一改变的地方

namespace MyAndroidApp
{
    public class MyTextboxEntry : ContentView
    {
        public MyTextboxEntry()
        {}

        public static readonly BindableProperty IsRequiredProperty
            = BindableProperty.Create(nameof(IsRequired), typeof(bool),
                typeof(MyTextboxEntry), false, BindingMode.TwoWay);
        public bool IsRequired
        {
            get { return (bool)GetValue(IsRequiredProperty); }
            set { SetValue(IsRequiredProperty, value); }
        }
    }
}

命名空间引用..

xmlns:myCtrls="clr-namespace:MyAndroidApp"

现在,转到控件模板。我实际上在控件中定义了多个部分,但为了简单的上下文在这里缩写了。

<ControlTemplate x:Key="CT_MyTextboxEntry" >
    <!-- Having a grid as an outer wrapper for multiple internal controls... -->
    <Grid HorizontalOptions="StartAndExpand" x:Name="UpdateThisGridControl" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150*" />
            <ColumnDefinition Width="50" />
            <ColumnDefinition Width="16" />
        </Grid.ColumnDefinitions>


        <Entry Text="Sample" Grid.Column="0"  />
        <Label Text="junk" Grid.Column="1" />
        <Image Source="Sample.jpg" Grid.Column="2" />

    <Grid.Triggers>
        <Trigger TargetType="myCtrls:MyTextboxEntry" Property="IsRequired" Value="True">
            <Setter Property="BackgroundColor" Value="Red"/>
        </Trigger>
    </Grid.Triggers>

    </Grid>
</ControlTemplate>

而页面中控件的最终实例要显示通过

<myCtrls:MyTextboxEntry ControlTemplate="{StaticResource CT_MyTextboxEntry}" />

所以,我的失败在 Grid.Triggers 部分。此处的目的是使用新条目控件(基于 ContentView)的可绑定 属性 以及“IsRequired”的正确 BindableProperty 声明,但要设置 GRID 的背景颜色。

在 WPF 中,您可以说在这里使用这个东西的触发器,但是在控件模板中更新这个其他控件,如“x:Name”引用所引用的那样,我将其作为“UpdateThisGridControl”就地使用。

如果我禁用 [Grid.Triggers] 部分,控件和模板将按预期显示。一旦我启用触发器,它就会失败

"bindable" not an instance of AssociatedType

但是,如果您考虑到条目 ContentView 具有背景色 属性 并且 Grid 控件也是如此,为什么在尝试通过触发器设置时它会阻塞。

如何从自定义控件为 属性 执行此类绑定以更新特定控件模板中的 属性?

如果您使用 Grid.Triggers,您应该像下面的代码一样在 Trigger 选项卡中设置 TargetType="Grid"

<ControlTemplate x:Key="CT_MyTextboxEntry" >

   <!-- Having a grid as an outer wrapper for multiple internal controls... -->
   <Grid HorizontalOptions="StartAndExpand" x:Name="UpdateThisGridControl" IsEnabled="True" >
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="150*" />
           <ColumnDefinition Width="50" />
           <ColumnDefinition Width="16" />
       </Grid.ColumnDefinitions>

       <Entry Text="Sample" Grid.Column="0"  />
       <Label Text="junk" Grid.Column="1" />
       <Image Source="Sample.jpg" Grid.Column="2" />

       <!-- For testing, I set the value of `Property` is `IsEnabled`, it worked as normal -->
       <Grid.Triggers>
           <Trigger TargetType="Grid" Property="IsEnabled" Value="True">
               <Setter Property="BackgroundColor" Value="Red"/>
           </Trigger>
       </Grid.Triggers>
   </Grid>
</ControlTemplate>

但是你想为Trigger设置TargetType="myCtrls:MyTextboxEntry",你可以尝试使用StylemyCtrls:MyTextboxEntry实现。

<ContentPage.Resources>

    <ResourceDictionary>
       <Style TargetType="myCtrls:MyTextboxEntry">
            <Style.Triggers>
                <Trigger TargetType="myCtrls:MyTextboxEntry"
                     Property="IsRequired" Value="True">
                    <Setter Property="BackgroundColor" Value="Red" />

                    <!-- Multiple setters elements are allowed -->
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>

    <ControlTemplate x:Key="CT_MyTextboxEntry" >
        <!-- Having a grid as an outer wrapper for multiple internal controls... -->
        <Grid HorizontalOptions="StartAndExpand" x:Name="UpdateThisGridControl"  >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150*" />
            <ColumnDefinition Width="50" />
            <ColumnDefinition Width="16" />
        </Grid.ColumnDefinitions>

        <Entry Text="Sample" Grid.Column="0"  />
        <Label Text="junk" Grid.Column="1" />
        <Image Source="Sample.jpg" Grid.Column="2" />

            <!-- <Grid.Triggers>
                <Trigger TargetType="Grid" Property="IsEnabled" Value="True">
                    <Setter Property="BackgroundColor" Value="Red"/>
                </Trigger>
            </Grid.Triggers> -->

        </Grid>
    </ControlTemplate>
</ContentPage.Resources>

<StackLayout>

    <myCtrls:MyTextboxEntry ControlTemplate="{StaticResource CT_MyTextboxEntry}" IsRequired="True" />

</StackLayout>

这是 运行 屏幕截图。