0

我正在为可以验证的条目创建自定义控件。

我通过创建一个 ContentView 来做到这一点,该 ContentView 有一个 Grid 作为它的子项,其中包含条目、错误标签等。

我希望这在验证方面具有灵活性,因此理想情况下,最好公开条目的 MultiValidationBehavior 的 Children 属性,或者将该属性设置为我的控件的内容属性。

就目前而言,我还没有想出一种方法来向我的自定义控件添加行为。

这可能吗?

<ContentView x:Class="MPK.UI.Views.Components.FormEntry"
             x:Name="FormEntryControl"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
             xmlns:yummy="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
             xmlns:converters="clr-namespace:MPK.UI.Converters;assembly=MPK.UI">

    <ContentView.Resources>
        <ResourceDictionary>
            <converters:IsValidToEntryBorderConverter x:Key="IsValidToEntryBorderConverter"/>
            <converters:ErrorsToLabelTextConverter x:Key="ErrorsToLabelTextConverter"/>
            <xct:InvertedBoolConverter x:Key="InvertedBoolConverter" />
        </ResourceDictionary>
        
        
    </ContentView.Resources>
    <Grid>
        <yummy:PancakeView CornerRadius="10"
                           HeightRequest="50"
                           HorizontalOptions="FillAndExpand"
                           BackgroundColor="{StaticResource EntryBackgroundColor}"
                           Padding="16,0,16,0">
            <yummy:PancakeView.Behaviors>
                <xct:AnimationBehavior AnimateCommand="{Binding Source={x:Reference FormEntryControl}, Path=ShakeCommand}">
                    <xct:AnimationBehavior.AnimationType>
                        <xct:ShakeAnimation />
                    </xct:AnimationBehavior.AnimationType>
                </xct:AnimationBehavior>
            </yummy:PancakeView.Behaviors>
            <yummy:PancakeView.Border>
                <yummy:Border
                    Color="{Binding IsValid, Source={x:Reference MultiValidationBehavior}, Converter={StaticResource IsValidToEntryBorderConverter}}"
                    Thickness="1" />
            </yummy:PancakeView.Border>
            <Entry x:Name="Entry"
                   Text="{Binding Text, Source={x:Reference FormEntryControl}}"
                   Placeholder="{Binding Placeholder, Source={x:Reference FormEntryControl}}"
                   ReturnType="{Binding ReturnType, Source={x:Reference FormEntryControl}}"
                   ReturnCommand="{Binding ReturnCommand, Source={x:Reference FormEntryControl}}"
                   PlaceholderColor="{StaticResource EntryPlaceholderTextColor}"
                   BackgroundColor="Transparent"
                   IsPassword="{Binding IsPassword, Source={x:Reference FormEntryControl}}"
                   ClearButtonVisibility="{Binding ClearButtonVisibility, Source={x:Reference FormEntryControl}}">
                <Entry.Effects>
                    <xct:RemoveBorderEffect />
                </Entry.Effects>
                <Entry.Behaviors>
                    <xct:MultiValidationBehavior x:Name="MultiValidationBehavior" 
                                                 IsValid="{Binding IsValid, Source={x:Reference FormEntryControl}, Mode=TwoWay}"
                                                 Children="{Binding ValidationBehaviors, Source={x:Reference FormEntryControl}}"/>
                    <!-- Binding children doesn't work here -->
                </Entry.Behaviors>
            </Entry>
        </yummy:PancakeView>
        <xct:Expander Margin="8,4,0,0"
                      AnimationLength="100"
                      IsExpanded="{Binding IsValid, Source={x:Reference FormEntryControl}, Mode=OneWay, Converter={StaticResource InvertedBoolConverter}}">
            <Label Text="{Binding Errors, Source={x:Reference MultiValidationBehavior}, Converter={StaticResource ErrorsToLabelTextConverter}}"
                   TextColor="{StaticResource ErrorColor}" />
        </xct:Expander>
    </Grid>
</ContentView>
4

1 回答 1

1

解决方案比我预期的要简单得多。

在我的控件背后的代码中,我需要添加一个指向 multivalidationbehavior 子属性的属性。

public IList<ValidationBehavior> ValidationBehaviors => TheMultiValidationBehavior.Children;

使用我的自定义控件看起来像这样:

            <components:FormEntry Placeholder="Name">
                <components:FormEntry.ValidationBehaviors>
                    <xct:TextValidationBehavior MinimumLength="1" xct:MultiValidationBehavior.Error="Min: 1"/>
                </components:FormEntry.ValidationBehaviors>
            </components:FormEntry>
    
于 2021-12-05T01:01:45.583 回答