Compartilhar via


Este artigo foi traduzido por máquina.

Pontos de dados

Validação de dados com o Silverlight 3 e o DataForm

JOHN PAPA

Criação de aplicativos Silverlight robustos que editar e validam dados ficou muito mais fácil com a introdução do controle DataForm no Silverlight 3. O controle DataForm contém vários recursos para ajudar a criar formulários que permitem adicionar, editar, excluir e navegar por conjuntos de dados. As vantagens de maiores do DataForm são suas opções de flexibilidade e personalização.

Na coluna ’s deste mês, Vou mostrar como o controle DataForm funciona e como ele pode ser personalizado e demonstrá-lo em ação. Começo, apresentando um aplicativo de exemplo que usa vários recursos para vincular, navegar, editar e validar dados usando o DataForm. Em seguida, eu percorrer como funciona o aplicativo de exemplo, ao destacando os requisitos básicos para usar o controle e personalizações que recomendo. Embora os DataAnnotations não são necessários pelo DataForm, eles podem influenciar a aparência, aspectos de validação e o comportamento do DataForm. O DataAnnotations também podem indicar um método de validação personalizada a ser chamado para uma propriedade ou uma entidade inteira. Mostrarei como implementar o DataAnnotations em uma entidade e como escrever seus próprios métodos PAPAvalidation personalizados. Todos os código deste artigo pode ser baixado do MSDN Code Gallery (msdn.microsoft.com/mag200910DataPoints).

O que ’s o Endgame?

Antes de mergulhar no código, let’s dê uma olhada no aplicativo de exemplo que demonstra a navegação, validação e recursos de edição do DataForm. A Figura 1 mostra um DataGrid exibindo uma lista de funcionários e uma DataForm onde cada registro de funcionário pode ser editado. Os funcionários do DataGrid podem ser navegados, alterando o que é o funcionário selecionado no momento. O DataForm é vinculado ao mesmo conjunto de funcionários e recebe esse funcionário.

Toolbar

DataForm mostrado na 1 figura foi colocado no modo de edição para o usuário pode fazer alterações e um salvar ou cancelá-las. A barra de ferramentas no canto direito superior do DataForm mostra ícones para edição (lápis), adicionando um novo registro (sinal de mais) e excluir um registro (o sinal de subtração). Esses botões podem ser formatados e desabilitados conforme necessário. Estado dos botões do é determinado pelas interfaces implementadas pela entidade, enquanto sua visibilidade pode ser personalizada definindo propriedades sobre o DataForm.

Rótulos

As legendas de cada TextBox no DataForm podem ser colocadas ao lado ou acima do controle. O conteúdo dos rótulos de pode ser usando o atributo exibir DataAnnotations controlados por metadados. Os atributos DataAnnotations são colocados nas propriedades de entidade, nesse caso, a entidade de funcionário, onde elas ajudam a informações DataForm, como o texto para exibir os rótulos de campo de feed.

DescriptionViewer

Quando o DataForm está no modo de edição (como mostrado no do Figura 1), o usuário pode focalizar o ícone ao lado para a legenda ao lado de cada controle TextBox para ver uma dica de ferramenta que fornece mais informações sobre o que digitar no campo. Esse recurso é implementado pela DataForm quando você coloca um controle DescriptionViewer ao lado do controle TextBox acoplado. O texto exibido na dica de ferramenta do DescriptionViewer também é alimentado pela atributo DataAnnotations exibir.


Figura 1 validação e editando com o DataForm

Cancelar e confirmação

O botão Cancelar na parte inferior da DataForm é ativado quando no modo de edição. Botão Salvar é ativado quando no modo de edição e um usuário altera um valor no DataForm. O texto e estilos para esses botões podem ser personalizados.


Figura 2 DataForm fora do caixa

Notificação de validação

NotificationThe DataForm no exemplo é mostrado no estado de edição onde o usuário tiver digitado em um endereço de email inválido e o número de telefone. Observe que as legendas de campo para os campos invalidados estão em vermelho e as caixas de texto são com borda em vermelho com um sinalizador vermelho no canto superior direito. Quando um usuário coloca o cursor em um controle invalidado, uma dica de ferramenta é exibida com uma mensagem descrevendo o que precisa ser feito para corrigir o problema. A Figura 1 também mostra uma lista os erros de validação na parte inferior da tela. Todos esses recursos são suportados pelo DataForm e DataAnnotations e podem usar estilos personalizados para dar uma aparência personalizada. As regras de validação são alimentadas de vários DataAnnotations para indicar gravadas regras, como campos obrigatórios ou regras personalizadas.

Criando o DataForm

DataForm, encontrado no Kit de ferramentas Silverlight, pode ser adicionada a um projeto uma vez o assembly que foi referenciado System.Windows.Controls.Data.DataForm.Toolkit.dll. O DataForm pode ser criado com muito pouca configuração. Uma vez arrastadas para a superfície de design no Blend ou criado no XAML — simplesmente definindo o ItemsSource do DataForm a uma coleção de entidades — o DataForm gerará automaticamente os campos para exibir e, em seguida, habilitar recursos de edição apropriados. O seguinte XAML irá gerar DataForm mostrado na do Figura 2:

<dataFormToolkit:DataForm x:Name="dataForm" ItemsSource="{Binding Mode=OneWay}" />

Observação: O modo de ligação é definido como OneWay no exemplo anterior somente para fins explícitas. Não é necessário. No entanto, acho útil para fins de esclarecimento e capacidade de suporte definir explicitamente o modo de ligação.

Configurações adicionais podem ser conectadas a DataForm para refinar sua funcionalidade. As configurações comuns incluem os mostrados na do Figura 3.

Figura 3 comuns DataForm personalizações

Geralmente, é vantajoso estilo recursos visuais ’s DataForm para coordenar a aparência visual do seu aplicativo. Vários aspectos do DataForm podem ser formatados usando os recursos no documento, app.xaml ou um dicionário de recurso. Existem vários estilos que podem ser definidos, conforme mostrado no Figura 4 na captura de tela parcial do Expression Blend. Observe CancelButtonStyle e o CommitButtonStyle estiverem definida como um valor. Este é o que acontece os botões de aparência azul como mostrado na parte inferior da tela no 1 figura. DataForm próprio pode ser formatado, definindo a propriedade Style. Aspectos individuais da DataForm, como o DataField ou ValidationSummary, também podem ser formatados.

Definindo algumas dessas propriedades mais comuns do DataForm, assim como alguns estilos básicos, podemos obter a aparência e funcionalidade exibido no do Figura 1. As configurações para o aplicativo de exemplo incluído neste artigo são mostradas no do Figura 5. Observe que AutoEdit e AutoCommit são ambos definida como false, exigindo, portanto, o DataForm explicitamente ser colocados em modo de edição, o usuário clicar no botão Editar na barra de ferramentas, e que o usuário clicar no botão Salvar para confirmar as alterações.


Figura 4 determinando estilo o DataForm

O botão de navegação é omitido da propriedade CommandButtonsVisibility, que significa que a barra de ferramentas não mostrará as opções de navegação. Se incluímos esta opção, adicionando a palavra-chave navegação o CommandButtonsVisibility ou alterando a configuração para a palavra-chave ALL, o DataForm também mostra os botões da barra de ferramentas de navegação. Como os botões de confirmação e Cancel estiverem incluídos na propriedade CommandButtonsVisibility, eles estarão visíveis. Enquanto o DataForm ainda não foi editada, o botão Cancelar será desabilitado conforme do Figura 6. Os botões de navegação permite ao usuário mover o conjunto de registros. No entanto, neste exemplo de aplicativo, os usuários também podem navegar usando o DataGrid ligados a dados, desde que ele também está vinculado ao mesmo conjunto de dados como o DataForm. Portanto, Eu desativei os botões de navegação na barra de ferramentas puramente como uma opção de design, porque a funcionalidade de navegação já pode ser conseguida através do DataGrid.

DataAnnotations

Muita a funcionalidade do DataForm é orientada pelos atributos DataAnnotations colocados nos dados de entidade vinculados a DataForm. Os DataAnnotations estarão disponíveis quando você referência ao assembly System.ComponentModel.DataAnnotations.dll. O DataForm examina os atributos e aplica-las de acordo. Figura 7 mostra vários atributos de DataAnnotations podem decorar propriedades de uma entidade e descreve seu efeito.

Figura 5 personalizando o DataForm

<dataFormToolkit:DataForm x:Name="dataForm"
                 ItemsSource="{Binding Mode=OneWay}"
                 BorderThickness="0"
                 FontFamily="Trebuchet MS" FontSize="13.333"
                 CommitButtonContent="Save"
                 CancelButtonContent="Cancel"
                 Header="Employee Details"
                 AutoEdit="False"
                 AutoCommit="False"
                 AutoGenerateFields="True"
                 CommandButtonsVisibility="Edit, Add, Delete, Commit, Cancel"
                 CommitButtonStyle="{StaticResource ButtonStyle}"
                 CancelButtonStyle="{StaticResource ButtonStyle}"
                 DescriptionViewerPosition="BesideLabel"
                 LabelPosition="Left" />

O atributo exibir feeds ’s DataForm Label e DescriptionViewer com os parâmetros nome e descrição, respectivamente. Se omitido, o DataForm gera automaticamente esses valores para os controles usando o nome da propriedade. Observe no Figura 8 que nome propriedade a entidade ’s funcionário está decorada com atributos DataAnnotations 3. O atributo de exibição indica que o rótulo deve exibir o texto “ nome ” e o DescriptionViewer deve mostrar uma dica de ferramenta “ ’s funcionário primeiro nome ”.

O atributo Required indica que um valor deve ser inserido para a propriedade nome. O atributo Required, como todos os atributos de validação, aceita um parâmetro ErrorMessage. O parâmetro ErrorMessage indica a mensagem que será exibida em uma dica de ferramenta para o controle invalidado e no controle ValidationSummary in a DataForm. O atributo StringLength para a propriedade de nome é definido para indicar que o campo não pode exceder 40 caracteres e, em caso afirmativo, uma mensagem de erro será exibida.

O código no do Figura 8 mostra que, quando um valor é definido na propriedade, o método Validate é chamado. Validar é um método que criei na classe base ModelBase usei para todas as entidades neste exemplo. Esse método valida a propriedade verificando-lo contra todos os seus atributos DataAnnotations. Se algum deles falhar, ele lança uma exceção, não definir a propriedade para o valor inválido e direciona DataForm para notificar o usuário. A Figura 1 mostra os resultados de esvaziar o campo nome, pois é necessário.

Validar método a classe ’s ModelBase é invocado em cada setter de propriedade para que cada propriedade pode ser validada quando definida. O método aceita o novo valor e o nome da propriedade que está sendo validado. Esses parâmetros são passados por sua vez para o validador ’s ValidateProperty método classe, que faz a validação real no valor de propriedade:

protected void Validate(object value,
string propertyName) {
Validator.ValidateProperty(value,
new ValidationContext(this, null, null) {
MemberName = propertyName });
}

O validador é uma classe estática que permite que você execute validação usando várias técnicas diferentes:

  • O método ValidateProperty verifica valores de uma única propriedade e lança DataAnnotations.ValidationException se o valor é inválido.
  • O método ValidateObject verifica todas as propriedades da entidade inteira e lança DataAnnotations.ValidationException se qualquer valor é inválido.
  • O método TryValidateProperty executa as mesma verificações de validação como ValidateProperty, exceto que ele retorna um valor Boolean em vez de gerar uma exceção.
  • O método TryValidateObject executa as mesma verificações de validação como ValidateObject, exceto que ele retorna um valor Boolean em vez de gerar uma exceção.
  • O método ValidateValue aceita um valor e uma coleção de atributos de validação. Se o valor falhar qualquer um dos atributos, um ValidationException é lançada.
  • O método TryValidateValue executa as mesma verificações de validação como ValidateValue, exceto que ele retorna um valor Boolean em vez de gerar uma exceção.

Figura 7 comuns DataAnnotations

Figura 8 propriedade de nome com DataAnnotations

private string firstName;
[Required(ErrorMessage = "Required field")]
[StringLength(40, ErrorMessage = "Cannot exceed 40")]
[Display(Name = "First Name", Description = "Employee's first name")]
public string FirstName
{
get { return firstName; }
set
{
if (firstName == value) return;
var propertyName = "FirstName";
Validate(value, propertyName);
firstName = value;
FirePropertyChanged(propertyName);
}
}

Também criei um método na classe ModelBase chamada IsValid, que chama o método TryValidateObject, como mostrado abaixo. Este método pode ser chamado na entidade a qualquer momento para determinar se ele está em um estado válido:

public bool IsValid() {
return Validator.TryValidateObject(this,
new ValidationContext(this, null, null),
this.validationResults, true);
}

Figura 9 de de validação de propriedade personalizada

public static class EmployeeValidator
{
public static ValidationResult ValidateAge(int age)
{
if (age > 150)
return new ValidationResult("Employee's age must be under 150.");
else if (age <= 0)
return new ValidationResult(
"Employee's age must be greater than 0.");
else
return ValidationResult.Success;
}
}

Validação personalizada

Quando um atributo gravado do conjunto de DataAnnotations não suficiente, você pode criar um método de validação personalizada e aplique-o para um objeto inteiro ou para um valor de propriedade. O método de validação deve ser estáticos e retornar um objeto ValidationResult. O objeto ValidationResult é o veículo que contém a mensagem que será acoplada a DataForm. Figura 9 mostra o método de validação personalizada ValidateAge, que verifica se o valor está entre 0 e 150. Esse é um exemplo simples, e um atributo de intervalo poderia ter sido usado. No entanto, criar um método específico permite que ele ser reutilizado por várias entidades para validação.

Métodos de validação personalizada também podem ser criados para validar um objeto inteiro. O método ValidateEmployee aceita a entidade inteira funcionário e examina várias propriedades em determinar se a entidade é em um estado válido. Isso é muito útil para aplicar validação de nível de entidade, como mostrado abaixo:

public static ValidationResult ValidateEmployee(Employee emp) {
string[] memberNames = new string[] { "Age", "AnnualSalary" };
if (emp.Age >= 50 && emp.AnnualSalary < 50000)
return new ValidationResult(
"Employee is over 50 and must make more than $50,000.",
memberNames);
else
return ValidationResult.Success;
}

O controle de resumo de validação é exibido pela DataForm quando um ou mais ValidationExceptions são lançadas (consulte do Figura 10). O nome do campo é realçado em negrito lettering enquanto a mensagem de validação é exibida ao lado dele. O estilo para o ValidationSummary também pode ser personalizado para usar um recurso, se desejado.


Figura 10 Resumo de validação

Influencers

O DataForm leva seu indicação de DataAnnotations bem como de interfaces que implementa sua fonte de dados ligada. Por exemplo, a entidade de funcionário implementa a interface IEditableObject. Essa interface força a implementação dos métodos BeginEdit CancelEdit e EndEdit que são chamados pelo DataForm tempo apropriado enquanto o DataForm está sendo editado. No aplicativo de exemplo, usei esses métodos para implementar um comportamento de ' Cancelar ' para que o usuário possa pressione o botão Cancelar e restaurar os valores originais de entidade.

Esse comportamento é obtido criando uma instância da entidade no método BeginEdit (cache nomeado) e copiando os valores originais da entidade. O método EndEdit limpa o objeto do cache enquanto o método CancelEdit copia todos os formulário valores a entidade de cache de volta para a entidade original, restaurando portanto seu estado original.

Quando o DataForm vê que a coleção que está vinculado a é um CollectionViewSource, ele oferecerá suporte a edição, classificação, filtragem e controlar o registro atual (também conhecido como moeda). O recurso de moeda é importante, pois ele também garante que o DataForm não permite que um usuário navegar fora de um estado inválido de entidade sem corrigi-lo e confirmar ou cancelar as alterações. Vinculando o DataForm a um PagedCollectionView também fornece desses mesmos recursos e também oferece a exclusão de um item, adicionando um item e agrupando os itens. Ligação para uma ObservableCollection desativará a alguns desses recursos, como por conta própria a ObservableCollection não implementa as interfaces que o DataForm procura.

Se suas entidades já estão contidas em uma ObservableCollection, você poderá criar um PagedCollectionView passando a instância ObservableCollection na coleção por seu construtor, como mostrado abaixo:

var employees = new DataService().GetPeople();
PagedCollectionView view = new PagedCollectionView(employees);
this.DataContext = view;

Como alternativa, você pode criar um CollectionViewSource passando ObservableCollection de funcionários inicializador de coleta ’s CollectionViewSource e definindo a propriedade Source, como mostrado abaixo:

var employees = new DataService().GetPeople();
CollectionViewSource view = new CollectionViewSource
{Source = employees};
this.DataContext = view;

Resumo

O DataForm adiciona muita de valor para aplicativos e para o processo normalmente código intensivos e monotonous de navegação, edição e exibição de dados. Seus recursos são personalizáveis para atender às suas necessidades e pode ser formatado visualmente para combinar com design ’s seu aplicativo.

John Papa (johnpapa.net) é um consultor sênior e um fanático por beisebol, que passa a maioria pelos Yankees com sua família noites de verão. Papa, MVP Silverlight, Silverlight Insider e INETA, escreveu vários livros, incluindo seu mais recente, “ serviços baseados em dados com o Silverlight 2 ” (O’Reilly, 2009). Ele costuma palestras em congressos como VSLive!, DevConnections e MIX.