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 格式異常