[WPF] WPF 데이터바인딩 예외처리 ValidationRule 사용 방법(사용자 정의 예외 처리)

안녕하세요.

 

오늘은 WPF에서 데이터 바인딩 예외처리 하는 방법에 대해서 알려 드리려고 합니다.

 

WPF에서 데이터 바인딩을 하다 보면 예를 들어서 TextBox 컨트롤에 나이를 입력해야 한다면, 숫자만 입력을 해야 하는데 문자 혹은 다른 타입의 무언가 입력이 될 때 사용자에게 알려 주기 위한 예외 처리가 필요한데요.

 

이때 사용하는 방법이 바로 ValidationRule 입니다.

 

그러면 어떻게 구현 하는지 예제를 통해서 알아 보도록 하겠습니다.

 

 

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
<Window x:Class="BindingTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BindingTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="160.827" Width="300">
 
    <Window.DataContext>
        <local:Student/>
    </Window.DataContext>
 
    <Grid>
 
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
 
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
 
        <TextBlock Grid.Row="0" Grid.Column="0" Text="이름 : "
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   Margin="10, 2"/>
        <TextBox Grid.Row="0" Grid.Column="1"
                 Margin="5"
                 Text="{Binding Path=Name, Mode=TwoWay}"/>
 
        <TextBlock Grid.Row="1" Grid.Column="0" Text="나이 : "
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   Margin="10, 2"/>
        
        <!--Validation Rule 예제-->
        <TextBox x:Name="uiTb_Age" Grid.Row="1" Grid.Column="1"
                 Margin="5"
                  ToolTip="{Binding RelativeSource={RelativeSource Self},Path=(Validation.Errors)[0].ErrorContent}">
            <TextBox.Text>
                <Binding Path="Age"
                         Mode="TwoWay"
                         UpdateSourceTrigger="PropertyChanged">
                    
                    <Binding.ValidationRules>
                        <local:AgeRangeExcetion/>
                    </Binding.ValidationRules>
                    
                </Binding>
            </TextBox.Text>
        </TextBox>
 
        <TextBlock Grid.Row="2" Grid.Column="0" Text="번호 : "
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   Margin="10, 2"/>
        <TextBox x:Name="uiTb_PhoneNumber" Grid.Row="2" Grid.Column="1"
                 Margin="5"
                 Text="{Binding Path=PhoneNumber}"
                 Foreground="Blue"/>
 
        <Grid Grid.Row="4" Grid.ColumnSpan="2" Height="30">
 
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
 
            <Button Grid.Column="1" Content="확인" Margin="5,3"
                    Foreground="{Binding ElementName=uiTb_Age, Path=Foreground}"/>
            <Button Grid.Column="2" Content="취소" Margin="5,3"/>
 
        </Grid>
 
    </Grid>
</Window>
 
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
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
 
namespace BindingTest
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
 
    /// <summary>
    /// ValidationRule 클래스
    /// </summary>
    public class AgeRangeExcetion : ValidationRule
    {
        public int MinAge { get; set; }
        public int MaxAge { get; set; }
 
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            int age = 0;
 
            if (!int.TryParse((string)value, out age))
            {
                return new ValidationResult(false"잘못된 숫자입니다.");
            }
 
            if (age >= MinAge && age <= MaxAge)
            {
                return new ValidationResult(truenull);
            }
            else
            {
                return new ValidationResult(false,$"나이의 범위는 {MinAge} ~ {MaxAge} 사이의 숫자 이어야 합니다.");
            }
        }
    }
}
cs

 

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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace BindingTest
{
    public class Student :INotifyPropertyChanged
    {
        /// <summary>
        /// this 생성자
        /// </summary>
        public Student() : this("범범조조""28""000-1111-2222") { }
 
        public Student(string name, string age, string number)
        {
            this.Name = name;
            this.Age = age;
            this.PhoneNumber = number;
        }
 
        private string name;
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                OnPropertyChanged("Name");
            }
        }
 
        private string age;
        public string Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
                OnPropertyChanged("Age");
            }
        }
 
        private string phoneNumber;
 
        public string PhoneNumber
        {
            get
            {
                return phoneNumber;
            }
            set
            {
                phoneNumber = value;
                OnPropertyChanged("PhoneNumber");
            }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));
        }
    }
}
 
cs

 

실행 결과

 

위와 같이 숫자가 아닌 다른 문자가 입력 되면, TextBox 에서 빨간색 영역으로 Border가 칠해지면서 ToolTip으로 현재의 에러 내용을 사용자에게 보여주고 있는 것을 확인하실 수 있습니다.

 

감사합니다.^^

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY