Для тестирования создадим Silverlight 3 приложение и добавим модель данных
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace BlendWorld.Silverlight3.ComponentModelSample
{
public class Person : INotifyPropertyChanged
{
public static List<Person> GetPeoples()
{
return new List<Person>
{
new Person {FirstName = "Tim", LastName = "Franklin", City = "New York", Age = 18, Phone = "111-111-1111"},
new Person {FirstName = "Lisa", LastName = "Washington", City = "Chicago", Age = 20, Phone = "222-222-2222"},
new Person {FirstName = "Zoe", LastName = "Johnson", City = "Miami", Age = 35, Phone = "333-333-3333"},
new Person {FirstName = "Zane", LastName = "Franklin", City = "Seattle", Age = 19, Phone = "444-444-4444"},
new Person {FirstName = "Jack", LastName = "Washington", City = "New York", Age = 40, Phone = "555-555-5555"},
new Person {FirstName = "Jean", LastName = "Johnson", City = "Chicago", Age = 32, Phone = "666-666-6666"},
new Person {FirstName = "Jessika", LastName = "Franklin", City = "Miami", Age = 27, Phone = "777-777-7777"},
new Person {FirstName = "Jean", LastName = "Johnson", City = "Seattle", Age = 25, Phone = "888-888-8888"},
};
}
string firstName;
string lastName;
int age;
string city;
string phone;
DateTime birthDate;
public string FirstName
{
get
{
return firstName;
}
set
{
if (firstName != value)
{
firstName = value;
OnPropertyChanged("FirstName");
}
}
}
public string LastName
{
get
{
return lastName;
}
set
{
if (lastName != value)
{
lastName = value;
OnPropertyChanged("LastName");
}
}
}
public int Age
{
get
{
return age;
}
set
{
if (age != value)
{
age = value;
OnPropertyChanged("Age");
}
}
}
public string City
{
get
{
return city;
}
set
{
if (city != value)
{
city = value;
OnPropertyChanged("City");
}
}
}
public string Phone
{
get
{
return phone;
}
set
{
if (phone != value)
{
phone = value;
OnPropertyChanged("Phone");
}
}
}
public string FullName
{
get
{
return string.Format("{0} {1}", firstName, lastName);
}
}
#region INotifyPropertyChanged Members
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}
Добавим DataGrid в MainPage (незабываем про референс на сборку System.Windows.Controls.Data)
<UserControl x:Class="BlendWorld.Silverlight3.ComponentModelSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
Width="600" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid ItemsSource="{Binding}">
</data:DataGrid>
</Grid>
</UserControl>
Сортировка
Добавим в наш DataGrid сортировку по умолчанию, это делается с помощью свойства DataGrid.SortDescriptions
<UserControl x:Class="BlendWorld.Silverlight3.ComponentModelSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=System.Windows"
Width="630" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid ItemsSource="{Binding}">
<data:DataGrid.SortDescriptions>
<scm:SortDescription PropertyName="Age" Direction="Descending"/>
<scm:SortDescription PropertyName="FullName" Direction="Ascending"/>
</data:DataGrid.SortDescriptions>
</data:DataGrid>
</Grid>
</UserControl>
Получаем обратную сортировку по возрасту и прямую по полному имени
Группировка
Для группировки необходимо добавить референс на новую сборку System.ComponentModel. Сгруппируем данные по полю City, для этого воспользуемся свойством DataGrid.GroupDescriptions
<UserControl x:Class="BlendWorld.Silverlight3.ComponentModelSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
xmlns:cm="clr-namespace:System.Windows.Data;assembly=System.ComponentModel"
Width="630" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid ItemsSource="{Binding}">
<data:DataGrid.GroupDescriptions>
<cm:PropertyGroupDescription PropertyName="City" />
</data:DataGrid.GroupDescriptions>
</data:DataGrid>
</Grid>
</UserControl>
Проверка
Для проверки данных в Silverlight 3 введена сборка System.ComponentModel.DataAnnotations. Простейший способ - это вызвать исключение ValidationException из сборки.
Изменим код свойства FirstName следующим образом:
public string FirstName
{
get
{
return firstName;
}
set
{
if (firstName != value)
{
if (string.IsNullOrEmpty(value))
{
throw new ValidationException("First Name cannot be empty");
}
firstName = value;
OnPropertyChanged("FirstName");
}
}
}
Теперь при неправильном заполнение получаем сообщение
Второй способ - это задать проверку с помощью атрибутов, добавим проверку возраста на попадание в диапазон
[Required]
[Range(18, 50)]
public int Age
{
get
{
return age;
}
set
{
if (age != value)
{
age = value;
OnPropertyChanged("Age");
}
}
}
Если хотим делать проверку в момент изменения данных, необходимо добавить вызов метода Validator.ValidateProperty
[Required]
[Range(18, 50)]
public int Age
{
get
{
return age;
}
set
{
if (age != value)
{
Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Age" });
age = value;
OnPropertyChanged("Age");
}
}
}
Также можно сделать проверку при помощи регулярных выражений, сделаем проверку телефона
[Required]
[RegularExpression("\\d{3}[-]\\d{3}[-]\\d{4}", ErrorMessage = "Invalid phone")]
public string Phone
{
get
{
return phone;
}
set
{
if (phone != value)
{
Validator.ValidateProperty(value, new ValidationContext(this, null, null) { MemberName = "Phone" });
phone = value;
OnPropertyChanged("Phone");
}
}
}
Также существует возможность пользовательской проверки обьекта данных. Добавим поле BirthDate
public DateTime BirthDate
{
get
{
return birthDate;
}
set
{
if (birthDate != value)
{
birthDate = value;
OnPropertyChanged("BirthDate");
}
}
}
А теперь сделаем проверку дня рождение на соответствие возрасту, для этого необходимо создать класс для проверки
public static class PersonValidator
{
public static bool IsValidBirthDay(object personObject, ValidationContext context, out ValidationResult validationResult)
{
validationResult = null;
var person = personObject as Person;
int dateComparison = person.BirthDate.CompareTo(DateTime.Today);
if (dateComparison > 1)
{
var properties = new List<string> { "BirthDate" };
validationResult = new ValidationResult("Birthday cannot be further than today!", properties);
}
return !(dateComparison > 1);
}
public static bool IsValidBirthDayAge(object personObject, ValidationContext context, out ValidationResult validationResult)
{
validationResult = null;
var person = personObject as Person;
int age = DateTime.Today.Year - person.BirthDate.Year;
if (age != person.Age)
{
var properties = new List<string> { "Age", "BirthDate" };
validationResult = new ValidationResult("Age does not match with Birthday! Your age should be " + age, properties);
}
return (age == person.Age);
}
}
и добавить необходимые атрибуты к классу Person
[CustomValidation(typeof(PersonValidator), "IsValidBirthDay")]
[CustomValidation(typeof(PersonValidator), "IsValidBirthDayAge")]
public class Person : INotifyPropertyChanged
Теперь при неправильном вводе получаем сообщение
Живая демонстрация
Скачать исходный код: BlendWorld.Silverlight3.ComponentModelSample.zip (20,27 kb)
aa94b97b-ec8b-46d7-85d6-0abeb15f890f|0|.0
Метки:
silverlight,
samples
Категории:
Silverlight in Action