■ 바인딩 유효성 검사를 구현하는 방법을 보여준다.
▶ 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 } } |