Aracılığıyla paylaş


Nasıl yapılır: DataGrid Denetimi ile Doğrulama Uygulama

Denetim, DataGrid hem hücre hem de satır düzeyinde doğrulama gerçekleştirmenizi sağlar. Hücre düzeyi doğrulama ile, kullanıcı bir değeri güncelleştirdiğinde ilişkili veri nesnesinin tek tek özelliklerini doğrularsınız. Satır düzeyi doğrulama ile, kullanıcı bir satıra değişiklikleri işlediğinde veri nesnelerinin tamamını doğrularsınız. Ayrıca doğrulama hataları için özelleştirilmiş görsel geri bildirim sağlayabilir veya denetimin sağladığı varsayılan görsel geri bildirimi DataGrid kullanabilirsiniz.

Aşağıdaki yordamlarda bağlamalara doğrulama kurallarının nasıl uygulanacağı DataGrid ve görsel geri bildirimin nasıl özelleştirileceği açıklanmaktadır.

Tek tek hücre değerlerini doğrulamak için

  • Bir sütunla kullanılan bağlamada bir veya daha fazla doğrulama kuralı belirtin. Bu, Veri Bağlamaya Genel Bakış'ta açıklandığı gibi basit denetimlerdeki verileri doğrulamaya benzer.

    Aşağıdaki örnekte, bir DataGrid iş nesnesinin farklı özelliklerine bağlı dört sütunlu bir denetim gösterilmektedir. Sütunlardan üçü özelliğini trueolarak ayarlayarak ValidatesOnExceptions öğesini belirtirExceptionValidationRule.

    <Grid>
    
      <Grid.Resources>
        <local:Courses x:Key="courses"/>
      </Grid.Resources>
    
      <DataGrid Name="dataGrid1" FontSize="20"
        ItemsSource="{StaticResource courses}" 
        AutoGenerateColumns="False">
        <DataGrid.Columns>
          <DataGridTextColumn Header="Course Name" 
            Binding="{Binding Name, TargetNullValue=(enter a course name)}"/>
          <DataGridTextColumn Header="Course ID"
            Binding="{Binding Id, ValidatesOnExceptions=True}"/>
          <DataGridTextColumn Header="Start Date"
            Binding="{Binding StartDate, ValidatesOnExceptions=True, 
              StringFormat=d}"/>
          <DataGridTextColumn Header="End Date"
            Binding="{Binding EndDate, ValidatesOnExceptions=True,
              StringFormat=d}"/>
        </DataGrid.Columns>
      </DataGrid>
      
    </Grid>
    

    Kullanıcı geçersiz bir değer (Kurs Kimliği sütununda tamsayı olmayan bir değer gibi) girdiğinde hücrenin çevresinde kırmızı bir kenarlık görünür. Bu varsayılan doğrulama geri bildirimini aşağıdaki yordamda açıklandığı gibi değiştirebilirsiniz.

Hücre doğrulama geri bildirimini özelleştirmek için

  • Sütunun özelliğini, sütunun EditingElementStyle düzenleme denetimine uygun bir stile ayarlayın. Düzenleme denetimleri çalışma zamanında oluşturulduğundan Validation.ErrorTemplate , ekli özelliği basit denetimlerle yaptığınız gibi kullanamazsınız.

    Aşağıdaki örnek, doğrulama kuralları olan üç sütun tarafından paylaşılan bir hata stili ekleyerek önceki örneği güncelleştirir. Kullanıcı geçersiz bir değer girdiğinde, stil hücre arka plan rengini değiştirir ve bir Araç İpucu ekler. Doğrulama hatası olup olmadığını belirlemek için tetikleyici kullanımına dikkat edin. Şu anda hücreler için ayrılmış bir hata şablonu olmadığından bu gereklidir.

    <DataGrid.Resources>
      <Style x:Key="errorStyle" 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 Header="Course Name" 
        Binding="{Binding Name, TargetNullValue=(enter a course name)}"/>
      <DataGridTextColumn Header="Course ID"
        EditingElementStyle="{StaticResource errorStyle}"
        Binding="{Binding Id, ValidatesOnExceptions=True}"/>
      <DataGridTextColumn Header="Start Date"
        EditingElementStyle="{StaticResource errorStyle}"
        Binding="{Binding StartDate, ValidatesOnExceptions=True, 
          StringFormat=d}"/>
      <DataGridTextColumn Header="End Date"
        EditingElementStyle="{StaticResource errorStyle}"
        Binding="{Binding EndDate, ValidatesOnExceptions=True,
          StringFormat=d}"/>
    </DataGrid.Columns>
    

    Sütun tarafından kullanılan öğesini değiştirerek CellStyle daha kapsamlı özelleştirmeler uygulayabilirsiniz.

Tek bir satırdaki birden çok değeri doğrulamak için

  1. Bağlı veri nesnesinin birden çok özelliğini denetleen bir ValidationRule alt sınıf uygulayın. Yöntem uygulamanızda Validate parametre değerini bir BindingGroup örneğe dönüştürebilirsinizvalue. Daha sonra veri nesnesine özelliği aracılığıyla Items erişebilirsiniz.

    Aşağıdaki örnek, bir Course nesnenin özellik değerinin özellik değerinden StartDate önce EndDate olup olmadığını doğrulamak için bu işlemi gösterir.

    public class CourseValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value,
            System.Globalization.CultureInfo cultureInfo)
        {
            Course course = (value as BindingGroup).Items[0] as Course;
            if (course.StartDate > course.EndDate)
            {
                return new ValidationResult(false,
                    "Start Date must be earlier than End Date.");
            }
            else
            {
                return ValidationResult.ValidResult;
            }
        }
    }
    
    Public Class CourseValidationRule
        Inherits ValidationRule
    
        Public Overrides Function Validate(ByVal value As Object, _
            ByVal cultureInfo As System.Globalization.CultureInfo) _
            As ValidationResult
    
            Dim course As Course = _
                CType(CType(value, BindingGroup).Items(0), Course)
    
            If course.StartDate > course.EndDate Then
                Return New ValidationResult(False, _
                    "Start Date must be earlier than End Date.")
            Else
                Return ValidationResult.ValidResult
            End If
    
        End Function
    
    End Class
    
  2. Doğrulama kuralını koleksiyona DataGrid.RowValidationRules ekleyin. özelliği, RowValidationRules denetim tarafından kullanılan tüm bağlamaları gruplandıran bir BindingGroup örneğin özelliğine doğrudan erişim ValidationRules sağlar.

    Aşağıdaki örnek, XAML'de özelliğini ayarlar RowValidationRules . ValidationStep özelliği olarak UpdatedValue ayarlanır, böylece doğrulama yalnızca ilişkili veri nesnesi güncelleştirildikten sonra gerçekleşir.

    <DataGrid.RowValidationRules>
      <local:CourseValidationRule ValidationStep="UpdatedValue"/>
    </DataGrid.RowValidationRules>
    

    Kullanıcı başlangıç tarihinden önceki bir bitiş tarihini belirttiğinde, satır üst bilgisinde kırmızı bir ünlem işareti (!) görünür. Bu varsayılan doğrulama geri bildirimini aşağıdaki yordamda açıklandığı gibi değiştirebilirsiniz.

Satır doğrulama geri bildirimini özelleştirmek için

  • DataGrid.RowValidationErrorTemplate özelliğini ayarlayın. Bu özellik, tek tek DataGrid denetimler için satır doğrulama geri bildirimini özelleştirmenizi sağlar. Ayrıca, özelliğini ayarlamak DataGridRow.ValidationErrorTemplate için örtük bir satır stili kullanarak birden çok denetimi de etkileyebilirsiniz.

    Aşağıdaki örnek, varsayılan satır doğrulama geri bildirimini daha görünür bir göstergeyle değiştirir. Kullanıcı geçersiz bir değer girdiğinde, satır üst bilgisinde beyaz ünlem işareti olan kırmızı bir daire görüntülenir. Bu, hem satır hem de hücre doğrulama hataları için oluşur. İlişkili hata iletisi bir Araç İpucu'nda görüntülenir.

    <DataGrid.RowValidationErrorTemplate>
      <ControlTemplate>
        <Grid Margin="0,-2,0,-2"
          ToolTip="{Binding RelativeSource={RelativeSource
          FindAncestor, AncestorType={x:Type DataGridRow}},
          Path=(Validation.Errors)[0].ErrorContent}">
          <Ellipse StrokeThickness="0" Fill="Red" 
            Width="{TemplateBinding FontSize}" 
            Height="{TemplateBinding FontSize}" />
          <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" 
            FontWeight="Bold" Foreground="White" 
            HorizontalAlignment="Center"  />
        </Grid>
      </ControlTemplate>
    </DataGrid.RowValidationErrorTemplate>
    

Örnek

Aşağıdaki örnek, hücre ve satır doğrulaması için eksiksiz bir gösterim sağlar. sınıfı, Course işlemleri desteklemek için uygulayan IEditableObject bir örnek veri nesnesi sağlar. Denetim DataGrid , kullanıcıların ESC tuşuna basarak değişiklikleri geri döndürmesini sağlamak için etkileşim IEditableObject kurar.

Dekont

Visual Basic kullanıyorsanız MainWindow.xaml dosyasının ilk satırında değerini ile x:Class="MainWindow"değiştirinx:Class="DataGridValidation.MainWindow".

Doğrulamayı test etmek için aşağıdakileri deneyin:

  • Kurs Kimliği sütununa tamsayı olmayan bir değer girin.

  • Bitiş Tarihi sütununa Başlangıç Tarihinden önceki bir tarih girin.

  • Kurs Kimliği, Başlangıç Tarihi veya Bitiş Tarihi'ndeki değeri silin.

  • Geçersiz bir hücre değerini geri almak için imleci hücreye geri getirin ve ESC tuşuna basın.

  • Geçerli hücre düzenleme modundayken satırın tamamında yapılan değişiklikleri geri almak için ESC tuşuna iki kez basın.

  • Doğrulama hatası oluştuğunda, ilişkili hata iletisini görmek için fare işaretçinizi satır üst bilgisindeki göstergenin üzerine getirin.

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace DataGridValidation
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            dataGrid1.InitializingNewItem += (sender, e) =>
            {
                Course newCourse = e.NewItem as Course;
                newCourse.StartDate = newCourse.EndDate = DateTime.Today;
            };
        }
    }

    public class Courses : ObservableCollection<Course>
    {
        public Courses()
        {
            this.Add(new Course
            {
                Name = "Learning WPF",
                Id = 1001,
                StartDate = new DateTime(2010, 1, 11),
                EndDate = new DateTime(2010, 1, 22)
            });
            this.Add(new Course
            {
                Name = "Learning Silverlight",
                Id = 1002,
                StartDate = new DateTime(2010, 1, 25),
                EndDate = new DateTime(2010, 2, 5)
            });
            this.Add(new Course
            {
                Name = "Learning Expression Blend",
                Id = 1003,
                StartDate = new DateTime(2010, 2, 8),
                EndDate = new DateTime(2010, 2, 19)
            });
            this.Add(new Course
            {
                Name = "Learning LINQ",
                Id = 1004,
                StartDate = new DateTime(2010, 2, 22),
                EndDate = new DateTime(2010, 3, 5)
            });
        }
    }

    public class Course : IEditableObject, INotifyPropertyChanged
    {
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (_name == value) return;
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        private int _number;
        public int Id
        {
            get
            {
                return _number;
            }
            set
            {
                if (_number == value) return;
                _number = value;
                OnPropertyChanged("Id");
            }
        }

        private DateTime _startDate;
        public DateTime StartDate
        {
            get
            {
                return _startDate;
            }
            set
            {
                if (_startDate == value) return;
                _startDate = value;
                OnPropertyChanged("StartDate");
            }
        }

        private DateTime _endDate;
        public DateTime EndDate
        {
            get
            {
                return _endDate;
            }
            set
            {
                if (_endDate == value) return;
                _endDate = value;
                OnPropertyChanged("EndDate");
            }
        }

        #region IEditableObject

        private Course backupCopy;
        private bool inEdit;

        public void BeginEdit()
        {
            if (inEdit) return;
            inEdit = true;
            backupCopy = this.MemberwiseClone() as Course;
        }

        public void CancelEdit()
        {
            if (!inEdit) return;
            inEdit = false;
            this.Name = backupCopy.Name;
            this.Id = backupCopy.Id;
            this.StartDate = backupCopy.StartDate;
            this.EndDate = backupCopy.EndDate;
        }

        public void EndEdit()
        {
            if (!inEdit) return;
            inEdit = false;
            backupCopy = null;
        }

        #endregion

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

    }

    public class CourseValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value,
            System.Globalization.CultureInfo cultureInfo)
        {
            Course course = (value as BindingGroup).Items[0] as Course;
            if (course.StartDate > course.EndDate)
            {
                return new ValidationResult(false,
                    "Start Date must be earlier than End Date.");
            }
            else
            {
                return ValidationResult.ValidResult;
            }
        }
    }
}
Imports System.Collections.ObjectModel
Imports System.ComponentModel

Public Class MainWindow

    Private Sub dataGrid1_InitializingNewItem(ByVal sender As System.Object, _
        ByVal e As System.Windows.Controls.InitializingNewItemEventArgs) _
        Handles dataGrid1.InitializingNewItem

        Dim newCourse As Course = CType(e.NewItem, Course)
        newCourse.StartDate = DateTime.Today
        newCourse.EndDate = DateTime.Today

    End Sub

End Class

Public Class Courses
    Inherits ObservableCollection(Of Course)

    Sub New()
        Me.Add(New Course With { _
            .Name = "Learning WPF", _
            .Id = 1001, _
            .StartDate = New DateTime(2010, 1, 11), _
            .EndDate = New DateTime(2010, 1, 22) _
        })
        Me.Add(New Course With { _
            .Name = "Learning Silverlight", _
            .Id = 1002, _
            .StartDate = New DateTime(2010, 1, 25), _
            .EndDate = New DateTime(2010, 2, 5) _
        })
        Me.Add(New Course With { _
            .Name = "Learning Expression Blend", _
            .Id = 1003, _
            .StartDate = New DateTime(2010, 2, 8), _
            .EndDate = New DateTime(2010, 2, 19) _
        })
        Me.Add(New Course With { _
            .Name = "Learning LINQ", _
            .Id = 1004, _
            .StartDate = New DateTime(2010, 2, 22), _
            .EndDate = New DateTime(2010, 3, 5) _
        })
    End Sub

End Class

Public Class Course
    Implements IEditableObject, INotifyPropertyChanged

    Private _name As String
    Public Property Name As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            If _name = value Then Return
            _name = value
            OnPropertyChanged("Name")
        End Set
    End Property

    Private _number As Integer
    Public Property Id As Integer
        Get
            Return _number
        End Get
        Set(ByVal value As Integer)
            If _number = value Then Return
            _number = value
            OnPropertyChanged("Id")
        End Set
    End Property

    Private _startDate As DateTime
    Public Property StartDate As DateTime
        Get
            Return _startDate
        End Get
        Set(ByVal value As DateTime)
            If _startDate = value Then Return
            _startDate = value
            OnPropertyChanged("StartDate")
        End Set
    End Property

    Private _endDate As DateTime
    Public Property EndDate As DateTime
        Get
            Return _endDate
        End Get
        Set(ByVal value As DateTime)
            If _endDate = value Then Return
            _endDate = value
            OnPropertyChanged("EndDate")
        End Set
    End Property

#Region "IEditableObject"

    Private backupCopy As Course
    Private inEdit As Boolean

    Public Sub BeginEdit() Implements IEditableObject.BeginEdit
        If inEdit Then Return
        inEdit = True
        backupCopy = CType(Me.MemberwiseClone(), Course)
    End Sub

    Public Sub CancelEdit() Implements IEditableObject.CancelEdit
        If Not inEdit Then Return
        inEdit = False
        Me.Name = backupCopy.Name
        Me.Id = backupCopy.Id
        Me.StartDate = backupCopy.StartDate
        Me.EndDate = backupCopy.EndDate
    End Sub

    Public Sub EndEdit() Implements IEditableObject.EndEdit
        If Not inEdit Then Return
        inEdit = False
        backupCopy = Nothing
    End Sub

#End Region

#Region "INotifyPropertyChanged"

    Public Event PropertyChanged As PropertyChangedEventHandler _
        Implements INotifyPropertyChanged.PropertyChanged

    Private Sub OnPropertyChanged(ByVal propertyName As String)
        RaiseEvent PropertyChanged(Me, _
           New PropertyChangedEventArgs(propertyName))
    End Sub

#End Region

End Class

Public Class CourseValidationRule
    Inherits ValidationRule

    Public Overrides Function Validate(ByVal value As Object, _
        ByVal cultureInfo As System.Globalization.CultureInfo) _
        As ValidationResult

        Dim course As Course = _
            CType(CType(value, BindingGroup).Items(0), Course)

        If course.StartDate > course.EndDate Then
            Return New ValidationResult(False, _
                "Start Date must be earlier than End Date.")
        Else
            Return ValidationResult.ValidResult
        End If

    End Function

End Class
<Window x:Class="DataGridValidation.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:DataGridValidation"
  Title="DataGrid Validation Example" Height="240" Width="600">

  <Grid>

    <Grid.Resources>
      <local:Courses x:Key="courses"/>
    </Grid.Resources>

    <DataGrid Name="dataGrid1" FontSize="20" RowHeaderWidth="27"
      ItemsSource="{StaticResource courses}" 
      AutoGenerateColumns="False">

      <DataGrid.Resources>
        <Style x:Key="errorStyle" 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 Header="Course Name" 
          Binding="{Binding Name, TargetNullValue=(enter a course name)}"/>
        <DataGridTextColumn Header="Course ID"
          EditingElementStyle="{StaticResource errorStyle}"
          Binding="{Binding Id, ValidatesOnExceptions=True}"/>
        <DataGridTextColumn Header="Start Date"
          EditingElementStyle="{StaticResource errorStyle}"
          Binding="{Binding StartDate, ValidatesOnExceptions=True, 
            StringFormat=d}"/>
        <DataGridTextColumn Header="End Date"
          EditingElementStyle="{StaticResource errorStyle}"
          Binding="{Binding EndDate, ValidatesOnExceptions=True,
            StringFormat=d}"/>
      </DataGrid.Columns>

      <DataGrid.RowValidationRules>
        <local:CourseValidationRule 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 StrokeThickness="0" Fill="Red" 
              Width="{TemplateBinding FontSize}" 
              Height="{TemplateBinding FontSize}" />
            <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" 
              FontWeight="Bold" Foreground="White" 
              HorizontalAlignment="Center"  />
          </Grid>
        </ControlTemplate>
      </DataGrid.RowValidationErrorTemplate>

    </DataGrid>

  </Grid>
</Window>

Ayrıca bkz.