C#/WPF

[WPF] ValidationRule 사용하기

kjun.kr 2023. 2. 26. 20:41
728x90
728x170

ValidationRule 을 이용하여 그리드 항목의 날짜 데이터가
시작일이 종료일보다 큰 경우를 입력한 경우 경고를 주는 방법입니다.

TestData.cs

using System;

namespace WPF.ValidationRuleTest
{
    public class TestData
    {
        public string? Name { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }

        public TestData()
        {
            StartDate = EndDate = DateTime.Today;
        }
    }
}


DateValidationRule.cs

using System.Globalization;
using System.Windows.Controls;
using System.Windows.Data;

namespace WPF.ValidationRuleTest
{
    public class DateValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            TestData course = (value as BindingGroup).Items[0] as TestData;

            if (course.StartDate > course.EndDate)
            {
                return new ValidationResult(false, "시작일은 종료일보다 앞서야 합니다.");
            }
            else
            {
                return ValidationResult.ValidResult;
            }
        }
    }
}

MainWindow.xaml

<Window
    x:Class="WPF.ValidationRuleTest.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:local="clr-namespace:WPF.ValidationRuleTest"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <DataGrid
            Name="dataGrid"
            AutoGenerateColumns="False"
            ItemsSource="{Binding Items}"
            RowHeaderWidth="30">
            <DataGrid.Resources>
                <Style x:Key="EditingElementStyle" TargetType="{x:Type TextBox}">
                    <Setter Property="Padding" Value="-2" />
                    <Style.Triggers>
                        <Trigger Property="Validation.HasError" Value="True">
                            <Setter Property="Background" Value="Red" />
                            <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTextColumn
                    Binding="{Binding Name, ValidatesOnExceptions=True}"
                    EditingElementStyle="{StaticResource EditingElementStyle}"
                    Header="이름" />
                <DataGridTextColumn
                    Binding="{Binding StartDate, ValidatesOnExceptions=True, StringFormat=yyyy-MM-dd}"
                    EditingElementStyle="{StaticResource EditingElementStyle}"
                    Header="시작일" />
                <DataGridTextColumn
                    Binding="{Binding EndDate, ValidatesOnExceptions=True, StringFormat=yyyy-MM-dd}"
                    EditingElementStyle="{StaticResource EditingElementStyle}"
                    Header="종료일" />
            </DataGrid.Columns>
            <DataGrid.RowValidationRules>
                <local:DateValidationRule ValidationStep="UpdatedValue" />
            </DataGrid.RowValidationRules>
            <DataGrid.RowValidationErrorTemplate>
                <ControlTemplate>
                    <Grid Margin="0,-2,0,-2" ToolTip="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent}">
                        <Ellipse
                            Width="{TemplateBinding FontSize}"
                            Height="{TemplateBinding FontSize}"
                            Fill="Red"
                            StrokeThickness="0" />
                        <TextBlock
                            HorizontalAlignment="Center"
                            FontSize="{TemplateBinding FontSize}"
                            FontWeight="Bold"
                            Foreground="White"
                            Text="!" />
                    </Grid>
                </ControlTemplate>
            </DataGrid.RowValidationErrorTemplate>
        </DataGrid>
    </Grid>
</Window>


MainViewModel.cs

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WPF.ValidationRuleTest
{
    public class MainViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged([CallerMemberName] string name = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));

        private ObservableCollection<TestData> items;

        public ObservableCollection<TestData> Items
        {
            get
            {
                if (this.items == null)
                {
                    this.items = new ObservableCollection<TestData>();
                }

                return this.items;
            }
            set
            {
                this.items = value;
                OnPropertyChanged();
            }
        }

        public MainViewModel()
        {
            this.Items.Add(new TestData { Name = "Jack", StartDate = new DateTime(2023, 10, 15), EndDate = new DateTime(2023, 10, 20) });
            this.Items.Add(new TestData { Name = "Brown", StartDate = new DateTime(2023, 1, 11), EndDate = new DateTime(2023, 1, 22) });
        }
    }
}

결과

[Source]
https://github.com/kei-soft/WPF.AppTest/tree/master/WPF.ValidationRuleTest

 

GitHub - kei-soft/WPF.AppTest: https://kjun.kr/category/C%23/WPF

https://kjun.kr/category/C%23/WPF. Contribute to kei-soft/WPF.AppTest development by creating an account on GitHub.

github.com

 

728x90
그리드형