星期三, 9月 09, 2020

[X.Form] Entry - BorderColor

Entry 搭配 Frame 來讓 Entry 具有 BorderColor 效果,利用 Email 驗證來練習,輸入 Email 格式不正確,BorderColor 就要用紅色表示

Xaml Layout 設計
<?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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:vw="clr-namespace:EntryDemo.ViewModels"
             mc:Ignorable="d"
             x:Class="EntryDemo.EntryBorderColor">

    <ContentPage.BindingContext>
        <vw:EntryBorderColorViewModel/>
    </ContentPage.BindingContext>

    <ContentPage.Content>
        <Grid Margin="20,20,20,20" ColumnDefinitions="1*,3*" RowDefinitions="100,100">
            <Label Grid.Row="0" Grid.Column="0" Text="請輸入 Email" FontSize="Large" VerticalOptions="CenterAndExpand"/>
            <Frame Grid.Row="0" Grid.Column="1" BorderColor="{Binding EmailBoardColor, Mode=TwoWay}" CornerRadius="10">
                <Entry FontSize="Large" Text="{Binding Email, Mode=TwoWay}"/>
            </Frame>
            <Label Grid.Row="1" Grid.Column="1" Text="{Binding EmailErrorMessage}" FontSize="Large" TextColor="Red" HorizontalOptions="End"/>
        </Grid>
    </ContentPage.Content>
</ContentPage>
ViewModel.cs 內容
using System.ComponentModel;
using System.Drawing;
using EntryDemo.Extension;

namespace EntryDemo.ViewModels
{
    public class EntryBorderColorViewModel : INotifyPropertyChanged
    {
        #region Email 相關

        private readonly Color entryBoardDefaultColor = Color.Transparent;

        public EntryBorderColorViewModel()
        {
            EmailBoardColor = entryBoardDefaultColor;
        }

        private string _email;
        public string Email
        {
            get { return _email; }
            set
            {

                bool isValidEmail = value.IsValidEmail(out string errorMessage);
                if (isValidEmail)
                {
                    EmailBoardColor = entryBoardDefaultColor;
                    EmailErrorMessage = string.Empty;
                }
                else
                {
                    EmailBoardColor = Color.Red;
                    EmailErrorMessage = errorMessage;
                }

                _email = value;
                OnPropertyChanged(nameof(this.Email));
            }
        }

        private Color _emailBoardColor;
        public Color EmailBoardColor
        {
            get { return _emailBoardColor; }
            set
            {
                _emailBoardColor = value;
                OnPropertyChanged(nameof(this.EmailBoardColor));
            }
        }

        private string _emailErrorMessage;
        public string EmailErrorMessage
        {
            get { return _emailErrorMessage; }
            set
            {
                _emailErrorMessage = value;
                OnPropertyChanged(nameof(this.EmailErrorMessage));
            }
        }
        #endregion

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}
Email 驗證
using System;
using System.Text.RegularExpressions;

namespace EntryDemo.Extension
{
    public static class StringExtension
    {
        /// <summary>
        /// 確認字串是否為有效的電子郵件格式
        /// </summary>
        /// <param name="email">Email</param>
        /// <returns>是否為有效的電子郵件格式</returns>
        public static bool IsValidEmail(this string value, out string errorMessage)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                errorMessage = $"{nameof(IsValidEmail)} 參數為 null 或空值,無法判斷 Email 格式";
                return false;
            }

            try
            {
                // 規則運算式只會驗證最上層網域名稱是否包含介於 2 到 24 個英數 ASCII 字元,且第一個和最後一個為英數字元,而其餘字元為英數字元或連字號 (-)。
                bool valid = Regex.IsMatch(value,
                    @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                    @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
                    RegexOptions.IgnoreCase,
                    TimeSpan.FromMilliseconds(250));

                errorMessage = valid ? string.Empty : "Email 格式不正確";
                return valid;
            }
            catch (RegexMatchTimeoutException)
            {
                errorMessage = $"{nameof(IsValidEmail)} 判斷 Email 格式 timeout";
                return false;
            }
        }
    }
}
Email 格式異常
 
[X.Form] Entry - BorderColor-1

Email 格式正確

[X.Form] Entry - BorderColor-2

沒有留言:

張貼留言