Практическое руководство. Реализация проверки с помощью элемента управления DataGrid
Data
Следующие процедуры описывают способы применения правил проверки к Data
Чтобы проверить значения отдельных ячеек
Укажите одно или несколько правил проверки для привязки, используемой со столбцом. Это аналогично проверке данных в простые элементы управления, как описано в разделе Общие сведения о привязке данных.
В следующем примере показан Data
Grid элемента управления с четырьмя столбцами, которые привязаны к различным свойствам бизнес-объекта. Укажите трех столбцов ExceptionValidation , задав ValidatesRule On свойстваExceptions 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>
Когда пользователь вводит недопустимое значение (например, отличный от integer в столбце идентификатор курса), появится красная граница вокруг ячейки. Вы можете изменить эти отзывы проверки по умолчанию, как описано в следующей процедуре.
Настройка сигнала о проверке ячейки
Значение столбца Editing
Element свойство на стиль, соответствующий столбец редактирования элемента управления. Так как элементы управления создаются во время выполнения, нельзя использовать Validation.Style Error присоединенного свойства, как с помощью простых элементов управления.Template В следующем примере обновляется предыдущего примера, добавив стиля ошибки, применяемое для трех столбцов с помощью правил проверки. Когда пользователь вводит недопустимое значение, стиль изменяет цвет фона ячейки и добавляет всплывающей подсказки. Обратите внимание на использование триггера, чтобы определить, имеется ли ошибка проверки. Это необходимо, поскольку в настоящее время отсутствует специальный шаблон ошибок для ячеек.
<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>
Можно реализовать дополнительную настройку, заменив Cell
Style используемый столбцом.
Для проверки нескольких значений в одной строке
Реализуйте Validation
Rule подкласса, который проверяет несколько свойств объекта привязки данных. В вашей Validate привести реализацию методаvalue
значение параметра для BindingGroup экземпляра. Вы можете обращаться к объекту данных, используя Items свойство.В следующем примере демонстрируется этот процесс проверки ли
StartDate
значение свойства дляCourse
объекта более ранняя, чем егоEndDate
значение свойства.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; } } }
Добавить правило проверки к Data
Grid. коллекции. RowRow Validation Rules Validation Свойство обеспечивает прямой доступ к ValidationRules Rules свойство BindingGroup экземпляр, который группирует все привязки, используемые элементом управления.В следующем примере задается Row
Validation свойства в XAML. ValidationRules Step Свойству UpdatedValue таким образом, чтобы проверка осуществляется только после обновления объект привязанных данных.<DataGrid.RowValidationRules> <local:CourseValidationRule ValidationStep="UpdatedValue"/> </DataGrid.RowValidationRules>
Когда пользователь указывает дату окончания, более ранняя, чем дата начала, в заголовке строки появляется красный восклицательный знак (!). Вы можете изменить эти отзывы проверки по умолчанию, как описано в следующей процедуре.
Настройка сигнала о проверке строки
Задайте свойство Data
Grid. . Это свойство позволяет настраивать сигнала о проверке строки для отдельных DataRow Validation Error Template Grid элементов управления. Могут также влиять на несколько элементов управления с помощью неявный стиль строки для установки DataGrid свойство.Row. Validation Error Template В следующем примере заменяется сигнала о проверке строки по умолчанию с более заметный индикатор. Когда пользователь вводит недопустимое значение, красный круг с белым восклицательным знаком отображается в заголовке строки. Эта операция выполняется для ошибок проверки строк и ячеек. Сообщение об ошибке отображается во всплывающей подсказке.
<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>
Пример
Следующий пример приводится полная демонстрация проверки ячеек и строк. Course
Класс предоставляет образец данных объект, реализующий IEditable
Note
Если вы используете Visual Basic, в первой строке файла MainWindow.XAML, замените x:Class="DataGridValidation.MainWindow"
с x:Class="MainWindow"
.
Чтобы протестировать проверку, попробуйте сделайте следующее:
В столбце идентификатор курса введите значение отличный от integer.
В столбце даты окончания введите дату, более ранняя, чем дата начала.
Удаление значения в идентификатор курса, Дата начала или дата окончания.
Чтобы отменить недопустимое значение для ячейки, поместите курсор в ячейку и нажмите клавишу ESC.
Чтобы отменить изменения для всей строки, когда текущая ячейка находится в режиме редактирования, дважды нажмите клавишу ESC.
При возникновении ошибки проверки, наведите указатель мыши на индикатор в заголовке строки, чтобы просмотреть сообщение об ошибке.
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;
}
}
}
}
<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>