x:Bind ๋ฐ Binding์์ ์ง์ํ๋ INotifyDataErrorInfo๋ก ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ ์ง์์ ์ถ๊ฐํฉ๋๋ค. ๋ ๋งํฌ์ ํ์ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก WPF์ ๋ฐ์ธ๋ฉ์์์ ๊ฐ์ด true์ธ ์ ValidatesOnNotifyDataErrors ์์ฑ์ ๊ฐ์ ธ์์ผ ํฉ๋๋ค.
ํ์ฌ UWP์๋ ํ๋ซํผ์ ๋ด์ฅ๋ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ LOB(Line of Business) ์ฑ์๋ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ํ์ํฉ๋๋ค. ์ ์ ํ ์ํฐํ๋ผ์ด์ฆ ์ฑ์ ์ํ ๊ฐ์ฅ ์ค์ํ ๊ธฐ๋ฅ ์ค ํ๋์ ๋๋ค. ์ด ๊ธฐ๋ฅ์ด WinUI์ ํจ๊ป ์ ๊ณต๋๋ค๋ uservoice ํญ๋ชฉ์ด ์์ง๋ง ์์ง ๋ณธ ์ ์ด ์์ต๋๋ค. https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/13052589-uwp-input -ํ์ธ
@LucasHaines ์ด๊ฒ์ด ๋น์ ์ด ์กฐ์ฌํ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ ๊ธฐ๋ฅ๊ณผ ์ด๋ค ๊ด๋ จ์ด ์์ต๋๊น?
@jevansaks ์ด๊ฒ์ ๋ด๊ฐ ์ค๋ช ํ๋ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ ์์ ๊ณผ ์ง์ ๊ด๋ จ์ด ์์ต๋๋ค.
์์ฒญ๋. ๊ณต์ ํ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ํญ๋ชฉ์ด ์์ผ๋ฉด ๊ธฐ๊บผ์ด ์ฌ์ฉํด ๋ณด๊ณ ํผ๋๋ฐฑ๊ณผ ์๊ฐ์ ์ ๊ณตํ๊ฒ ์ต๋๋ค.
์ด๊ฒ์ Build 2018์์ ์ธ๊ธ๋ ์ผ์ข ์ ์ ํจ์ฑ ๊ฒ์ฌ์ ๋๋ค.
`
Text="{x:๋ฐ์ธ๋ ViewModel.Person.UserName,
UpdateSourceTrigger=์์ฑ ๋ณ๊ฒฝ,
๋ชจ๋=์๋ฐฉํฅ}" />
Password="{x: ViewModel.Person.Password ๋ฐ์ธ๋ฉ,
UpdateSourceTrigger=๋ก์คํธํฌ์ปค์ค,
๋ชจ๋=์๋ฐฉํฅ}"/>
`
@thomasclaudiushuber {Binding}์ ์ผ๋ถ๋ก ์ด ์์ ์ ์ํํ๋ ๊ฒ์ด ์ผ๋ง๋ ์ค์ํ๋ค๊ณ ์๊ฐํ์ญ๋๊น? ๊ธฐ์ ์ ์ธ ๋ฌธ์ ๊ฐ ์ฌ์ํ์ง ์๊ณ ํ์ ์์ค์์ ์๋ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฌป์ต๋๋ค. ์ฐ๋ฆฌ์ ์๋ ์์ด๋์ด๋ ๋งํฌ์ ์ปดํ์ผ๋ฌ ๋ณ๊ฒฝ๋ง ํ์ํ๊ณ ํ์ ์์ค์์ ์๋ํ ์ ์๋ x:Bind๋ฅผ ์ง์ํ๋ ๊ฒ์ด์์ต๋๋ค.
๋ํ INotifyDataErrorInfo ๋ฐ DataAnnotations ํจ๋ฌ๋ค์๋ง ์ง์ํ ๊ณํ์ด์์ต๋๋ค. ์ฐ๋ฆฌ๋ Binding.ValidationRules์ ์ ์ฌํ ๊ฒ์ ์ถ๊ฐํ ์๋๊ฐ ์์์ผ๋ฏ๋ก ValidatesOnNotifyDataErrors์ ๋ํ ์ถฉ๋ถํ ํ์์ฑ์ ๋๋ผ์ง ๋ชปํ์ต๋๋ค.
์ด ๊ธฐ๋ฅ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์ํ๋ ์ ์๋๋ก ๊ณ์ ์์ ํ๋ฉด์ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ์ถ์ต๋๋ค!
@stevenbrix
์งง์ ๋๋ต: ์, ๋น์ ์ด ์๊ฐํ๋ ๊ฒ๊ณผ ๊ณํํ ๊ฒ์ด ํ๋ฅญํ๊ฒ ๋ค๋ฆฝ๋๋ค. x:Bind๋ง ๊ด์ฐฎ๊ณ INotifyDataErrorInfo๋ ๊ด์ฐฎ์ต๋๋ค.
๊ธด:
๋ชจ๋ WPF-LOB์ ๊ฒฝ์ฐ์๋ ํญ์ ์ปดํ์ผ ํ์์ ์๋ ค์ง ์ผ์ข ์ ViewModel์ด ์๋ค๊ณ ์๊ฐํ ์ ์์ผ๋ฉฐ ์ค๋ฆฌ ํ์ดํ์ด ์์ผ๋ฏ๋ก x:Bind๊ฐ ์ข์ต๋๋ค. WPF์์์ ๋์ผํ ๊ตฌ๋ฌธ์ ์ป์ ์ ์๋๋ก ์ง์ํ ์ ์๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ์์๋ {Binding}์ ์์ฑํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋งค์ฐ ์ค์ํ ๊ฒ๋ณด๋ค "์์ผ๋ฉด ์ข์" ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ {Binding}๊ณผ x:Bind๋ ์ด๋ฉด์์ ์์ ํ ๋ค๋ฅธ ๋ ๊ฐ์ง์ด๊ณ {Binding}์ด ํฌํจ๋ ๋ฐํ์ ํญ๋ชฉ์ ์ธ๊ธํ ๊ฒ์ฒ๋ผ ์ค์ํ์ง ์์ผ๋ฏ๋ก {Binding}์ ์์ด๋ฒ๋ฆฌ์ธ์. x:Bind์ฉ์ผ๋ก๋ง ์ฌ์ฉํ๋ ๊ฒ์ ๊ด์ฐฎ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ด๊ฐ ์๊ฐํ ์ ์๋ ์ฌ์ฉ ์ฌ๋ก์์ ์๋ํ ๊ฒ์ ๋๋ค. UWP ๋ฐ x:Bind์ ๋ํ ๋ชจ๋ ํ์์์ x:Bind๋ ๋ชจ๋ XAML ๊ฐ๋ฐ์๊ฐ ๊ฐ์ฅ ์ข์ํ๋ UWP ๊ธฐ๋ฅ ์ค ํ๋์ด๋ฉฐ "์ด๋์์๋ ๋ฐ์ธ๋ฉ๋ณด๋ค x:Bind๋ฅผ ์ ํธํฉ๋๋ค. ํ ์์๋ค". :) Intellisense, perf, step-into-code ๋ฐ compile-time ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด UWP์์ x:Bind๊ฐ ์ ๊ธฐ๋ณธ๊ฐ์ด ๋๋ฏ๋ก ์ ํจ์ฑ ๊ฒ์ฌ ์ง์์ ๊ฑฐ๊ธฐ์ ๋๋ ๊ฒ์ด ์ข๊ณ ์ข์ ๊ฒฐ์ ์ ๋๋ค.
INotifyDataErrorInfo ๋ฐ DataAnnotations ํจ๋ฌ๋ค์์ ์ง์ํ๋ ๊ฒ๋ง์ผ๋ก๋ ๊ธฐ๋ถ์ด ์ข์ต๋๋ค. WPF๋ ๋ฐ์ดํฐ ์ฃผ์์ ์๋์ผ๋ก ์ ํํ์ง ์์ผ๋ฏ๋ก Validator ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ INotifyDataErrorInfo ๊ตฌํ์์ ์๋์ผ๋ก ์ฐ๊ฒฐํด์ผ ํฉ๋๋ค. "DataAnnotations ํจ๋ฌ๋ค์"์ด๋ผ๊ณ ํ ๋ ์ด๊ฒ์ ์๋ฏธํฉ๋๊น? ์๋๋ฉด ๊ฐ๋ฐ์๊ฐ ์์ฑ์ ๋ฐ์ดํฐ ์ฃผ์์ ๋ฃ์ ์ ์๋๋ก ํ๋ ๊ธฐ๋ณธ ์ ๊ณต DataAnnotation ์ง์์ ๊ณํํ๊ณ ์์ต๋๊น? ASP.NET Core MVC์์์ฒ๋ผ? ๊ทธ๊ฒ ์ข๊ฒ ์ง๋ง ํ์ํ์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ValidationContext, Validator ๋ฐ ValidationResult ํด๋์ค์ System.ComponentModel.DataAnnotations์ ๋ค๋ฅธ ํด๋์ค๊ฐ ์์ผ๋ฉด ์ถฉ๋ถํฉ๋๋ค.
์๋์, ํ์คํ ์ถ๊ฐํ์ง ๋ง์ญ์์ค. INotifyDataErrorInfo๋ ์ถฉ๋ถํ๊ณ ์ต๊ณ ์ ๋๋ค. IDataErrorInfo ์ง์์ด WPF์ ์ถ๊ฐ๋ ํ ๋ ์ด์ ValidationRules๋ฅผ ์ฌ์ฉํ์ง ์์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ INotifyDataErrorInfo๊ฐ .NET Framework 4.5์ ์ถ๊ฐ๋์์ ๋ ์ ์ ์ ๊ณ ๊ฐ์ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํด ๋ชจ๋ ํ๋ก์ ํธ์์ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ์ด ์ธํฐํ์ด์ค๋ง ์ง์ํด๋ ๊ด์ฐฎ์ต๋๋ค.
์, ์ด๊ฒ์ ์ถ๊ฐํ ํ์๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌ๋ Binding.ValidationRules์ ์๋ฌด ๊ด๋ จ์ด ์์ต๋๋ค. ์ด ์์ฑ์ INotifyDataErrorInfo ์ธํฐํ์ด์ค์ ์ง์ ๊ด๋ จ์ด ์์ต๋๋ค. WPF์ ๋ฐ์ธ๋ฉ ๋งํฌ์ ํ์ฅ์์ ValidatesOnNotifyDataErrors๋ ๊ธฐ๋ณธ์ ์ผ๋ก true์ ๋๋ค. ์ฆ, ๋ฐ์ธ๋ฉ๋ ๊ฐ์ฒด๊ฐ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๊ฒฝ์ฐ {Binding}์ด ๊ตฌํ๋ INotifyDataErrorInfo ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ ํํฉ๋๋ค. Binding ํ๊ทธ ํ์ฅ์ ValidatesOnNotifyDataErrors ์์ฑ์ false๋ก ์ค์ ํ๋ฉด Binding ํ๊ทธ ํ์ฅ์ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํด INotifyDataErrorInfo ๊ตฌํ์ ์ ํํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ x:Bind๋ก ๊ตฌํํ๋ ๊ฒ์ด ๊ทธ๋ฆฌ ์ด๋ ต์ง ์์ ์๋ ์์ง๋ง ํ์ํ์ง ์์ ์๋ ์์ต๋๋ค. ๊ทธ๋ฌ๋, ํ์ง๋ง. ์ด๊ฑด ๋นผ๋ ๊ด์ฐฎ์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ณผ๊ฑฐ์ ์ด๊ฒ์ด ํ์ํ๋ ์๋๋ฆฌ์ค๋ฅผ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
WPF ์ปจํธ๋กค์ ๊ธฐ๋ณธ์ ์ผ๋ก Validation.ErrorTemplate์ ํตํด ์ ์๋ ๋นจ๊ฐ์ ํ ๋๋ฆฌ๋ฅผ ํ์ํฉ๋๋ค. ์ด์ FirstName ์์ฑ์ด ์๋ ํด๋์ค๋ก INotifyDataErrorInfo ๊ตฌํ์ด ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. ํ์์ด๋ฏ๋ก FirstName ์์ฑ์ด null์ด๊ฑฐ๋ ๋น์ด ์์ผ๋ฉด ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค. ์ด์ TextBox๋ฅผ ํด๋น FirstName ์์ฑ์ ๋ฐ์ธ๋ฉํ์ต๋๋ค. ์ฌ์ฉ์๊ฐ ํด๋น ์ด๋ฆ์ ์ ๊ฑฐํ๋ฉด ๋นจ๊ฐ์ ํ ๋๋ฆฌ๊ฐ ๋ํ๋ฉ๋๋ค. ํ๋ฅญํฉ๋๋ค. ์ ํํ ๋น์ ์ด ์ํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ UI์ ๋ค๋ฅธ ์์น์ FirstName ์์ฑ์๋ ๋ฐ์ธ๋ฉ๋ ๋ค๋ฅธ ์ปจํธ๋กค์ด ์์ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํญ ํค๋์ TextBlock. WPF๋ ์ ํจ์ฑ ๊ฒ์ฌ ์ค๋ฅ๊ฐ ์๋ ๊ฒฝ์ฐ ํด๋น TextBlock์ ๋นจ๊ฐ์ ํ ๋๋ฆฌ์๋ ํ์๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋น์ ์ด ์ํ๋ ๊ฒ์ด ์๋ ์๋ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ ์ด๋ฆ์ ๋ณ๊ฒฝํ ์ ์๋ TextBox์์๋ง ์ค๋ฅ๋ฅผ ์ํ์ง๋ง Tab ํค๋์ TextBlock์์๋ ๊ทธ๋ ์ง ์์ต๋๋ค. TextBlock์ ๋นจ๊ฐ์ ํ ๋๋ฆฌ๋ฅผ ์ ๊ฑฐํ๋ ค๋ฉด TextBlock์ ErrorTemplate์ ํธ์งํ ํ์๊ฐ ์์ต๋๋ค. ๋์ ValidatesOnNotifyDataErrors ์์ฑ์ false๋ก ์ค์ ํ์ฌ TextBlock-FirstName-Binding์ ๋ํ INotifyDataErrorInfo ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ค์ ํ๋ฉด ๋ฉ๋๋ค. ์ด๊ฒ์ด ๋ด๊ฐ ์ด ์์ฑ์ ๋ํด ๊ฐ์ง ์ ์ผํ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. :)
์ด๊ฒ ๋์์ด ๋๊ธธ ๋ฐ๋๋ค.
์, ์ ์ ์ผ๋ก ๋์ํฉ๋๋ค. INotifyDataErrorInfo๋ฅผ ์ง์ํ๋ x:Bind์์๋ง ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๋ ๊ฒ์ด ์ข์ ๊ณํ์ ๋๋ค.
์๋์, ํ์์ ์ธ ๊ณํ์ ๋๋ค. ๋ฒ์จ๋ถํฐ ๋งค์ฐ ๊ธฐ๋๋ฉ๋๋ค!
@thomasclaudiushuber ์์ธํ ํ์ ์กฐ์น์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค! ๋น์ ์ด ์ค๋ช ํ๋ ํต์ฌ ์๋๋ฆฌ์ค๋ ์ฐ๋ฆฌ๊ฐ ์ง์ ํ ๊ฐ์น ๋์ธ์ด๋ผ๊ณ ๋ฏฟ๋ ๊ฒ๊ณผ ๋ผ์ธ์ ์ ๊ตฌ์ฑํ๋ฏ๋ก ์ข์ ์์์ ๋๋ค. ์ด ๊ธฐ๋ฅ๊ณผ API์ ์ ์ฒด ๋์์ธ์ ๋๋ถ๋ถ WPF๊ฐ ์ํํ ์ด์ ์์ ์ผ๋ก ์ธํด ์ ๋์ ์ด์์ต๋๋ค. ์ฌ๊ธฐ์ ๋ช ๊ฐ์ง ์ค์ํ ์ฌํญ์ด ์์์ต๋๋ค.
์์์ ๋ ผ์ํ ๋ฐ์ ๊ฐ์ด WPF์ ์ ํจ์ฑ ๊ฒ์ฌ ์์คํ ์๋ ๊ฐ์น๊ฐ ์ถ๊ฐ๋์ง ์์๊ฑฐ๋ ๋ ๋์ ํจํด์ผ๋ก ๋์ฒด๋ ํน์ ์ธก๋ฉด์ด ์์๊ธฐ ๋๋ฌธ์ UWP๋ก ๊ฐ์ ธ์ฌ ๊ณํ์ด ์์์ต๋๋ค.
WPF ์ ํจ์ฑ ๊ฒ์ฌ ์์คํ ์ ํน์ ๊ธฐ๋ฅ์ UWP์ ์๋ ํต์ฌ WPF ๊ธฐ๋ฅ์ ํ์ฉํฉ๋๋ค. ๊ฐ์ฅ ์ฃผ๋ชฉํ ๋งํ ๊ฒ์ WPF์ ๋ชจ๋ UIElement๊ฐ ์ปจํธ๋กค(์ผ๋ถ ํ ํ๋ฆฟ ๋ถ๋ถ ์ถ๊ฐ๋ฅผ ํตํด)๋ฟ๋ง ์๋๋ผ ์ ํจ์ฑ ๊ฒ์ฌ ์๊ฐ์ ๊ฐ์ฒด๋ฅผ ํ์ํ ์ ์๋๋ก ํ๋ ํ์๊ธฐ ๋ ์ด์ด์ ๋๋ค.
UWP Xaml์๋ ํ์ฌ ์ฐ๊ฒฐ๋ ์ด๋ฒคํธ์ ๊ฐ๋ ์ด ์์ผ๋ฉฐ Validation ํด๋์ค๋ฅผ ๋ฏธ๋ฌ๋งํ๋ฉด Validation.Error ์ด๋ฒคํธ๊ฐ ์ถ๊ฐ๋ฉ๋๋ค. ๊ทธ๊ฒ์ ๊ฑฐ๋ ์ฐจ๋จ๊ธฐ๊ฐ ์๋๋ผ ๋ณต์ก์ฑ์ ๊ฐ์ค์ํค๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ผ๋ก ์๋ก์ด ๊ฐ๋ ์ ์ถ๊ฐํ๋ ๊ฒ์ ์กฐ์ฌํ๊ธฐ ๋๋ฌธ์ ์ธ๊ธํ ์ฌํญ์ ๋๋ค. ๋ํ ์์ ์๋ ์ปจํธ๋กค์ ํ ํ๋ฆฟ์ ๋ณ๊ฒฝํด์ผ ํ๋ฏ๋ก ํน์ ํ ํ๋ฆฟ ๋ณ๊ฒฝ์ ์ ๊ณตํ๋ ์ปจํธ๋กค ์งํฉ๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋งํด์ ์๋ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ผ๋ถ ์๋๋ฆฌ์ค์์๋ ์๋ํ์ง ์๋ API๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ข์ ์ต๊ด์ด ์๋๋ฏ๋ก ํด๋น ๋ชจ๋ธ์์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ๋ ๋ซ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์ด๋ ์ปจํธ๋กค์ด ๊ตฌํํ๋ ๊ณตํต ์ธํฐํ์ด์ค ๋ฐ/๋๋ ์์ฑ๊ณผ ๊ฐ์ ๋ค๋ฅธ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์ฐ๋ฆฌ๋ ์ฌ์ ํ ์๋กญ๊ณ ํฅ๋ฏธ๋ก์ด ์คํ ์์ค ์ธ๊ณ์์ API ๋ฐ ์ฌ์ ๊ฒํ ๋ฅผ ์ํํ๋ ๋ฐฉ๋ฒ์ ์ดํดํ๋ ๊ณผ์ ์ ์์ต๋๋ค. ์ปค๋ฎค๋ํฐ์ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ์ถ๊ธฐ ๋๋ฌธ์ ๊ณง API ์ ์์ ๋ฐ์ ์ปค๋ฎค๋ํฐ๊ฐ ์ดํด๋ณด๊ณ ๋ชจ๋๊ฐ ์ด๊ดํ๋ ๊ฒ์ ๋ง๋ค ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค!
@stevenbrix ์ ํจ์ฑ ๊ฒ์ฌ ๊ธฐ๋ฅ์ ๋ํ ์คํ ์์ค ์ฌ์์ ์์ํ ๋ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์ด๋ป๊ฒ ๋ณด์ด๋์ง์ ๋ํ ์ผ๋ฌ์คํธ๋ ์ด์ ๊ณผ ์ํ ์๋๋ฆฌ์ค๋ฅผ ์ ๊ณตํ์ฌ ๋ํ๊ฐ UI ์ธก๋ฉด์ ๋ํด ์ข ๋ ๊ด๋ฒ์ํ ์ ์๋๋ก ํ์๊ฒ ์ต๋๊น? , ์ฝ๋ฉ๋ณด๋ค :)
@mdtauk ๋ฌผ๋ก ์ ๋๋ค. ์ฐ๋ฆฌ๊ฐ ๊ณต์ ํ ํ์ฌ UI๋ ์ฌ์ ํ ์ ํํฉ๋๋ค. ํผ๋๋ฐฑ์ด ์๋ ๊ฒฝ์ฐ ์ด ์ค๋ ๋์ ์์ ๋กญ๊ฒ ์ ๊ณตํ์ญ์์ค.
@LucasHaines UI๊ฐ ์ข์ ๋ณด์ ๋๋ค. ๊ทธ๋ฌ๋ ์ค๋ฅ๊ฐ ํ์๋๋ ๋ฐฉ์์ ์ด๋ป๊ฒ ์กฐ์ ํ ์ ์๋์ง ๊ถ๊ธํฉ๋๋ค. ๋๋ ์ด๊ฒ์ ๊ดํด ์๋ฌด ๊ฒ๋ ์ฐพ์ง ๋ชปํ๊ณ ๋น์ ์ด ์ด๋ฏธ ๊ทธ ๋ถ์ผ์์ ๊ณต์ ํ ๊ฒ์ด ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. WPF์์ ์ฒจ๋ถ๋ Validation.ErrorTemplate ์์ฑ๊ณผ ์ ์ฌํ ๊ฒ์ด ์์ต๋๊น?
์ด์ ๋ํ ๊ณต์์ ์ธ ์ฌ์/์ ์์ด ์ธ์ ๋ฐํ๋ ๊ฒ์ธ์ง์ ๋ํ ์ผ์ ์ด ์์ต๋๊น?
์ ํ์ ๋ ๋นจ๋ฆฌ ์ ์ฉํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
์์ @mrlacey ์ ๋์ํฉ๋๋ค... ์ด์ ์ด๊ฒ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก ๊ฐ๋ฅํ ํ ๋์์ ๋๋ฆฌ๊ฒ ๋์ด ๊ธฐ์ฉ๋๋ค.
์ฐ๋ฆฌ๋ ๊ณต๊ฐ ์ฌ์์ ์์ ์ค์ด๋ฉฐ ์ฌ์ ๋ฆฌํฌ์งํ ๋ฆฌ์์ ์ฌ์ฉํ ์ ์์์ ๋ชจ๋ ์ฌ๋์๊ฒ ์๋ฆด ๊ฒ์ ๋๋ค.
์ง๋ฌธ: IDataErrorInfo๋ ์ง์ํ์ง ์๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? .net ํ์ค์์ ์ง์๋๋๋ฐ, ์ง์ํ์ง ์๋ ๊ฒ์ด ์ด์ํ์ง ์์๊น์? ์ด๊ฒ์ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ ์ธํฐํ์ด์ค๋ฅผ ์ปดํ์ผ ํ์์ ํ์ธํ ์ ์๊ธฐ ๋๋ฌธ์ ์ฌ์ฉํ์ง ์๋ ์ฌ๋๋ค์ ์ฑ๋ฅ์ ์ํฅ์ ๋ฏธ์น์ง ์์์ผ ํฉ๋๋ค.
๊ณต๊ฐ ์ฌ์ ๋ฆฌํฌ์งํ ๋ฆฌ์์ ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ์ ๋ํ ๊ณต๊ฐ ์ฌ์ ๊ฒํ ๋ฅผ ์์ํ์ต๋๋ค. https://github.com/Microsoft/microsoft-ui-xaml-specs/pull/26
์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ, ์ฐ๋ฆฌ๋ ์ด๊ฒ์ ์ด๋ป๊ฒ ์ถ์ ํ๊ณ ์์ต๋๊น? ETA๊ฐ ์์ต๋๊น?
@knightmeister ์ฌ๊ธฐ์ ๊ณต๊ฐ ์ฌ์์ด ์์ฑ ๋์์ต๋๋ค . ๊ฒํ ์ ์ฐธ์ฌํ๊ณ ๊ธฐ๋ฅ์ ํ์ฑํ๋ ๋ฐ ๋์์ ์ฃผ์ธ์. ์ฐ๋ฆฌ๋ ์ด๊ฒ์ WinUI 3.0์ ์ผ๋ถ๋ก ์ ๊ณตํ ๊ณํ์ ๋๋ค. WinUI 3.0 ๋ก๋๋งต์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ฌธ์ #717์ ํ์ธํ์ญ์์ค.
์๋ ํ์ธ์ ์ฌ๋ฌ๋ถ - ์ฌ์์ ์ต์ ์ํ์ ์ดํด๋ณด์ญ์์ค. @stevenbrix ๋ ์ํ์ ๋ํ ๋ช ๊ฐ์ง ํ๋ฅญํ ์ ๋ฐ์ดํธ๋ฅผ ์ํํ๊ณ ๋ค๋ฅธ ํผ๋๋ฐฑ์ ์ฒ๋ฆฌํ์ต๋๋ค.
ํ ๊ฐ์ง ์ง๋ฌธ: ์ ํจ์ฑ ๊ฒ์ฌ ์ ๋ณด๊ฐ ์ ์ด ๊ณ์ธต์ผ๋ก ํ๋ฅผ๊น์? ์๋ฅผ ๋ค์ด ์ปจํ ์ด๋ ์ปจํธ๋กค(์: TabView ๋๋ Pivot)์ด ์๋ชป๋ ์ํ์ ์์ ์ปจํธ๋กค์ด ์์์ ์ ์ ์์ต๋๊น?
์๋ฅผ ๋ค์ด ์์ ์ปจํธ๋กค์ด ์๋ชป๋ ์ํ์ ์์ ๋ Pivot ํค๋์ ์คํ์ผ์ ๋ณ๊ฒฝํ์ฌ ๋ทฐ์ ์ด๋ ๋ถ๋ถ์ ์ฃผ์๊ฐ ํ์ํ์ง ๊ฐ์กฐ ํ์ํ๋ ค๋ ์ฌ๋ฌ ์ปจํ ์ด๋ ์ปจํธ๋กค์ด ์๋ ๋ณต์กํ ๋ทฐ๋ฅผ ์๊ฐํด ๋ณด์ญ์์ค.
์ด๊ฒ์ ๋์๊ฒ ์ค์ํ ๋ฌธ์ ์
๋๋ค.
๋ด ์ ์ฒด XAML ์ ํจ์ฑ ๊ฒ์ฌ ์์คํ
์ WPF ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ BindingExpression
์์ ํ๋์ ์ํฐํฐ ๋ชจ๋ธ์ ์ฝ๊ณ DA ์ ํจ์ฑ ๊ฒ์ฌ ํน์ฑ์ ๋ฐ๋ผ ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น์ ๋ง๋ญ๋๋ค( this ์ฐธ์กฐ).
์๋ฅผ ๋ค์ด ์ปจํ ์ด๋ ์ปจํธ๋กค(์: TabView ๋๋ Pivot)์ด ์๋ชป๋ ์ํ์ ์์ ์ปจํธ๋กค์ด ์์์ ์ ์ ์์ต๋๊น?
@tbolon ์, ์ํํ ์ ์๋ ์์
์ด์ง๋ง ํด๋น ์ปจํ
์ด๋์ ๋ด์ฅ๋ ์ง์์ด ์์ ๊ฐ๋ฅ์ฑ์ ๊ฑฐ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ด ๊ธฐ๋ฅ์ด ๋ด์ฅ๋ Form
์ปจํธ๋กค์ ๋ง๋๋ ๊ฒ์ ๋ํด ์๊ฐํด ๋ณด์์ง๋ง ํ์ฌ๋ก์๋ ์๋ง๋ ๋ฐฑ๋ก๊ทธ์ ์์ ๊ฒ์
๋๋ค. WPF์ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ฐ ์ปจํธ๋กค์ด ์ ํจํ์ง ์๊ฑฐ๋ ์ ํจํ์ง ์์ ๋ ๋ฐ์ํ๋ ValidationError
(์ด๋ฆ์ด ํ๋ฆด ์ ์์) ์ด๋ฒคํธ๊ฐ ์์ต๋๋ค. ์ด ์ด๋ฒคํธ๋ ๋ผ์ฐํธ๋ ์ด๋ฒคํธ๊ฐ ์๋๋ฏ๋ก ๋ฃ๊ณ ์ถ์ ๊ฐ ์์๋ฅผ ๊ตฌ๋
ํด์ผ ํฉ๋๋ค.
๋ด ์ ์ฒด XAML ์ ํจ์ฑ ๊ฒ์ฌ ์์คํ ์ WPF ์ ํจ์ฑ ๊ฒ์ฌ ๊ท์น์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
@weitzhandler ํ์ฌ ValidationRule
์ ๊ฐ์ ๊ฒ์ WinUI์ ์ถ๊ฐํ ๊ณํ์ด ์์ต๋๋ค. ์ด๊ฒ์ ์ฌ์ฉํ๋ฉด ValidationAttributes
๋ฅผ ์ฌ์ฉํ๊ณ ๋ชจ๋ธ์ด INotifyDataErrorInfo
๋ฅผ ๊ตฌํํ๋๋ก ํ๋ ๊ฒ์ด ์์ต๋๊น? ์ฌ์ฉ ์๋๋ฆฌ์ค๋ฅผ ๋ ์ ์ดํดํ๊ธฐ ์ํด ๋ชจ๋ธ๊ณผ XAML์ด ์ด๋ป๊ฒ ์๊ฒผ๋์ง ๋ณด๊ณ ์ถ์ต๋๋ค.
INDEI๋ ๋ชจ๋ ์ํฐํฐ์ ํ์ ์ํฐํฐ๋ฅผ ๊ตฌํํ๋๋ก ์๊ตฌํฉ๋๋ค.
๊ท์น์ ์ฌ์ฉํ๋ฉด ๋ณ๊ฒฝํ ํ์๊ฐ ์์ผ๋ฉฐ ๋ชจ๋ ์ ํจ์ฑ ๊ฒ์ฌ ์์ฑ๋ง ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ์๋ํฉ๋๋ค.
INDEI๋ ๋ชจ๋ ์ํฐํฐ์ ํ์ ์ํฐํฐ๋ฅผ ๊ตฌํํ๋๋ก ์๊ตฌํฉ๋๋ค.
์ด์ ๋ํด ๋ ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?
๊ท์น์ ์ฌ์ฉํ๋ฉด ๋ณ๊ฒฝํ ํ์๊ฐ ์์ผ๋ฉฐ ๋ชจ๋ ์ ํจ์ฑ ๊ฒ์ฌ ์์ฑ๋ง ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ์๋ํฉ๋๋ค.
๋๋ถ๋ถ์ ๊ฒฝ์ฐ ValidationAttributes
๋ฐ INotifyDataErrorInfo
๋ฅผ ์ฌ์ฉํ ๋๋ ๋ชจ๋ ์๋์ผ๋ก ์๋ํฉ๋๋ค. ์ฌ์์ ์๋ ๋ช ๊ฐ์ง ์ฝ๋ ์ค๋ํซ์ ์ฌ๊ธฐ์ ํ์ํ๊ฒ ์ต๋๋ค. ๊ทธ๋์ ์ฐ๋ฆฌ๋ (๋ฐ๋ผ๊ฑด๋) ๊ฐ์ ํ์ด์ง์ ์์ต๋๋ค.
FWIW, ์ฐ๋ฆฌ๋ ์ด ValidationBase
ํด๋์ค๋ฅผ Toolkit์ ํฌํจํ ๊ณํ์ด๋ฏ๋ก ์ด ์์ฉ๊ตฌ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ ํ์๊ฐ ์์ต๋๋ค.
public class ValidationBase : INotifyPropertyChanged, INotifyDataErrorInfo
{
public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
protected void SetValue<T>(ref T currentValue, T newValue, [CallerMemberName] string propertyName = "")
{
if (!EqualityComparer<T>.Default.Equals(currentValue, newValue))
{
currentValue = newValue;
OnPropertyChanged(propertyName, newValue);
}
}
readonly Dictionary<string, List<ValidationResult>> _errors = new Dictionary<string, List<ValidationResult>>();
public bool HasErrors
{
get
{
return _errors.Any();
}
}
public IEnumerable GetErrors(string propertyName)
{
return _errors[propertyName];
}
private void OnPropertyChanged(string propertyName, object value)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Validate(propertyName, value);
}
private void AddErrors(string propertyName, IEnumerable<ValidationResult> results)
{
if (!_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
{
errors = new List<ValidationResult>();
_errors.Add(propertyName, errors);
}
errors.AddRange(results);
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
private void ClearErrors(string propertyName)
{
if (_errors.TryGetValue(propertyName, out List<ValidationResult> errors))
{
errors.Clear();
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
}
public void Validate(string memberName, object value)
{
ClearErrors(memberName);
List<ValidationResult> results = new List<ValidationResult>();
bool result = Validator.TryValidateProperty(
value,
new ValidationContext(this, null, null)
{
MemberName = memberName
},
results
);
if (!result)
{
AddErrors(memberName, results);
}
}
}
๊ทธ๋ฌ๋ฉด ๋ชจ๋ธ์ด ํด๋น ํด๋์ค์์ ํ์๋๊ณ ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค.
public class Person : ValidationBase
{
private string name;
[MinLength(4)]
[MaxLength(6)]
public string Name
{
get { return name; }
set { SetValue(ref name, value); }
}
}
์ด Person
ํด๋์ค๊ฐ Page
์ ViewModel
์์ฑ์ผ๋ก ์ค์ ๋์ด ์๋ค๊ณ ๊ฐ์ ํ๋ฉด ์ด์ ๋ฐ์ธ๋ฉํ๊ณ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์๋์ผ๋ก ๋ฐ์ํฉ๋๋ค.
<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay}" />
์ด๊ฒ์ด ์ค๋๋ ์ฌ๋ฌ๋ถ์ด ํ๊ณ ์๋ ๊ฒ๊ณผ ์ฝ๊ฐ ๋ค๋ฅผ ์ ์๋ค๋ ๊ฒ์ ์ดํดํ์ง๋ง, ํ์ํ์ง ์์ ๊ฒฝ์ฐ ๋์ผํ ์์ ์ ์ํํ๋ ๋ ๊ฐ์ง ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ง์ํ์ง ์์ผ๋ ค๊ณ ํฉ๋๋ค. ์ด๊ฒ์ด ๋ง์ด ๋๋์ง, ์๋๋ฉด ์์ง ์ฐ๋ฆฌ๊ฐ ๋์น๊ณ ์๋ ๊ฒ์ด ์๋ค๊ณ ์๊ฐํ๋ค๋ฉด ์๋ ค์ฃผ์ธ์!
๋น์ ๋ง์ด ๋ง์์. ํ์ง๋ง ๋น์ ์ ์ํฐํฐ๋ POCO๊ฐ ์๋์ด์ผ ํฉ๋๋ค.
ํ๋ฒ ํด๋ด์ผ๊ฒ ๋ค์. LoB ์ฑ์์ EntityBase
ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ทธ๋ฆฌ ๋์์ง ์์ ์ ์์ต๋๋ค. ๋๋ ๋จ์ง POCO๋ฅผ ์ฌ์ฉํ๋ ๋ฐ ์ต์ํฉ๋๋ค.
UWP์๋ *HAVE Validation* ์ด ์์ต๋๋ค!!!!!!! ๋ฐฉ๊ธ ํ๋ก์ ํธ๋ฅผ ์์ํ์ต๋๋ค. ๋ช ๋ ์ ๊น์ง WPF๋ก ๋์๊ฐ์ญ์์ค.
@rufw91 ์์ฃ ?!
๋น์ ์ ์๊ฐ ์ ์ฝ์ ๋ฌด์์ ๋๊น? ์ด๊ฒ์ ์ฒซ ๋ฒ์งธ ๊ตฌํ์ WinUI3 ์ํ์ ์์ผ๋ฉฐ //Build ์๊ฐ ํ๋ ์์ ๊ณง ์ ๊ณต๋ WinUI ๋ฐ์คํฌํฑ์ ๋ํ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ๊ฐ ์์ด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ฌํด ๋ง๊น์ง RTM'์ ํ ๊ณํ์ ๋๋ค.
UWP์๋ *HAVE Validation* ์ด ์์ต๋๋ค!!!!!!! ๋ฐฉ๊ธ ํ๋ก์ ํธ๋ฅผ ์์ํ์ต๋๋ค. ๋ช ๋ ์ ๊น์ง WPF๋ก ๋์๊ฐ์ญ์์ค.
์์ผ๋ก ๋ช ๋ ๋์ WPF๋ ๊ณ์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ๋๋ ๋ชจ๋ ์ผ(WPF, SL, WP, UWP ๋ฑ)์ ์ํํ์ง๋ง ๊ฒฐ๊ตญ WPF์ธ ๋จ 1๊ฐ์ ๊ธฐ์ ๋ง ๊ฒฌ๊ณ ํด ๋ณด์ ๋๋ค. ๋ช ๋ ์์ WinUI๊ฐ ์ด๋์ ์๋์ง ํ์ธํ๋ ๊ฒ์ด ํฅ๋ฏธ๋ก์ธ ์ ์์ง๋ง ์๋ก์ด ๊ธฐ์ ๋ก ์ ํํ๊ณ ์ด๋ ์์ ํ๋ก ๋จ๊ฒจ์ง๋ ๋ฐ ์ง์ณค์ต๋๋ค. WPF๋ ์ฑ์ํ๊ณ ํ๋ฅญํ๊ฒ ์๋ํฉ๋๋ค. ์๋ง๋ ๋ช ๋ ์์ OS๋ก์์ Windows๋ ์ ํ ๊ด๋ จ์ด ์์ ๊ฒ์ด๋ฏ๋ก ํ๋ซํผ์ ๋ ๋ง์ ํฌ์๋ฅผ ํ๊ธฐ ์ ์ ๊ธฐ๋ค๋ ค ๋ด ์๋ค.
์๋ง๋ ๋ช ๋ ์์ OS๋ก์์ Windows๋ ์ ํ ๊ด๋ จ์ด ์์ ๊ฒ์ด๋ฏ๋ก ํ๋ซํผ์ ๋ ๋ง์ ํฌ์๋ฅผ ํ๊ธฐ ์ ์ ๊ธฐ๋ค๋ ค ๋ด ์๋ค.
Windows 10 ์ค์น ์๊ฐ 10์ต ๊ฐ๋ฅผ ๋ง ๋์๋ค๋ ์ ์ ๊ณ ๋ คํ ๋ ๊ทธ๊ฒ์ด ์ฌ์ค์ด ๋ ์ง ๋ฏฟ๊ธฐ ์ด๋ ต์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ ํ์คํ ๋น์ ์ ์ข์ ๊ฐ์ ๋๋ผ๊ณ WPF์ ๋จธ๋ฌด๋ฅด๋ ๊ฒ์ ๋ํด ๋น์ ์ ๋น๋ํ์ง ์์ต๋๋ค. FWIW, ์ฐ๋ฆฌ ํ์ ์ง๊ธ WPF์ ์์ ๊ถ์ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ๊ฐ ๊ฑฐ๊ธฐ์์ ํ๋ ๊ฒ์ ๋ณด๊ณ ์ถ์ ๊ฒ์ด ์์ผ๋ฉด ์๋ ค์ฃผ์ญ์์ค.
INDEI๋ ๋ชจ๋ ์ํฐํฐ์ ํ์ ์ํฐํฐ๋ฅผ ๊ตฌํํ๋๋ก ์๊ตฌํฉ๋๋ค.
์ด์ ๋ํด ๋ ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?
๋ด ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ชจ๋ POCO ์ํฐํฐ๊ฐ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ง ์๊ณ ๊ธฐ๋ณธ ํด๋์ค ์์ด ์ ์ง๋ ์ ์์ต๋๋ค. INPC๋ Fody๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก ๊ตฌํ๋ฉ๋๋ค. ๋ ์ธ๋ จ๋ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ํ์ํ ๋ IValidatableObject
๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ ์ ํ์์๋ ์๋ํฉ๋๋ค.
FWIW, ์ฐ๋ฆฌ๋ ์ด
ValidationBase
ํด๋์ค๋ฅผ Toolkit์ ํฌํจํ ๊ณํ์ด๋ฏ๋ก ์ด ์์ฉ๊ตฌ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ ํ์๊ฐ ์์ต๋๋ค.
๊ทธ๊ฑด ์ข์ง ์์. ๋ด ์ํฐํฐ์ ์ด๋ฏธ ๊ธฐ๋ณธ ํด๋์ค๊ฐ ์๋ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํฉ๋๊น? ์ด๊ฒ์ด ๋ด๊ฐ INotifyDataErrorInfo
์ ์ด๋ ฌํ ํฌ์ด ์๋ ์ด์ ์ด๊ธฐ๋ ํฉ๋๋ค. INPC ์์ฑ์ ํนํ ์๋ง์ ์ํฐํฐ๊ฐ ์๋ ๋๊ท๋ชจ ๋ฐ์ดํฐ ์ฑ์ ์ฒ๋ฆฌํ ๋ ์ด๋ฏธ ๊ณจ์นซ๊ฑฐ๋ฆฌ์
๋๋ค.
UWP์ ์์ง ์ ์ ํ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์๋ค๋ ๊ฒ์ ๋งค์ฐ ์ถฉ๊ฒฉ์ ์ ๋๋ค. ์ด๋ ๊ฑฐ์ ๋ชจ๋ ์ฑ์์ ๊ฐ์ฅ ์ค์ํ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ด๋ฉฐ ์ต์ฐ์ ์์๋ฅผ ๋์ด์ผ ํฉ๋๋ค.
UWP์ ์์ง ์ ์ ํ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์๋ค๋ ๊ฒ์ ๋งค์ฐ ์ถฉ๊ฒฉ์ ์ ๋๋ค. ์ด๋ ๊ฑฐ์ ๋ชจ๋ ์ฑ์์ ๊ฐ์ฅ ์ค์ํ ๊ธฐ๋ณธ ๊ธฐ๋ฅ์ด๋ฉฐ ์ต์ฐ์ ์์๋ฅผ ๋์ด์ผ ํฉ๋๋ค.
๋ค, ๊ทธ๋์ ์ ํฌ๊ฐ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค :)
๊ทธ๊ฑด ์ข์ง ์์. ๋ด ์ํฐํฐ์ ์ด๋ฏธ ๊ธฐ๋ณธ ํด๋์ค๊ฐ ์๋ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํฉ๋๊น?
๋๋ ์ฌ๊ธฐ์์ ๋น์ ์ ์ฌ์ฉ๋ฒ์ ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ๊ธฐ๋ณธ ํด๋์ค๋ ๋ฌด์์ด๋ฉฐ ์ด ํด๋์ค์์ ํ์๋ ์ ์์ต๋๊น?
๋ค, ๊ทธ๋์ ์ ํฌ๊ฐ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค :)
๊ฐ์ฌํฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค. ์ด๊ฒ๊ณผ ๋๋จธ์ง ์์
.
Needs-winui-3 ๋ ์ด๋ธ์ ๋ฌด์์ ์๋ฏธํฉ๋๊น?
๋๋ ์ฌ๊ธฐ์์ ๋น์ ์ ์ฌ์ฉ๋ฒ์ ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ๊ธฐ๋ณธ ํด๋์ค๋ ๋ฌด์์ด๋ฉฐ ์ด ํด๋์ค์์ ํ์๋ ์ ์์ต๋๊น?
๋ด ํด๋ผ์ด์ธํธ์์ ์์ฑ๋ ์ํฐํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํด OData Connected Service ๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
์์ฑ๋ ๊ฐ์ฒด๋ ๋ค์ ํจํด์
๋๋ค.
c#
public abstract partial class ContactBase :
Microsoft.OData.Client.BaseEntityType, INotifyPropertyChanged
Needs-winui-3 ๋ ์ด๋ธ์ ๋ฌด์์ ์๋ฏธํฉ๋๊น?
@weitzhandler
์ด๋ ์
๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ WinUI 3๊ณผ ํจ๊ป ์ ๊ณต๋ ๊ฒ์์ ์๋ฏธํฉ๋๋ค. (ํ์ฌ ๊ณํ๋ ๋๋ก 3.0). ์ง๊ธ๊น์ง ์ ์ง ๊ด๋ฆฌ ๋ชจ๋์ ์๋ OS XAML ์ฝ๋๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๋ฏ๋ก WinUI 2์๋ ๋์ค์ง ์์ ๊ฒ์
๋๋ค.
Uno Platform ์ฑ์์ UWP๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. WinUI๊ฐ ์ถ์๋๋ฉด ๋ค๋ฃฐ ๊ฒ์
๋๋ค.
์
๋ฐ์ดํธ ์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค!
๋๋ ์ฌ๊ธฐ์์ ๋น์ ์ ์ฌ์ฉ๋ฒ์ ์ดํดํ๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค. ๊ธฐ๋ณธ ํด๋์ค๋ ๋ฌด์์ด๋ฉฐ ์ด ํด๋์ค์์ ํ์๋ ์ ์์ต๋๊น?
๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๊ฐ๋ ๊ฒ์ ์ 3์์ ์ํด ์๊ตฌ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค(์: ์ฌ์ฉํ๋ ์ง์์ฑ ํ๋ ์์ํฌ). UWP/WinUI๋ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์๊ตฌํ๋ ๊ฒ๋ ์ต์ ์ด ์๋๋๋ค. ์ ์ฉํ๋ ค๋ฉด ์ธํฐํ์ด์ค๊ฐ ํ์ํ๋ฉฐ, ์ฐ๋ฆฌ์ ์ด๋ค ์ ํ๋ฆฌ์ผ์ด์ ๋ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. (์ฆ, ์ฌ์ฉํ๋ ค๋ ์ฌ๋๋ค์ ์ํ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๊ฐ์ง ์ ์๋ค๋ ์๋ฏธ๋ ์๋๋๋ค. ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ด ์๋๋ผ ์ ํ ์ฌํญ์ผ ํ์๊ฐ ์์ต๋๋ค.)
๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๊ฐ๋ ๊ฒ์ ์ 3์์ ์ํด ์๊ตฌ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค(์: ์ฌ์ฉํ๋ ์ง์์ฑ ํ๋ ์์ํฌ). UWP/WinUI๋ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์๊ตฌํ๋ ๊ฒ๋ ์ต์ ์ด ์๋๋๋ค. ์ ์ฉํ๋ ค๋ฉด ์ธํฐํ์ด์ค๊ฐ ํ์ํ๋ฉฐ, ์ฐ๋ฆฌ์ ์ด๋ค ์ ํ๋ฆฌ์ผ์ด์ ๋ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์กฐ๊ธ ๋ฐฑ์ ํฉ์๋ค. ๋ด๊ฐ ๋ง๋ ๋ง์ง๋ง ๋ช ๊ฐ์ ๋๊ธ์ด ์ฝ๊ฐ์ ํผ๋์ ์ผ์ผ์ผฐ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด๋ ์ ์๋ชป์ ๋๋ค.
๋ชจ๋ธ์ ํ์ํ ๋ชจ๋ ๊ฒ์ System.ComponentModel.INotifyDataErrorInfo
(๋๋ C++์ ๊ฒฝ์ฐ Windows.UI.Xaml.Data.INotifyDataErrorInfo
)๋ฅผ ๊ตฌํํ๋ ๊ฒ์
๋๋ค. ์ปดํ์ผ๋ฌ๋ {x:Bind}
๋ฅผ ์ฌ์ฉํ ๋ ๋ทฐ์ ์ฐ๊ฒฐํ๋ ์ฝ๋๋ฅผ ์ ์ ํ๊ฒ ์์ฑํฉ๋๋ค.
์์์ ์ธ๊ธํ ValidationBase
ํด๋์ค๋ INotifyPropertyChanged
์ ํจ๊ป ์ด๊ฒ์ ๊ตฌํํ๋ ์ปค๋ฎค๋ํฐ ํดํท์ ์ ๊ณตํ ๊ณํ์ด์๋ ๋์ฐ๋ฏธ ํด๋์ค์
๋๋ค. ์ฌ์ฉ ์ฌ๋ก์์ ํ์ฉํ์ง ์๋ ๊ฒฝ์ฐ ํ์ํ ํ์๊ฐ ์์ต๋๋ค.
@stevenbrix์ ์ค๋ช ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค.
์ ํจ์ฑ ๊ฒ์ฌ ํน์ฑ ๋ฐ IValidatableObject
๋ ์ด๋ป์ต๋๊น? UWP ๋ฐํ์์์ ์ด๋ฅผ ์กด์คํฉ๋๊น?
์์ ์ธ๊ธํ MaxLength
์์ฑ๊ณผ ๊ฐ์ ๋ค๋ฅธ ์์ฑ์ ASP.NET์์์ ๊ฐ์ด TextBox
์ต๋ ๊ธธ์ด๊ฐ ์๋์ผ๋ก ์ค์ ๋ฉ๋๊น?
DataTypeAttribute
, EditableAttribute
์ ๋์ผํฉ๋๋ค.
๋ํ ํ๋ ํค๋๋ฅผ ์์ฑํ๊ธฐ ์ํ DisplayAttribute
์
๋๋ค.
๋ด๊ฐ ๊ธฐ์ตํ๋ ํ ๊ทธ๊ฒ๋ค์ ๋ชจ๋ Silverlight์์ ์ง์๋์์ต๋๋ค.
( ์ด ์ฐธ์กฐ).
์ ํจ์ฑ ๊ฒ์ฌ ํน์ฑ๊ณผ IValidatableObject๋ ์ด๋ป์ต๋๊น? UWP ๋ฐํ์์์ ์ด๋ฅผ ์กด์คํฉ๋๊น?
๋ฐ๋ผ์ ํ์ฌ Required
์์ฑ์ ์ง์ํ ์์ ์
๋๋ค. ์ผ๋ถ ์ปจํธ๋กค์ ์ด๊ฒ์ด ์ฌ์ฉ๋ ๋ ํค๋ ํ
์คํธ ์์ ์๋์ผ๋ก ์์ ๋ณํ๋ฅผ ํ์ํฉ๋๋ค. ๋น์ ์ด ์ํ๋ค๋ฉด ์ฐ๋ฆฌ๋ ์์ผ๋ก ๋ ๋ง์ ๊ฒ์ ์ง์ํ ์ค๋น๊ฐ ๋์ด ์์ต๋๋ค. ๋ ๋ง์ ๊ฒ์ ๋ณด๊ณ ์ถ์ผ์๋ค๋ฉด ๋ณ๋์ ๋ฌธ์ ๋ฅผ ์ฌ์ญ์์ค. ๊ธฐ๋์น๋ฅผ ์ค์ ํ๊ธฐ ์ํด ์ถ๊ฐ ์์ฑ ์ง์์ ์ด๊ธฐ WinUI3 ๋ฆด๋ฆฌ์ค๋ฅผ ๋ง๋ค ๊ฐ๋ฅ์ฑ์ด ๊ฑฐ์ ์์ต๋๋ค.
IValidatableObject
์ ๊ดํด์๋ ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ผ๋ฐํํ๋ฉด, ์ฐ๋ฆฌ ์์ง์ ๋จ์ํ INotifyDataErrorInfo.ErrorsChanged
์ด๋ฒคํธ๋ฅผ ์์ ํ์ฌ ์๋ํฉ๋๋ค. ๋ชจ๋ธ์ ์ค์ ์ ํจ์ฑ ๊ฒ์ฌ๋ ์ฑ ๊ฐ๋ฐ์์๊ฒ ๋ฌ๋ ค ์์ผ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ๋์์์ ์์ค๋ก ๊ฐ์ ์ ์กํ ๋ ์ํ๋ฉ๋๋ค.
์ ์ํ ValidationBase
์ ๋ํ ๋์์ผ๋ก Validator.TryValidateObject
๋ฅผ ์ฌ์ฉํ์ฌ ์ ํจ์ฑ ๊ฒ์ฌ ํ๋ก์ธ์ค๋ฅผ ์คํํ๊ณ ์ ํจ์ฑ ๊ฒ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ํฐํฐ์ ์ฝ์
ํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ฆฌ๋ ํ์ฅ ๋ฉ์๋ ์งํฉ์ด ์์ด์ผ ํฉ๋๋ค. ?
์ด๋ฐ ์์ผ๋ก INotifyDataErrorInfo
๋ฅผ ๊ตฌํํ๋ฉด ์ฝ๊ฒ ๋ฌ์ฑํ ์ ์์ต๋๋ค. ๋ํ ์ค๋ฅ ์ปฌ๋ ์
์ ๋ณด์ ํ๋ ์์ฑ์ ์ถ๊ฐํ๋ INotifyDataErrorInfo
์์ ์์ํ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก UWP ๋ฐํ์ ๋๋ ๋๊ตฌ ํคํธ๊ฐ ๋์ ์๋ํ๋ ์ ํจ์ฑ ๊ฒ์ฌ ๊ฐ๋ฅํ ์ํฐํฐ๋ก ์ธ์ํ๊ณ ๊ตฌํ๋ ๊ฒฝ์ฐ ์์ฑ์ ์๋์ผ๋ก ์ค์ ํ ์ ์์ต๋๋ค.
์๋ง๋ ๋น์ ์ด ์ ์ํ ValidationBase์ ๋ํ ๋์์ผ๋ก Validator.TryValidateObject๋ฅผ ์ฌ์ฉํ์ฌ ์ ํจ์ฑ ๊ฒ์ฌ ํ๋ก์ธ์ค๋ฅผ ์คํํ๊ณ ์ ํจ์ฑ ๊ฒ์ฌ ๊ฒฐ๊ณผ๋ฅผ ์ํฐํฐ์ ์ฃผ์ ํ์ฌ ๋ณ๊ฒฝ ์ฌํญ์ ์๋ฆฌ๋ ํ์ฅ ๋ฉ์๋ ์งํฉ์ด ์์ด์ผ ํฉ๋๋ค.
์ด๊ฒ์ ์ข์ ์์ด๋์ด์ ๋๋ค :)
๐ฆ ์๋ก์ด ์์ค ์์ฑ๊ธฐ ํจ๋ฌ๋ค์์ด ์ฌ๊ธฐ์์๋ ๋์์ด ๋ ์ ์๋์ง ๊ถ๊ธํ์ญ๋๊น?
์ @michael-hawker, ๋๋ ๋น์ ์ ์๊ฐ์ ์ข์ํฉ๋๋ค!
์ผ๋ง ์ ์ ์๋ก์ด ์์ค ์์ฑ๊ธฐ ๊ฐ๋ฅ์ฑ์ ๋ํด ์ฒ์ ์ฝ์์ ๋๋ ๊ฐ์ ์๊ฐ์ ํ์ต๋๋ค.
์๋ก์ด ์์ค ์์ฑ๊ธฐ ํจ๋ฌ๋ค์์ ์ฌ์ฉํ๋ฉด INotifyDataErrorInfo ๋ฐ INotifyPropertyChanged์ ๋ํ ๋ฐฐํ์์ ๋ง์ ๊ฒ์ ๋น๋/์์ฑํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ์ํ ๋ฐ์ดํฐ ์ฃผ์์ ํฌํจํ์ฌ T4, INotifyPropertyChanged ๋ฐ INotifyDataErrorInfo๋ก ์ ํํ ์ด ์์
์ ์ํํ๋ Pluralsight์ ๋ํ WPF ๊ณผ์ ์ด ์์ต๋๋ค. https://www.pluralsight.com/courses/wpf-mvvm-advanced-model-treatment
์ด ๊ณผ์ ์ ๋ํ ์ฌ์ฉ์ ์ง์ ์ฐ๊ฒฐ๋ ์์ฑ์ ์ฌ์ฉํ์ฌ ํญ๋ชฉ์ ์ฐ๊ฒฐํฉ๋๋ค.
์ด ๊ณผ์ ์ ๋ชฉํ๋ ๋ชจ๋ ์
๋ ฅ ํ๋๊ฐ ๋ณ๊ฒฝ๋๊ณ ์๋ ๊ฐ์ด ๋ฌด์์ธ์ง ํ์ํ๋ MVVM WPF ์ฑ์ ๋น๋ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ์
๋๋ค.
๋ฐ๋ผ์ ํ์คํ ๋ฌด์ธ๊ฐ๋ฅผ ์์ฑํ๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋๋๋ ๊ฒ(WCT์ ์ผ๋ถ๋ก)์ ๊ต์ฅํ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ WinUI๋ฅผ ์ํด ๊ทธ ๊ณผ์ ์ ๋ค์ ํ๊ณ ์ถ์ต๋๋ค. :)
@rufw91 ์์ฃ ?!
๋น์ ์ ์๊ฐ ์ ์ฝ์ ๋ฌด์์ ๋๊น? ์ด๊ฒ์ ์ฒซ ๋ฒ์งธ ๊ตฌํ์ WinUI3 ์ํ์ ์์ผ๋ฉฐ //Build ์๊ฐ ํ๋ ์์ ๊ณง ์ ๊ณต๋ WinUI ๋ฐ์คํฌํฑ์ ๋ํ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ๊ฐ ์์ด์ผ ํฉ๋๋ค. ์ฐ๋ฆฌ๋ ์ฌํด ๋ง๊น์ง RTM'์ ํ ๊ณํ์ ๋๋ค.
@stevenbrix ํฌ๋งํฉ๋๋ค. WPF๋ก ๋ค์ ์ ํํด์ผ ํ์ต๋๋ค. ์ด์ ๊ฑฐ์ ์๋ฃ๋์์ต๋๋ค.
๋๋ ์ด๊ฒ์ ์ด์์ต๋๋ค.
์ด์ ๋ํ ํ์ ์กฐ์น๋ก Twitter์์ @stevenbrix ์ ๋ํํ ํ ๊ทธ๊ฐ ์ฌ๊ธฐ ์ ์ ๊ณตํ ๊ธฐ๋ณธ INotifyDataErrorInfo
๊ตฌํ์ ์๋ก์ด MVVM ํดํท์ ํฌํจ๋๋ ์๋ก์ด ObservableValidator
ํด๋์ค์ ํตํฉํ์ต๋๋ค. Microsoft.Toolkit.Mvvm
๋ผ์ด๋ธ๋ฌ๋ฆฌ), INotifyPropertyChanged
๋ฐ INotifyPropertyChanging
๋ ๊ตฌํํฉ๋๋ค. ๐
์ด๋ฒ ํธ ์์ ๊ด๋ จ ์ฝ๋์ ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ด๋ จ๋ ๋ชจ๋ ๋ด์ฉ์ ์์ฝ์ ๋ณผ ์ ์์ต๋๋ค.
๋ํ MVVM Toolkit์ ์๋ ๋ฌธ์ ์ ๋ํ ๋งํฌ์ ์๋ก์ด ๊ฐ๋ฐ์๋ฅผ ์ํ ์ถ๊ฐ ๋ฌธ์๋ ํฌํจํ์ต๋๋ค.
์ด์ ๋ํ ์ต์ ์ ๋ณด๋ฅผ ์ ๊ณตํด ์ฃผ์๊ฒ ์ต๋๊น? UWP 10.0 18362๊ฐ INotifyDataErrorInfo
๋ฅผ ์ง์ํ๋์ง ๊ถ๊ธํฉ๋๋ค. ๋ค์ ๋ฌธ์ ํ์ด์ง์ ๋ฐ๋ฅด๋ฉด https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.inotifydataerrorinfo?view=netcore-3.1 INotifyDataErrorInfo
UWP 10.0์ "์ ์ฉ"๋ฉ๋๋ค. ๊ทธ๋ฌ๋ UWP 10.0 18362๋ฅผ ์ค์นํ๊ณ ๋์์ผ๋ก ์ง์ ํ๋ฉด ํ
์คํธ ์์์ INotifyDataErrorInfo
์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ํ์๋์ง ์์ต๋๋ค. ํ
์คํธ ์์๋ XAML์์ ๋ค์๊ณผ ๊ฐ์ด ์ค๋ช
๋ฉ๋๋ค.
<TextBox Text="{x:Bind ViewModel.Username, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์ ReactiveValidationObject
๋ฅผ INotifyDataErrorInfo
๊ตฌํ์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
@worldbeater ์ด๊ฒ์ WinUI3์ ์ต์ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ์์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฌ์ฉ ์ค์ด์ ๊ฐ์?
@stevenbrix ๊ฐ์ฌํฉ๋๋ค! WinUI3๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํฉ๋๋ค. INotifyDataErrorInfo
์ UWP๊ฐ ๋๋์ด ์น๊ตฌ๊ฐ ๋์ด ๊ธฐ์ฉ๋๋ค โจ
@worldbeater , ์์ง ๋ฏธ๋ฆฌ ๋ณด๊ธฐ ๋จ๊ณ์ด๋ฏ๋ก ์ด์ ๋ํ ํผ๋๋ฐฑ์ ๋ฐ๊ณ ์ถ์ต๋๋ค! ๐ช
๊ทธ๊ฑด ๊ทธ๋ ๊ณ @worldbeater ๋ ๋ฌธ์์ UWP 10.0์์ ์ฌ์ฉํ ์ ์๋ค๊ณ ๋์ ์์ง๋ง UWP 10.0์์ ์ง์ํ๋ค๋ ์๋ฏธ๋ ์๋๋๋ค. ๋ฌธ์๊ฐ ์ถฉ๋ถํ ๋ช ํํ์ง ์์ต๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด์ ๋ํด ๋ ์์ธํ ์ค๋ช ํด ์ฃผ์๊ฒ ์ต๋๊น?
๋๋ถ๋ถ์ ๊ฒฝ์ฐ
ValidationAttributes
๋ฐINotifyDataErrorInfo
๋ฅผ ์ฌ์ฉํ ๋๋ ๋ชจ๋ ์๋์ผ๋ก ์๋ํฉ๋๋ค. ์ฌ์์ ์๋ ๋ช ๊ฐ์ง ์ฝ๋ ์ค๋ํซ์ ์ฌ๊ธฐ์ ํ์ํ๊ฒ ์ต๋๋ค. ๊ทธ๋์ ์ฐ๋ฆฌ๋ (๋ฐ๋ผ๊ฑด๋) ๊ฐ์ ํ์ด์ง์ ์์ต๋๋ค.FWIW, ์ฐ๋ฆฌ๋ ์ด
ValidationBase
ํด๋์ค๋ฅผ Toolkit์ ํฌํจํ ๊ณํ์ด๋ฏ๋ก ์ด ์์ฉ๊ตฌ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ ํ์๊ฐ ์์ต๋๋ค.๊ทธ๋ฌ๋ฉด ๋ชจ๋ธ์ด ํด๋น ํด๋์ค์์ ํ์๋๊ณ ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค.
์ด
Person
ํด๋์ค๊ฐPage
์ViewModel
์์ฑ์ผ๋ก ์ค์ ๋์ด ์๋ค๊ณ ๊ฐ์ ํ๋ฉด ์ด์ ๋ฐ์ธ๋ฉํ๊ณ ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ์๋์ผ๋ก ๋ฐ์ํฉ๋๋ค.์ด๊ฒ์ด ์ค๋๋ ์ฌ๋ฌ๋ถ์ด ํ๊ณ ์๋ ๊ฒ๊ณผ ์ฝ๊ฐ ๋ค๋ฅผ ์ ์๋ค๋ ๊ฒ์ ์ดํดํ์ง๋ง, ํ์ํ์ง ์์ ๊ฒฝ์ฐ ๋์ผํ ์์ ์ ์ํํ๋ ๋ ๊ฐ์ง ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ง์ํ์ง ์์ผ๋ ค๊ณ ํฉ๋๋ค. ์ด๊ฒ์ด ๋ง์ด ๋๋์ง, ์๋๋ฉด ์์ง ์ฐ๋ฆฌ๊ฐ ๋์น๊ณ ์๋ ๊ฒ์ด ์๋ค๊ณ ์๊ฐํ๋ค๋ฉด ์๋ ค์ฃผ์ธ์!