Xamarin Trigger (一) DataTrigger 用Style的方式

  • 303
  • 0
  • 2017-01-30

DataTrigger

DataTrigger的用途:  綁定另一個control的屬性,使得當另一control的屬性變動時 trigger自己的屬性也發生變動

課堂上的做法是三個Label 各自綁定Trigger,這篇文章稍做改良,用style 提升到resource裡面,另外用了xamarin 內建的Device.StartTimer 來處理計時器 

ViewModel也稍做簡化 , 對於這篇的觀念個人在學習上會比較集中在xaml 的data binding 上

以下是透過switch 的IsToggle屬性綁定ViewModel的IsActive ,若IsActive有變動時則啟動或關閉計時器

Label 內設定一個DataTrigger ,當ViewModel內的IsActive有變動時,畫面的Label皆變動屬性BackgroundColor 與TextColor

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:Local="clr-namespace:DifferenceUI;assembly:DifferenceUI"
             x:Class="DifferenceUI.DataTriggerPage"
             >
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="Label">
                <Setter Property="FontSize" Value="Large"></Setter>
                <Setter Property="HorizontalOptions" Value="FillAndExpand"></Setter>
                <Setter Property="VerticalOptions" Value="FillAndExpand"></Setter>
                <Setter Property="HorizontalTextAlignment" Value="Center"></Setter>
                <Setter Property="VerticalTextAlignment" Value="Center"></Setter>
                <Setter Property="TextColor" Value="White"></Setter>
                <Setter Property="BackgroundColor" Value="Black"></Setter>
                <Style.Triggers>
                    <!-- 來源是IsActive 若是false or true要設定BackGroundColor-->
                    <DataTrigger TargetType="Label" Binding="{Binding IsActive}" Value="false">
                        <Setter Property="BackgroundColor" Value="Gray"></Setter>
                        <Setter Property="TextColor" Value="Yellow"></Setter>
                    </DataTrigger>
                    <DataTrigger TargetType="Label" Binding="{Binding IsActive}" Value="true">
                        <Setter Property="BackgroundColor" Value="Black"></Setter>
                        <Setter Property="TextColor" Value="Pink"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"></RowDefinition>
            <RowDefinition Height="1*"></RowDefinition>
            <RowDefinition Height="1*"></RowDefinition>
            <RowDefinition Height="2*"></RowDefinition>
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Text="{Binding TimeString}"></Label>
        <Label Grid.Row="1" Text="{Binding TimeString}"></Label>
        <Label Grid.Row="2" Text="{Binding TimeString}"></Label>
        <Switch Grid.Row="3" IsToggled="{Binding IsActive}" HorizontalOptions="CenterAndExpand" 
                VerticalOptions="StartAndExpand"></Switch>
    </Grid>
</ContentPage>

這裡使用xamarin.form 內建的Device.StartTimer(timespan,Func<bool>)的方法

timespan指的是interval

啟動Timer 則在func 中 return true

關閉Timer 則 return false

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace DifferenceUI
{
    public partial class DataTriggerPage : ContentPage
    {
        public DataTriggerPage()
        {
            InitializeComponent();

            DataTriggerViewModel vm = new DataTriggerViewModel()
            {
                IsActive = true,
                TimeString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            };

            this.BindingContext = vm;

        }
    }

    public class DataTriggerViewModel : INotifyPropertyChanged
    {
        private String _name;
        public String Name
        {
            set
            {
                OnPropertyChanged("Name");
                _name = value;
            }
            get
            {

                return _name;
            }
        }
        private String _timeString;
        public String TimeString
        {
            set
            {
                _timeString = value;
                OnPropertyChanged("TimeString");

            }
            get
            {
                return _timeString;
            }
        }

        private bool _isActive;

        public bool IsActive
        {
            set
            {
                _isActive = value;
                StartTime();
                OnPropertyChanged("IsActive");

            }
            get
            {
                return _isActive;
            }
        }


        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void StartTime()
        {
            Device.StartTimer(TimeSpan.FromSeconds(1), () =>
            {

                if (this._isActive)
                {
                    this.TimeString = String.Format("{0}", TimeString = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    return true;
                }
                else
                    return false;
            });
        }

        public DataTriggerViewModel()
        {

        }


        public event PropertyChangedEventHandler PropertyChanged;
    }

}