[C#/COMMON/.NET8] MemberNotNullWhenAttribute 클래스 : 해당 멤버 NOT NULL 보장하기
■ MemberNotNullWhenAttribute 클래스를 사용해 특정 멤버가 NOT NULL인 것을 보장하는 방법을 보여준다. ※ 조건부 not null 보장 : 특정 조건이 참일 때
■ MemberNotNullWhenAttribute 클래스를 사용해 특정 멤버가 NOT NULL인 것을 보장하는 방법을 보여준다. ※ 조건부 not null 보장 : 특정 조건이 참일 때
■ @field_validator 데코레이터를 사용해 커스텀 검증 논리를 추가하는 방법을 보여준다. ▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from pydantic import BaseModel from pydantic import Field from pydantic import field_validator class Joke(BaseModel): setup : str = Field(description = "question to set up a joke" ) punchline : str = Field(description = "answer to resolve the joke") # Pydantic을 사용하면 사용자 정의 검증 논리를 쉽게 추가할 수 있습니다. @field_validator("setup") def valiedateSetup(cls, field): if field[-1] != "?": raise ValueError("Badly formed question!") return field |
■ BaseModel 클래스를 사용해 모델 클래스를 만드는 방법을 보여준다. ※ langchain>=0.0.267부터 LangChain을 사용하면 사용자가 Pydantic V1 또는 V2를 설치할 수 있다. ※
■ Field 함수를 사용해 모델 클래스에서 필수/선택 항목을 설정하는 방법을 보여준다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
from typing import Optional from pydantic import BaseModel, Field class Student(BaseModel): id : str = Field(... , description = "ID" ) # 필수 항목 name : str = Field(... , description = "성명") # 필수 항목 weight : Optional[int] = Field(None, description = "체중") # 선택 항목 student = Student(id = "ID1", name = "홍길동") field1 = Field(... , description = "ID" ) print(type(field1)) print(student) """ id='ID1' name='홍길동' weight=None """ |
▶ requirements.txt
1 2 3 4 5 6 |
annotated-types==0.7.0 pydantic==2.7.4 pydantic_core==2.18.4 typing_extensions==4.12.2 |
※ pip install pydantic 명령을
■ pydantic 패키지를 설치하는 방법을 보여준다. 1. 명령 프롬프트를 실행한다. 2. 명령 프롬프트에서 아래 명령을 실행한다. ▶ 실행 명령
1 2 3 4 5 6 7 8 9 |
pip install pydantic pip install "pydantic[email]" pip install "pydantic[dotenv]" pip install "pydantic[email,dotenv]" |
■ BaseModel 클래스를 사용해 REST POST 요청 바디를 검증하는 방법을 보여준다. ▶ main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from fastapi import FastAPI, APIRouter from pydantic import BaseModel class TodoItem(BaseModel): id : int item : str todoItemList = [] apiRouter = APIRouter() @apiRouter.post("/todo") async def addTodoItem(todoItem : TodoItem) -> dict: todoItemList.append(todoItem) return {"message" : "Todo item added successfully"} @apiRouter.get("/todo") async def getTodoItemList() -> dict: return {"todoItemList" : todoItemList} fastAPI = FastAPI() @fastAPI.get("/") def root(): return {"message" : "Hello World"} @fastAPI.get("/home") def home(): return {"message" : "home"} fastAPI.include_router(apiRouter) |
▶ requirements.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
annotated-types==0.6.0 anyio==4.3.0 certifi==2024.2.2 click==8.1.7 dnspython==2.6.1 email_validator==2.1.1 exceptiongroup==1.2.1 fastapi==0.111.0 fastapi-cli==0.0.3 h11==0.14.0 httpcore==1.0.5 httptools==0.6.1 httpx==0.27.0 idna==3.7 itsdangerous==2.2.0 Jinja2==3.1.4 markdown-it-py==3.0.0 MarkupSafe==2.1.5 mdurl==0.1.2 orjson==3.10.3 pydantic==2.7.1 pydantic-extra-types==2.7.0 pydantic-settings==2.2.1 pydantic_core==2.18.2 Pygments==2.18.0 python-dotenv==1.0.1 python-multipart==0.0.9 PyYAML==6.0.1 rich==13.7.1 shellingham==1.5.4 sniffio==1.3.1 starlette==0.37.2 typer==0.12.3 typing_extensions==4.11.0 ujson==5.10.0 uvicorn==0.29.0 uvloop==0.19.0 watchfiles==0.21.0 websockets==12.0 |
▶ FastAPI 서버 실행 명령
■ ValidationRule 클래스를 사용해 바인딩 항목을 검증하는 방법을 보여준다. ▶ DateAndPriceRule.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using System; using System.Globalization; using System.Windows.Controls; using System.Windows.Data; namespace TestProject { /// <summary> /// 일자/가격 규칙 /// </summary> public class DateAndPriceRule : ValidationRule { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(value, cultureInfo) /// <summary> /// 검증하기 /// </summary> /// <param name="value">값</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>검증 결과</returns> public override ValidationResult Validate(object value, CultureInfo cultureInfo) { BindingGroup bindingGroup = value as BindingGroup; PurchaseItem item = bindingGroup?.Items[0] as PurchaseItem; object priceObject; object offerExpiresObject; bool priceResult = bindingGroup.TryGetValue(item, "Price" , out priceObject ); bool offerExpiresResult = bindingGroup.TryGetValue(item, "OfferExpires", out offerExpiresObject); if(!priceResult || !offerExpiresResult) { return new ValidationResult(false, "Properties not found"); } double price = (double)priceObject; DateTime offerExpires = (DateTime)offerExpiresObject; if(price > 100) { if(offerExpires < DateTime.Today + new TimeSpan(7, 0, 0, 0)) { return new ValidationResult(false, "Items over $100 must be available for at least 7 days."); } } return ValidationResult.ValidResult; } #endregion } } |
▶ FutureDateRule.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System; using System.Globalization; using System.Windows.Controls; namespace TestProject { /// <summary> /// 미래 일자 규칙 /// </summary> internal class FutureDateRule : ValidationRule { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(value, cultureInfo) /// <summary> /// 검증하기 /// </summary> /// <param name="value">값</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>검증 결과</returns> public override ValidationResult Validate(object value, CultureInfo cultureInfo) { DateTime date; try { date = DateTime.Parse(value?.ToString()); } catch(FormatException) { return new ValidationResult(false, "Value is not a valid date."); } return DateTime.Now.Date > date ? new ValidationResult(false, "Please enter a date in the future.") : ValidationResult.ValidResult; } #endregion } } |
▶ PositivePriceRule.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using System; using System.Globalization; using System.Windows.Controls; namespace TestProject { /// <summary> /// 양수 가격 규칙 /// </summary> public class PositivePriceRule : ValidationRule { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(value, cultureInfo) /// <summary> /// 검증하기 /// </summary> /// <param name="value">값</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>검증 결과</returns> public override ValidationResult Validate(object value, CultureInfo cultureInfo) { try { double price = Convert.ToDouble(value); if(price < 0) { return new ValidationResult(false, "Price must be positive."); } return ValidationResult.ValidResult; } catch(Exception) { return new ValidationResult(false, "Price must be a number."); } } #endregion } } |
▶ PurchaseItem.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
using System; using System.ComponentModel; namespace TestProject { /// <summary> /// 구매 항목 /// </summary> public class PurchaseItem : INotifyPropertyChanged, IEditableObject { //////////////////////////////////////////////////////////////////////////////////////////////////// Event ////////////////////////////////////////////////////////////////////////////////////////// Public #region 속성 변경시 - PropertyChanged /// <summary> /// 속성 변경시 /// </summary> public event PropertyChangedEventHandler PropertyChanged; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Struct ////////////////////////////////////////////////////////////////////////////////////////// Private #region 항목 데이터 - ItemData /// <summary> /// 항목 데이터 /// </summary> private struct ItemData { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Internal #region Field /// <summary> /// 설명 /// </summary> internal string Description; /// <summary> /// 제안 만기일 /// </summary> internal DateTime OfferExpires; /// <summary> /// 가격 /// </summary> internal double Price; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Internal #region 새 항목 구하기 - GetNewItem() /// <summary> /// 새 항목 구하기 /// </summary> /// <returns>새 항목</returns> internal static ItemData GetNewItem() { ItemData data = new ItemData { Description = "New item", Price = 0, OfferExpires = DateTime.Now + new TimeSpan(7, 0, 0, 0) }; return data; } #endregion } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 복사 데이터 /// </summary> private ItemData copyData = ItemData.GetNewItem(); /// <summary> /// 현대 데이터 /// </summary> private ItemData currentData = ItemData.GetNewItem(); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 설명 - Description /// <summary> /// 설명 /// </summary> public string Description { get { return this.currentData.Description; } set { if(this.currentData.Description != value) { this.currentData.Description = value; FirePropertyChangedEvent("Description"); } } } #endregion #region 가격 - Price /// <summary> /// 가격 /// </summary> public double Price { get { return this.currentData.Price; } set { if(this.currentData.Price != value) { this.currentData.Price = value; FirePropertyChangedEvent("Price"); } } } #endregion #region 제안 만기일 - OfferExpires /// <summary> /// 제안 만기일 /// </summary> public DateTime OfferExpires { get { return this.currentData.OfferExpires; } set { if(value != this.currentData.OfferExpires) { this.currentData.OfferExpires = value; FirePropertyChangedEvent("OfferExpires"); } } } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - PurchaseItem() /// <summary> /// 생성자 /// </summary> public PurchaseItem() { } #endregion #region 생성자 - PurchaseItem(description, price, offerExpires) /// <summary> /// 생성자 /// </summary> /// <param name="description">설명</param> /// <param name="price">가격</param> /// <param name="offerExpires">제안 만기일</param> public PurchaseItem(string description, double price, DateTime offerExpires) { Description = description; Price = price; OfferExpires = offerExpires; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 편집 시작하기 - BeginEdit() /// <summary> /// 편집 시작하기 /// </summary> public void BeginEdit() { this.copyData = this.currentData; } #endregion #region 편집 취소하기 - CancelEdit() /// <summary> /// 편집 취소하기 /// </summary> public void CancelEdit() { this.currentData = this.copyData; FirePropertyChangedEvent(""); } #endregion #region 편집 종료하기 - EndEdit() /// <summary> /// 편집 종료하기 /// </summary> public void EndEdit() { this.copyData = ItemData.GetNewItem(); } #endregion #region 문자열 구하기 - ToString() /// <summary> /// 문자열 구하기 /// </summary> /// <returns>문자열</returns> public override string ToString() => $"{Description}, {Price:c}, {OfferExpires:D}"; #endregion ////////////////////////////////////////////////////////////////////////////////////////// Protected #region 속성 변경시 이벤트 발생시키기 - FirePropertyChangedEvent(propertyName) /// <summary> /// 속성 변경시 이벤트 발생시키기 /// </summary> /// <param name="propertyName">속성명</param> private void FirePropertyChangedEvent(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion } } |
▶
■ IDataErrorInfo 인터페이스를 사용해 커스텀 객체에 대한 검증 로직을 구현하는 방법을 보여준다. ▶ Person.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
using System.ComponentModel; namespace TestProject { /// <summary> /// 사람 /// </summary> public class Person : IDataErrorInfo { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 나이 - Age /// <summary> /// 나이 /// </summary> public int Age { get; set; } #endregion #region 에러 - Error /// <summary> /// 에러 /// </summary> public string Error => null; #endregion #region 인덱서 - this[name] /// <summary> /// 인덱서 /// </summary> /// <param name="name">명칭</param> /// <returns>오류 메시지</returns> public string this[string name] { get { string result = null; if(name == "Age") { if(Age < 0 || Age > 150) { result = "Age must not be less than 0 or greater than 150."; } } return result; } } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestProject" Width="800" Height="600" Title="TestProject" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <local:Person x:Key="PersonKey" /> <Style x:Key="ErrorTextBoxStyleKey" TargetType="TextBox"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock>Enter your age :</TextBlock> <TextBox Style="{StaticResource ErrorTextBoxStyleKey}" HorizontalAlignment="Left" Margin="0 10 0 0" Width="100" Height="25" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Path="Age" Source="{StaticResource PersonKey}" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <DataErrorValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBlock Margin="0 10 0 0">Mouse-over to see the validation error message.</TextBlock> </StackPanel> </Window> |
TestProject.zip
■ 바인딩 유효성 검사를 구현하는 방법을 보여준다. ▶ SampleData.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
namespace TestProject { /// <summary> /// 샘플 데이터 /// </summary> public class SampleData { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 나이 1 - Age1 /// <summary> /// 나이 1 /// </summary> public int Age1 { get; set; } #endregion #region 나이 2 - Age2 /// <summary> /// 나이 2 /// </summary> public int Age2 { get; set; } #endregion #region 나이 3 - Age3 /// <summary> /// 나이 3 /// </summary> public int Age3 { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - SampleData() /// <summary> /// 생성자 /// </summary> public SampleData() { Age1 = 0; Age2 = 0; } #endregion } } |
▶ AgeRangeRule.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
using System; using System.Globalization; using System.Windows.Controls; namespace TestProject { /// <summary> /// 나이 범위 규칙 /// </summary> public class AgeRangeRule : ValidationRule { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 최소 - Minimum /// <summary> /// 최소 /// </summary> public int Minimum { get; set; } #endregion #region 최대 - Maximum /// <summary> /// 최대 /// </summary> public int Maximum { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(value, cultureInfo) /// <summary> /// 검증하기 /// </summary> /// <param name="value">값</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>검증 결과</returns> public override ValidationResult Validate(object value, CultureInfo cultureInfo) { int age = 0; try { if(((string)value).Length > 0) { age = int.Parse((string)value); } } catch(Exception exception) { return new ValidationResult(false, "Illegal characters or " + exception.Message); } if((age < Minimum) || (age > Maximum)) { return new ValidationResult(false, "Please enter an age in the range: " + Minimum + " - " + Maximum + "."); } return new ValidationResult(true, null); } #endregion } } |
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TestProject" Width="900" Height="600" Title="TestProject" FontFamily="나눔고딕코딩" FontSize="16"> <Window.Resources> <local:SampleData x:Key="SampleDataKey" /> <ControlTemplate x:Key="ValidationTemplateKey"> <DockPanel> <TextBlock Margin="0 5 0 0" Foreground="Red" FontWeight="Bold"> ! </TextBlock> <AdornedElementPlaceholder /> </DockPanel> </ControlTemplate> <Style x:Key="ErrorTextBoxStyleKey" TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="true"> <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Margin="10" FontSize="18" FontWeight="Bold" Text="Enter a number between 21-130 or there will be a validation error :" /> <StackPanel Orientation="Horizontal"> <Label Margin="20 0 0 0" Target="{Binding ElementName=textBox1}"> TextBox with _custom ErrorTemplate and ToolTip : </Label> <TextBox Name="textBox1" Style="{StaticResource ErrorTextBoxStyleKey}" Validation.ErrorTemplate="{StaticResource ValidationTemplateKey}" Margin="10 0 0 0" Width="50" Height="25" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Source="{StaticResource SampleDataKey}" Path="Age1" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:AgeRangeRule Minimum="21" Maximum="130" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> </StackPanel> <StackPanel Orientation="Horizontal"> <Label Margin="20 0 0 0" Target="{Binding ElementName=textBox2}"> TextBox with _default ErrorTemplate : </Label> <TextBox Name="textBox2" Grid.Row="3" Grid.Column="1" Margin="10 0 0 0" Width="50" Height="25" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Source="{StaticResource SampleDataKey}" Path="Age2" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <local:AgeRangeRule Minimum="21" Maximum="130" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> </StackPanel> <TextBlock Margin="10" FontSize="18" FontWeight="Bold" Text="The following TextBox uses the ExceptionValidationRule and UpdateSourceExceptionFilter handler :" /> <StackPanel Orientation="Horizontal"> <Label Margin="20 0 0 0" Target="{Binding ElementName=textBox3}"> TextBox with UpdateSourceExceptionFilter _handler : </Label> <TextBox Name="textBox3" Style="{StaticResource ErrorTextBoxStyleKey}" Margin="10 0 0 0" Width="50" Height="25" Validation.ErrorTemplate="{StaticResource ValidationTemplateKey}" VerticalContentAlignment="Center"> <TextBox.Text> <Binding Source="{StaticResource SampleDataKey}" Path="Age3" UpdateSourceTrigger="PropertyChanged"> <Binding.ValidationRules> <ExceptionValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <CheckBox Name="checkBox" VerticalAlignment="Center" Margin="10 0 0 0"> Enable Custom Handler (see ToolTip) </CheckBox> </StackPanel> </StackPanel> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Data; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); this.checkBox.Checked += checkBox_Checked; this.checkBox.Unchecked += checkBox_Unchecked; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region 체크 박스 체크시 처리하기 - checkBox_Checked(sender, e) /// <summary> /// 체크 박스 체크시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void checkBox_Checked(object sender, RoutedEventArgs e) { BindingExpression bindingExpression = this.textBox3.GetBindingExpression(TextBox.TextProperty); Binding parentBinding = bindingExpression.ParentBinding; parentBinding.UpdateSourceExceptionFilter = ReturnExceptionHandler; bindingExpression.UpdateSource(); } #endregion #region 체크 박스 체크 해제시 처리하기 - checkBox_Unchecked(sender, e) /// <summary> /// 체크 박스 체크 해제시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void checkBox_Unchecked(object sender, RoutedEventArgs e) { Binding binding = BindingOperations.GetBinding(this.textBox3, TextBox.TextProperty); binding.UpdateSourceExceptionFilter -= ReturnExceptionHandler; BindingExpression bindingExpression = BindingOperations.GetBindingExpression(this.textBox3, TextBox.TextProperty); bindingExpression.UpdateSource(); } #endregion //////////////////////////////////////////////////////////////////////////////// Function #region 예외 반환 핸들러 - ReturnExceptionHandler(bindingExpression, exception) /// <summary> /// 예외 반환 핸들러 /// </summary> /// <param name="bindingExpression">바인딩 표현식</param> /// <param name="exception">예외</param> /// <returns>처리 결과</returns> private object ReturnExceptionHandler(object bindingExpression, Exception exception) => "This is from the UpdateSourceExceptionFilterCallBack."; #endregion } } |
TestProject.zip
■ ValidationRule 클래스를 사용해 현재 날짜보다 미래 날짜 여부를 검증하는 방법을 보여준다. ▶ 예제 코드 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System; using System.Globalization; using System.Windows.Controls; /// <summary> /// 미래 날짜 규칙 /// </summary> public class FutureDateRule : ValidationRule { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(value, cultureInfo) /// <summary> /// 검증하기 /// </summary> /// <param name="value">값</param> /// <param name="cultureInfo">문화 정보</param> /// <returns>검증 결과</returns> public override ValidationResult Validate(object value, CultureInfo cultureInfo) { DateTime date; try { date = DateTime.Parse(value.ToString()); } catch(FormatException) { return new ValidationResult(false, "Value is not a valid date. Please enter a valid date"); } if(DateTime.Now.Date > date) { return new ValidationResult(false, "Value is not a future date. Please enter a date in the future."); } return ValidationResult.ValidResult; } #endregion } |
■ IValidatableObject 인터페이스의 Validate 메소드를 사용해 객체를 검증하는 방법을 보여준다. ▶ Student.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
using System.ComponentModel.DataAnnotations; namespace TestProject; /// <summary> /// 학생 /// </summary> public class Student : IValidatableObject { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 이용 가능 여부 - Enabled /// <summary> /// 이용 가능 여부 /// </summary> [Required] public bool Enabled { get; set; } #endregion #region 등급 1 - Grade1 /// <summary> /// 등급 1 /// </summary> [Range(1, 5)] public int Grade1 { get; set; } #endregion #region 등급 2 - Grade2 /// <summary> /// 등급 2 /// </summary> [Range(1, 5)] public int Grade2 { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Public #region 검증하기 - Validate(context) /// <summary> /// 검증하기 /// </summary> /// <param name="context">검증 컨텍스트</param> /// <returns>검증 결과 열거 가능형</returns> public IEnumerable<ValidationResult> Validate(ValidationContext context) { List<ValidationResult> validationResultList = new List<ValidationResult>(); if(Enabled) { Validator.TryValidateProperty ( Grade1, new ValidationContext(this, null, null) { MemberName = "Grade1" }, validationResultList ); Validator.TryValidateProperty ( Grade2, new ValidationContext(this, null, null) { MemberName = "Grade2" }, validationResultList ); if(Grade1 > Grade2) { validationResultList.Add(new ValidationResult("Grade1은 Grade2보다 커야 합니다.")); } } return validationResultList; } #endregion } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
using System.ComponentModel.DataAnnotations; namespace TestProject; /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { Student student = new Student() { Enabled = true, Grade1 = 15, Grade2 = 12 }; bool validateAllProperties = false; List<ValidationResult> validationResultList = new List<ValidationResult>(); bool isValid = Validator.TryValidateObject ( student, new ValidationContext(student, null, null), validationResultList, validateAllProperties ); if(!isValid) { foreach(ValidationResult validationResult in validationResultList) { Console.WriteLine(validationResult); } } } #endregion } |
TestProject.zip
■ UriValidationBehavior 클래스에서 사용자 입력 URI를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Entry x:Name="entry" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="URI를 입력해 주시기 바랍니다." /> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
using CommunityToolkit.Maui.Behaviors; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); Style validStyle = new Style(typeof(Entry)); validStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Green }); Style invalidStyle = new Style(typeof(Entry)); invalidStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Red }); UriValidationBehavior behavior = new UriValidationBehavior { ValidStyle = validStyle, InvalidStyle = invalidStyle, Flags = ValidationFlags.ValidateOnValueChanged, UriKind = UriKind.Absolute }; this.entry.Behaviors.Add(behavior); } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ UriValidationBehavior 엘리먼트에서 사용자 입력 URI를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <ContentPage.Resources> <Style x:Key="ValidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Green" /> </Style> <Style x:Key="InvalidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Red" /> </Style> </ContentPage.Resources> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="URI를 입력해 주시기 바랍니다."> <Entry.Behaviors> <toolkit:UriValidationBehavior ValidStyle="{StaticResource ValidEntryStyleKey}" InvalidStyle="{StaticResource InvalidEntryStyleKey}" Flags="ValidateOnValueChanged" UriKind="Absolute" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ TextValidationBehavior 엘리먼트의 MinimumLength/MaximumLength 속성을 사용해 사용자 입력 문자열 길이를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <ContentPage.Resources> <Style x:Key="ValidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Green" /> </Style> <Style x:Key="InvalidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Red" /> </Style> </ContentPage.Resources> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="값을 입력해 주시기 바랍니다."> <Entry.Behaviors> <toolkit:TextValidationBehavior ValidStyle="{StaticResource ValidEntryStyleKey}" InvalidStyle="{StaticResource InvalidEntryStyleKey}" Flags="ValidateOnValueChanged" MinimumLength="1" MaximumLength="10" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ RequiredStringValidationBehavior 클래스를 사용해 사용자의 특정 텍스트 입력 여부를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Entry x:Name="entry" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="값을 입력해 주시기 바랍니다." /> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using CommunityToolkit.Maui.Behaviors; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); Style validStyle = new Style(typeof(Entry)); validStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Green } ); Style invalidStyle = new Style(typeof(Entry)); invalidStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Red }); RequiredStringValidationBehavior behavior = new RequiredStringValidationBehavior { ValidStyle = validStyle, InvalidStyle = invalidStyle, Flags = ValidationFlags.ValidateOnValueChanged, RequiredString = "MAGIC ANSWER" }; this.entry.Behaviors.Add(behavior); } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ RequiredStringValidationBehavior 엘리먼트를 사용해 사용자의 특정 텍스트 입력 여부를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <ContentPage.Resources> <Style x:Key="ValidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Green" /> </Style> <Style x:Key="InvalidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Red" /> </Style> </ContentPage.Resources> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="값을 입력해 주시기 바랍니다."> <Entry.Behaviors> <toolkit:RequiredStringValidationBehavior ValidStyle="{StaticResource ValidEntryStyleKey}" InvalidStyle="{StaticResource InvalidEntryStyleKey}" Flags="ValidateOnValueChanged" RequiredString="MAGIC ANSWER" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ NumericValidationBehavior 클래스를 사용해 사용자 입력 숫자를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Entry x:Name="entry" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Keyboard="Numeric" Placeholder="값을 입력해 주시기 바랍니다." /> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using CommunityToolkit.Maui.Behaviors; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); Style validStyle = new Style(typeof(Entry)); validStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Green }); Style invalidStyle = new Style(typeof(Entry)); invalidStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Red }); NumericValidationBehavior behavior = new NumericValidationBehavior { ValidStyle = validStyle, InvalidStyle = invalidStyle, Flags = ValidationFlags.ValidateOnValueChanged, MinimumValue = 1.0, MaximumValue = 100.0, MaximumDecimalPlaces = 2 }; this.entry.Behaviors.Add(behavior); } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ NumericValidationBehavior 엘리먼트를 사용해 사용자 입력 숫자를 검증하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <ContentPage.Resources> <Style x:Key="ValidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Green" /> </Style> <Style x:Key="InvalidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Red" /> </Style> </ContentPage.Resources> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Keyboard="Numeric" Placeholder="값을 입력해 주시기 바랍니다."> <Entry.Behaviors> <toolkit:NumericValidationBehavior ValidStyle="{StaticResource ValidEntryStyleKey}" InvalidStyle="{StaticResource InvalidEntryStyleKey}" Flags="ValidateOnValueChanged" MinimumValue="1.0" MaximumValue="100.0" MaximumDecimalPlaces="2" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ MultiValidationBehavior 클래스를 사용해 복수 무결성 검사기를 사용하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Entry x:Name="entry" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" IsPassword="True" Placeholder="Password" /> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
using CommunityToolkit.Maui.Behaviors; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); Style validStyle = new Style(typeof(Entry)); validStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Green }); Style invalidStyle = new Style(typeof(Entry)); invalidStyle.Setters.Add(new Setter { Property = Entry.TextColorProperty, Value = Colors.Red }); CharactersValidationBehavior bahavior1 = new CharactersValidationBehavior { CharacterType = CharacterType.Digit, MinimumCharacterTypeCount = 1, Flags = ValidationFlags.ValidateOnValueChanged }; MultiValidationBehavior.SetError(bahavior1, "숫자 최소 1문자"); CharactersValidationBehavior behavior2 = new CharactersValidationBehavior { CharacterType = CharacterType.UppercaseLetter, MinimumCharacterTypeCount = 1, Flags = ValidationFlags.ValidateOnValueChanged }; MultiValidationBehavior.SetError(behavior2, "대문자 최소 1문자"); CharactersValidationBehavior behavior3 = new CharactersValidationBehavior { CharacterType = CharacterType.NonAlphanumericSymbol, MinimumCharacterTypeCount = 1, Flags = ValidationFlags.ValidateOnValueChanged }; MultiValidationBehavior.SetError(behavior3, "기호 최소 1문자"); CharactersValidationBehavior behavior4 = new CharactersValidationBehavior { CharacterType = CharacterType.Any, MinimumCharacterTypeCount = 1, Flags = ValidationFlags.ValidateOnValueChanged }; MultiValidationBehavior.SetError(behavior4, "최소 8문자"); MultiValidationBehavior multipleBehavior = new MultiValidationBehavior { InvalidStyle = invalidStyle, ValidStyle = validStyle, Flags = ValidationFlags.ValidateOnValueChanged, Children = { bahavior1, behavior2, behavior3, behavior4 } }; this.entry.Behaviors.Add(multipleBehavior); } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ MultiValidationBehavior 엘리먼트를 사용해 복수 무결성 검사기를 사용하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <ContentPage.Resources> <Style x:Key="InvalidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Red" /> </Style> <Style x:Key="ValidEntryStyleKey" TargetType="Entry"> <Setter Property="TextColor" Value="Green" /> </Style> </ContentPage.Resources> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" IsPassword="True" Placeholder="Password"> <Entry.Behaviors> <toolkit:MultiValidationBehavior ValidStyle="{StaticResource ValidEntryStyleKey}" InvalidStyle="{StaticResource InvalidEntryStyleKey}" Flags="ValidateOnValueChanged"> <toolkit:CharactersValidationBehavior CharacterType="Digit" MinimumCharacterTypeCount="1" toolkit:MultiValidationBehavior.Error="숫자 최소 1문자" /> <toolkit:CharactersValidationBehavior CharacterType="UppercaseLetter" MinimumCharacterTypeCount="1" toolkit:MultiValidationBehavior.Error="대문자 최소 1문자" /> <toolkit:CharactersValidationBehavior CharacterType="NonAlphanumericSymbol" MinimumCharacterTypeCount="1" toolkit:MultiValidationBehavior.Error="기호 최소 1문자" /> <toolkit:CharactersValidationBehavior CharacterType="Any" MinimumCharacterTypeCount="8" toolkit:MultiValidationBehavior.Error="최소 8문자" /> </toolkit:MultiValidationBehavior> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
TestProject.zip
■ MaxLengthReachedBehavior 클래스의 Command 속성을 사용해 사용자가 최대 길이 입력시 처리하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Entry x:Name="entry" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" MaxLength="20" Placeholder="최대 길이로 입력할 때가 타이핑을 해주시기 바랍니다." /> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
using System.Windows.Input; using CommunityToolkit.Maui.Behaviors; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 최대 길이 도달시 명령 - MaximumLengthReachedCommand /// <summary> /// 최대 길이 도달시 명령 /// </summary> public ICommand MaximumLengthReachedCommand { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); MaximumLengthReachedCommand = new Command ( execute : async () => { await DisplayAlert("INFORMATION", "최대 길이까지 입력했습니다.", "확인"); } ); MaxLengthReachedBehavior behavior = new MaxLengthReachedBehavior(); behavior.SetBinding ( MaxLengthReachedBehavior.CommandProperty, new Binding(nameof(MaximumLengthReachedCommand)) ); this.entry.Behaviors.Add(behavior); BindingContext = this; } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
■ MaxLengthReachedBehavior 엘리먼트의 Command 속성을 사용해 사용자가 최대 길이 입력시 처리하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" MaxLength="20" Placeholder="최대 길이로 입력할 때가 타이핑을 해주시기 바랍니다."> <Entry.Behaviors> <toolkit:MaxLengthReachedBehavior Command="{Binding MaximumLengthReachedCommand}" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
using System.Windows.Input; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Property ////////////////////////////////////////////////////////////////////////////////////////// Public #region 최대 길이 도달시 명령 - MaximumLengthReachedCommand /// <summary> /// 최대 길이 도달시 명령 /// </summary> public ICommand MaximumLengthReachedCommand { get; set; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); MaximumLengthReachedCommand = new Command ( execute : async () => { await DisplayAlert("INFORMATION", "최대 길이까지 입력했습니다.", "확인"); } ); BindingContext = this; } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
■ MaskedBehavior 클래스의 Mask 속성을 사용해 사용자 입력 마스크를 설정하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Entry x:Name="entry" HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="계좌 번호를 입력해 주시기 바랍니다." Keyboard="Numeric" /> </ContentPage> |
▶ MainPage.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
using CommunityToolkit.Maui.Behaviors; namespace TestProject; /// <summary> /// 메인 페이지 /// </summary> public partial class MainPage : ContentPage { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainPage() /// <summary> /// 생성자 /// </summary> public MainPage() { InitializeComponent(); MaskedBehavior behavior = new MaskedBehavior { Mask = "XXXX XXXX XXXX XXXX" }; this.entry.Behaviors.Add(behavior); } #endregion } |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
※
■ MaskedBehavior 엘리먼트의 UnmaskedCharacter 속성을 사용해 사용자 지정 프롬프트 문자를 설정하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="계좌 번호를 입력해 주시기 바랍니다." Keyboard="Numeric"> <Entry.Behaviors> <toolkit:MaskedBehavior Mask="0000X0000X0000X0000" UnmaskedCharacter="0" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
※ 프리뷰 버전
■ MaskedBehavior 엘리먼트의 Mask 속성을 사용해 사용자 입력 마스크를 설정하는 방법을 보여준다. ▶ MainPage.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage x:Class="TestProject.MainPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"> <Entry HorizontalOptions="Center" VerticalOptions="Center" BackgroundColor="Yellow" Placeholder="계좌 번호를 입력해 주시기 바랍니다." Keyboard="Numeric"> <Entry.Behaviors> <toolkit:MaskedBehavior Mask="XXXX XXXX XXXX XXXX" /> </Entry.Behaviors> </Entry> </ContentPage> |
▶ MauiProgram.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
using CommunityToolkit.Maui; namespace TestProject; /// <summary> /// MAUI 프로그램 /// </summary> public static class MauiProgram { //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region MAUI 앱 생성하기 - CreateMauiApp() /// <summary> /// MAUI 앱 생성하기 /// </summary> /// <returns>MAUI 앱</returns> public static MauiApp CreateMauiApp() { MauiAppBuilder builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .UseMauiCommunityToolkit() .ConfigureFonts ( fontCollection => { fontCollection.AddFont("OpenSans-Regular.ttf" , "OpenSansRegular" ); fontCollection.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); } ); return builder.Build(); } #endregion } |
※ 프리뷰 버전 테스트시,