Nasıl yapılır: DataGrid Denetimi ile Doğrulama Uygulama
DataGridDenetim, hem hücrede hem de satır düzeyinde doğrulama gerçekleştirmenize olanak sağlar. Hücre düzeyinde doğrulamayla, bir Kullanıcı bir değeri güncelleştiriyorsa, bağlantılı bir veri nesnesinin tek tek özelliklerini doğrularsınız. Satır düzeyinde doğrulamayla, bir Kullanıcı bir satıra değişiklik yaptığı zaman tüm veri nesnelerini 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 bildirimini kullanabilirsiniz DataGrid .
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çıklanır.
Bağımsız 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ışbölümünde açıklandığı gibi basit denetimlerde verileri doğrulamaya benzer.
Aşağıdaki örnek, DataGrid bir iş nesnesinin farklı özelliklerine sınırlı dört sütunlu bir denetim gösterir. Sütunun üçü, ExceptionValidationRuleValidatesOnExceptions özelliğini olarak ayarlayarak belirler
true.<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 girdiğinde (kurs KIMLIĞI sütununda tamsayı olmayan gibi), hücrenin etrafında 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 EditingElementStyle özelliğini sütunun Editing denetimine uygun bir stil olarak ayarlayın. Çalışma zamanında düzenlemenin denetimleri oluşturulduğundan, bu Validation.ErrorTemplate özelliği basit denetimlerle yaptığınız gibi kullanamazsınız.
Aşağıdaki örnek, doğrulama kurallarına sahip üç sütun tarafından paylaşılan bir hata stili ekleyerek önceki örneği günceller. Kullanıcı geçersiz bir değer girdiğinde, stil hücre arka plan rengini değiştirir ve bir araç Ipucu ekler. Bir doğrulama hatası olup olmadığını anlamak için tetikleyicinin kullanımını aklınızda yapın. Bu, şu anda hücreler için adanmış bir hata şablonu bulunmadığından 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ütunu tarafından kullanılan öğesini değiştirerek daha kapsamlı özelleştirmeler uygulayabilirsiniz CellStyle .
Tek bir satırdaki birden çok değeri doğrulamak için
ValidationRuleBağlanan veri nesnesinin birden çok özelliğini denetleyen bir alt sınıf uygulayın. ValidateYöntem uygulamanızda
valueparametre değerini bir BindingGroup örneğe atayın. Daha sonra, veri nesnesine özelliği aracılığıyla erişebilirsiniz Items .Aşağıdaki örnek,
StartDatebir nesnenin özellik değerininCourseözellik değerinden daha önce olup olmadığını doğrulamak için bu işlemi gösterirEndDate.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 ClassDoğrulama kuralını DataGrid.RowValidationRules koleksiyona ekleyin. RowValidationRulesÖzelliği, ValidationRulesBindingGroup Denetim tarafından kullanılan tüm bağlamaları gruplandıran bir örnek özelliğine doğrudan erişim sağlar.
Aşağıdaki örnek RowValidationRules xaml 'de özelliğini ayarlar. ValidationStepÖzelliği, UpdatedValue doğrulamanın yalnızca bağlantılı veri nesnesi güncelleştirildikten sonra oluşması için olarak ayarlanır.
<DataGrid.RowValidationRules> <local:CourseValidationRule ValidationStep="UpdatedValue"/> </DataGrid.RowValidationRules>Bir kullanıcı başlangıç tarihinden önceki bir bitiş tarihini belirttiğinde, satır üstbilgisinde kırmızı bir ünlem işareti (!) belirir. 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
Özelliği ayarlayın DataGrid.RowValidationErrorTemplate . Bu özellik ayrı denetimler için satır doğrulama geri bildirimini özelleştirmenizi sağlar DataGrid . Özelliği ayarlamak için örtük bir satır stili kullanarak birden çok denetimi de etkileyebilirsiniz DataGridRow.ValidationErrorTemplate .
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 üstbilgisinde beyaz ünlem işaretine sahip kırmızı bir daire görünür. Bu durum hem satır hem de hücre doğrulama hataları için oluşur. İlişkili hata iletisi bir araç Ipucunda 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ğrulama için kapsamlı bir tanıtım sağlar. CourseSınıfı, işlemleri desteklemek için uygulayan bir örnek veri nesnesi sağlar IEditableObject . DataGridDenetim, IEditableObject kullanıcıların ESC tuşuna basarak değişiklikleri döndürmenize olanak tanımak için ile etkileşime girer.
Not
Visual Basic kullanıyorsanız, MainWindow. xaml ' in ilk satırında x:Class="DataGridValidation.MainWindow" ile değiştirin x:Class="MainWindow" .
Doğrulamayı test etmek için aşağıdakileri deneyin:
Kurs KIMLIĞI sütununda, tamsayı olmayan bir değer girin.
Bitiş tarihi sütununda, başlangıç tarihinden önceki bir tarih girin.
Kurs KIMLIĞI, başlangıç tarihi veya bitiş tarihi değerlerini silin.
Geçersiz bir hücre değerini geri almak için imleci hücreye geri koyun ve ESC tuşuna basın.
Geçerli hücre düzenleme modundayken bir satırın tamamına ait değişiklikleri geri almak için ESC tuşuna iki kez basın.
Bir doğrulama hatası oluştuğunda, ilişkili hata iletisini görmek için fare işaretçinizi satır üstbilgisindeki göstergenin üzerine taşıyın.
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>