第二十三章:触发器和行为(十)

简介: 响应水龙头切换视图的各种表现形式演示了一种响应XAML文件中的点击的方法。 如果将tap事件集成到VisualElement类中,您可以使用EventTrigger更直接且更轻松地获取它们。 但是您无法将EventTrigger附加到TapGestureRecognizer。

响应水龙头
切换视图的各种表现形式演示了一种响应XAML文件中的点击的方法。 如果将tap事件集成到VisualElement类中,您可以使用EventTrigger更直接且更轻松地获取它们。 但是您无法将EventTrigger附加到TapGestureRecognizer。
解决这个小限制是一种专门用于点击的行为的目的。 这叫做TapBehavior:

namespace Xamarin.FormsBook.Toolkit
{
    public class TapBehavior : Behavior<View>
    {
        TapGestureRecognizer tapGesture;
        static readonly BindablePropertyKey IsTriggeredKey =
            BindableProperty.CreateReadOnly("IsTriggered", typeof(bool),
                                            typeof(TapBehavior), false);
        public static readonly BindableProperty IsTriggeredProperty =
                                            IsTriggeredKey.BindableProperty;
        public bool IsTriggered
        {
            private set { SetValue(IsTriggeredKey, value); }
            get { return (bool)GetValue(IsTriggeredProperty); }
        }
        protected override void OnAttachedTo(View view)
        {
            base.OnAttachedTo(view);
            tapGesture = new TapGestureRecognizer();
            tapGesture.Tapped += OnTapped;
            view.GestureRecognizers.Add(tapGesture);
        }
        protected override void OnDetachingFrom(View view)
        {
            base.OnDetachingFrom(view);
            view.GestureRecognizers.Remove(tapGesture);
            tapGesture.Tapped -= OnTapped;
        }
        async void OnTapped(object sender, EventArgs args)
        {
            IsTriggered = true;
            await Task.Delay(100);
            IsTriggered = false;
        }
    }
}

TapBehavior类定义了一个名为IsTriggered的布尔属性,但它的功能与普通属性完全不同。首先,它由只读可绑定属性支持。这意味着
IsTriggered属性只能在TapBehavior类中设置,并且当IsTriggered属性在十分之一秒内变为true时,类设置IsTriggered的唯一时间是TapGestureRecognizer的事件处理程序。
换句话说,Tapped事件被转换为属性值的非常短暂的峰值 - 这让人想起事件是如何在数字硬件中触发的。但IsTriggered属性可以
然后在DataTrigger中引用。
假设您喜欢ShiverButton的想法,但是您希望将概念应用于除Button之外的其他内容,这意味着您需要响应Tapped事件。您可以使用EventTrigger,但TapBehavior允许您使用DataTrigger。
为了演示,这里是BoxViewTapShiver,它将TapBehavior对象附加到三个Box View元素,每个元素还包括一个DataTrigger,它引用行为并在其EnterActions集合中调用ShiverAction:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit=
                 "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
             x:Class="BoxViewTapShiver.BoxViewTapShiverPage">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="BoxView">
                <Setter Property="WidthRequest" Value="200" />
                <Setter Property="HeightRequest" Value="50" />
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>
        <BoxView Color="Red">
            <BoxView.Behaviors>
                <toolkit:TapBehavior x:Name="tapBehavior1" />
            </BoxView.Behaviors>
            <BoxView.Triggers>
                <DataTrigger TargetType="BoxView"
                             Binding="{Binding Source={x:Reference tapBehavior1},
                                               Path=IsTriggered}"
                             Value="True">
                    <DataTrigger.EnterActions>
                        <toolkit:ShiverAction />
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </BoxView.Triggers>
        </BoxView>
        <BoxView Color="Green">
            <BoxView.Behaviors>
                <toolkit:TapBehavior x:Name="tapBehavior2" />
            </BoxView.Behaviors>
            <BoxView.Triggers>
                <DataTrigger TargetType="BoxView"
                             Binding="{Binding Source={x:Reference tapBehavior2},
                                               Path=IsTriggered}"
                             Value="True">
                    <DataTrigger.EnterActions>
                        <toolkit:ShiverAction />
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </BoxView.Triggers>
        </BoxView>
        <BoxView Color="Blue">
            <BoxView.Behaviors>
                <toolkit:TapBehavior x:Name="tapBehavior3" />
            </BoxView.Behaviors>
            <BoxView.Triggers>
                <DataTrigger TargetType="BoxView"
                             Binding="{Binding Source={x:Reference tapBehavior3},
                                               Path=IsTriggered}"
                             Value="True">
                    <DataTrigger.EnterActions>
                        <toolkit:ShiverAction />
                    </DataTrigger.EnterActions>
                </DataTrigger>
            </BoxView.Triggers>
        </BoxView>
    </StackLayout>
</ContentPage>

三个TapBehavior对象中的每一个都具有唯一的名称,该名称由相应的DataTrigger引用。 当您点击BoxView时,它会颤抖,并且它们都可以独立工作。
将TapBehavior和DataTrigger对象放在样式中以减少重复标记是非常诱人的,但这不起作用。 这将导致在三个BoxView元素之间共享一个TapBehavior。 此外,每个DataTrigger按名称引用相应的TapBehavior。
如果你想在这种情况下减少标记,你将再次需要定义一个新类。 ShiverViews程序演示了这一点。 它首先定义一个名为ShiverView的类,它派生自BoxView并添加TapBehavior和DataTrigger:

<BoxView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit=
                 "clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
             x:Class="ShiverViews.ShiverView">

    <BoxView.Behaviors>
        <toolkit:TapBehavior x:Name="tapBehavior" />
    </BoxView.Behaviors>
    <BoxView.Triggers>
        <DataTrigger TargetType="BoxView"
                     Binding="{Binding Source={x:Reference tapBehavior},
                                       Path=IsTriggered}"
                     Value="True">
            <DataTrigger.EnterActions>
                <toolkit:ShiverAction />
            </DataTrigger.EnterActions>
        </DataTrigger>
    </BoxView.Triggers>
</BoxView>

与SwitchClone类一样,您也可以在代码隐藏文件中添加一些属性,并在XAML文件中引用它们。
然后,ShiverViewsPage XAML文件可以使用隐式样式实例化三个独立的ShiverView对象:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ShiverViews"
             x:Class="ShiverViews.ShiverViewsPage">
    <StackLayout>
        <StackLayout.Resources>
            <ResourceDictionary>
                <Style TargetType="local:ShiverView">
                    <Setter Property="WidthRequest" Value="200" />
                    <Setter Property="HeightRequest" Value="50" />
                    <Setter Property="HorizontalOptions" Value="Center" />
                    <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                </Style>
            </ResourceDictionary>
        </StackLayout.Resources>

        <local:ShiverView Color="Red" />
        <local:ShiverView Color="Green" />
        <local:ShiverView Color="Blue" />
    </StackLayout>
</ContentPage>
目录
相关文章
|
JavaScript Android开发
第二十三章:触发器和行为(十二)
淡化和定向在本书中,您已经看到了几个颜色选择程序,可以通过使用三个Slider元素以交互方式形成颜色。 本章的最后一个示例是另一个颜色选择程序,但是这个程序为您提供了选项:它包含三个标记为“RGB Hex”,“RGB Float”和“HSL”的单选按钮(实际上是简单的Label元素)。
707 0
|
JavaScript Android开发
第二十三章:触发器和行为(七)
行为 触发器和行为通常是串联讨论的,因为它们具有一些应用重叠。 有时候你会感到困惑是否使用触发器或行为,因为似乎要么这样做工作。你可以用触发器做任何事情,你也可以做一个行为。 但是,行为总是涉及一些代码,这是一个派生自Behavior 的类。
948 0
|
JavaScript Android开发
第二十三章:触发器和行为(十一)
单选按钮内置于旧汽车仪表板中的无线电通常具有一排六个(左右)按钮,可以为各种无线电台“编程”。 按下其中一个按钮会导致无线电跳转到该预选电台,并且还会弹出前一个选择按钮。那些旧的汽车收音机现在是古董,但我们的电脑屏幕上的互斥选项仍然由我们称为单选按钮的视觉对象表示。
908 0
|
JavaScript Android开发 Windows
第二十三章:触发器和行为(九)
切换和复选框在第15章“交互式界面”和第16章“数据绑定”中,您了解了如何构造传统的CheckBox视图。 但是,自定义视图的另一种方法是将视图的交互逻辑合并到行为中,然后完全在XAML中实现视觉效果。
728 0
|
Android开发
第二十三章:触发器和行为(八)
具有属性的行为Behavior 类派生自Behavior类,该类派生自BindableObject。这表明您的Behavior 派生可以定义自己的可绑定属性。之前你看过一些Action 衍生产品,比如ScaleAction和ShiverAction,它们定义了一些属性以赋予它们更大的灵活性。
649 0
|
JavaScript Android开发
第二十三章:触发器和行为(六)
MultiTrigger中的组合条件Trigger和DataTrigger都有效地监视属性以确定它是否等于特定值。 这称为触发器的条件,如果条件为真,则调用Setter对象的集合。作为程序员,您可能会开始怀疑是否可以在触发器中具有多个条件。
650 0
|
JavaScript Android开发 iOS开发
第二十三章:触发器和行为(五)
数据触发器到目前为止,您只看到在特定对象的上下文中运行的触发器。 触发器通过更改同一对象的另一个属性或通过调用影响该对象的Action来响应对象属性的更改。 EventTrigger同样响应一个对象触发的事件,以在同一个对象上调用Action。
933 0
|
JavaScript Android开发 Windows
第二十三章:触发器和行为(四)
更多事件触发器前一章关于动画的章节展示了一个按钮,它在点击时旋转或缩放。 虽然大多数动画示例都是为了制作有趣的演示而采取极端措施,但是按钮用一点动画来响应点击并不是不合理的。 这是EventTrigger的完美工作。
777 0
|
JavaScript Android开发
第二十三章:触发器和行为(三)
触发动作和动画虽然某些触发器可以完全在XAML中实现,但其他触发器需要一些代码支持。 如您所知,Xamarin.Forms没有直接支持在XAML中实现动画,因此如果您想使用触发器为元素设置动画,则需要一些代码。
1015 0
|
JavaScript Android开发
第二十三章:触发器和行为(二)
触发器 在最普遍(和最模糊)的意义上,触发器是导致响应的条件。 更具体地说,触发器通过设置另一个属性或运行一些代码来响应属性更改或触发事件。 几乎总是,设置的属性或运行的代码涉及用户界面,并在XAML中表示。
972 0