Compartilhar via


Visão geral da associação de dados com o Windows Forms

No Windows Forms, você pode se associar não apenas a fontes de dados tradicionais, mas também a quase qualquer estrutura que contenha dados. Você pode associar a uma matriz de valores que você calcula no tempo de execução, lê de um arquivo ou deriva dos valores de outros controles.

Além disso, você pode associar qualquer propriedade de qualquer controle à fonte de dados. Na associação de dados tradicional, você normalmente associa a propriedade de exibição, por exemplo, a propriedade Text de um controle TextBox à fonte de dados. Com o .NET, você também tem a opção de definir outras propriedades por meio da associação. Você pode usar a associação para executar as seguintes tarefas:

  • Definindo o gráfico de um controle de imagem.

  • Definindo a cor da tela de fundo de um ou mais controles.

  • Definindo o tamanho dos controles.

Essencialmente, a associação de dados é uma maneira automática de definir qualquer propriedade acessível em tempo de execução de qualquer controle em um formulário.

ADO.NET permite criar muitas estruturas de dados diferentes para atender às necessidades de associação do aplicativo e aos dados com os quais você está trabalhando. Talvez você queira criar suas próprias classes que fornecem ou consomem dados no Windows Forms. Esses objetos podem oferecer diferentes níveis de funcionalidade e complexidade. Desde a associação de dados básica até o fornecimento de suporte em tempo de design, verificação de erros, notificação de alteração ou até mesmo suporte para uma reversão estruturada das alterações feitas nos próprios dados.

Consumidores de interfaces de associação de dados

As seções a seguir descrevem dois grupos de objetos de interface. O primeiro grupo de interface é implementado em fontes de dados por autores da fonte de dados. Os consumidores da fonte de dados, como os controles ou componentes do Windows Forms, implementam essas interfaces. O segundo grupo de interface foi projetado para ser usado por autores de componentes. Os autores de componentes usam essas interfaces quando estão criando um componente que dá suporte à associação de dados a ser consumida pelo mecanismo de associação de dados do Windows Forms. Você pode implementar essas interfaces em classes associadas ao seu formulário para habilitar a associação de dados. Cada caso apresenta uma classe que implementa uma interface que permite a interação com dados. As ferramentas de experiência de design de dados RAD (desenvolvimento rápido de aplicativos) do Visual Studio já aproveitam essa funcionalidade.

Interfaces para implementação por autores da fonte de dados

Os controles do Windows Forms implementam as seguintes interfaces:

  • Interface IList

    Uma classe que implementa a interface IList pode ser um Array, ArrayListou CollectionBase. Estas são listas indexadas de itens do tipo Object e as listas devem conter tipos homogêneos, pois o primeiro item do índice determina o tipo. IList seria disponibilizado para associação somente em tempo de execução.

    Observação

    Se você quiser criar uma lista de objetos de negócios para associação com o Windows Forms, considere usar o BindingList<T>. O BindingList é uma classe extensível que implementa as interfaces primárias necessárias para associação de dados bidirecionais do Windows Forms.

  • Interface IBindingList

    Uma classe que implementa a interface IBindingList fornece um nível muito maior de funcionalidade de associação de dados. Essa implementação oferece recursos básicos de classificação e notificação de alteração. Ambos são úteis quando os itens de lista são alterados e quando a própria lista é alterada. A notificação de alteração será importante se você planeja ter vários controles associados aos mesmos dados. Ele ajuda você a fazer alterações de dados feitas em um dos controles para propagar para os outros controles associados.

    Observação

    A notificação de alteração está habilitada para a interface IBindingList por meio da propriedade SupportsChangeNotification que, quando true, gera um evento ListChanged, indicando que a lista foi alterada ou um item na lista foi alterado.

    O tipo de alteração é descrito pela propriedade ListChangedType do parâmetro ListChangedEventArgs. Portanto, sempre que o modelo de dados for atualizado, quaisquer exibições dependentes, como outros controles associados à mesma fonte de dados, também serão atualizadas. No entanto, os objetos contidos na lista terão que notificar a lista quando forem alterados para que a lista possa gerar o evento ListChanged.

    Observação

    O BindingList<T> fornece uma implementação genérica da interface IBindingList.

  • Interface IBindingListView

    Uma classe que implementa a interface IBindingListView fornece toda a funcionalidade de uma implementação de IBindingList, juntamente com a filtragem e a funcionalidade de classificação avançada. Essa implementação oferece filtragem baseada em strings e classificação de várias colunas com pares de descritor de propriedade e direção.

  • Interface IEditableObject

    Uma classe que implementa a interface IEditableObject permite que um objeto controle quando as alterações nesse objeto são permanentes. Essa implementação dá suporte aos métodos BeginEdit, EndEdite CancelEdit, que permitem reverter as alterações feitas no objeto. Veja a seguir uma breve explicação do funcionamento dos métodos BeginEdit, EndEdite CancelEdit e como eles funcionam uns com os outros para habilitar uma possível reversão de alterações feitas nos dados:

    • O método BeginEdit sinaliza o início de uma edição em um objeto. Um objeto que implementa essa interface precisará armazenar as atualizações após a chamada do método BeginEdit de modo que as atualizações possam ser descartadas se o método CancelEdit for chamado. Em Windows Forms para associação de dados, você pode chamar BeginEdit várias vezes dentro do escopo de apenas uma transação de edição (por exemplo, BeginEdit, BeginEdit, EndEdit). As implementações de IEditableObject devem acompanhar se BeginEdit já foi chamado e ignorar chamadas subsequentes para BeginEdit. Como esse método pode ser chamado várias vezes, é importante que as chamadas subsequentes sejam não destrutivas. As chamadas BeginEdit subsequentes não podem destruir as atualizações que foram feitas ou alterar os dados que foram salvos na primeira chamada BeginEdit.

    • O método EndEdit aplica as alterações desde a chamada de BeginEdit ao objeto subjacente, se o objeto estiver atualmente em modo de edição.

    • O método CancelEdit descarta as alterações feitas no objeto.

    Para obter mais informações sobre como funcionam os métodos BeginEdit, EndEdite CancelEdit, consulte Salvar dados de volta para o banco de dados.

    Essa noção transacional de funcionalidade de dados é usada pelo controle DataGridView.

  • Interface ICancelAddNew

    Uma classe que implementa a interface ICancelAddNew geralmente implementa a interface IBindingList e permite reverter uma adição feita à fonte de dados com o método AddNew. Se a fonte de dados implementar a interface IBindingList, você também deve fazer com que ela implemente a interface ICancelAddNew.

  • Interface IDataErrorInfo

    Uma classe que implementa a interface IDataErrorInfo permite que os objetos ofereçam informações de erro personalizadas aos controles associados:

    • A propriedade Error retorna texto de mensagem de erro geral (por exemplo, "Ocorreu um erro").

    • A propriedade Item[] retorna uma cadeia de caracteres com a mensagem de erro específica da coluna (por exemplo, "O valor na coluna State é inválido").

  • Interface IEnumerable

    Uma classe que implementa a interface IEnumerable normalmente é consumida por ASP.NET. O suporte do Windows Forms para essa interface só está disponível por meio do componente BindingSource.

    Observação

    O componente BindingSource copia todos os itens IEnumerable em uma lista separada para fins de associação.

  • Interface ITypedList

    Uma classe de coleções que implementa a interface ITypedList possui o recurso de controlar a ordem e o conjunto de propriedades expostas ao controle vinculado.

    Observação

    Quando você implementa o método GetItemProperties e a matriz PropertyDescriptor não é nula, a última entrada na matriz será o descritor de propriedade que descreve a propriedade de lista que é outra lista de itens.

  • Interface ICustomTypeDescriptor

    Uma classe que implementa a interface ICustomTypeDescriptor fornece informações dinâmicas sobre si mesma. Essa interface é semelhante a ITypedList mas é usada para objetos em vez de listas. Essa interface é usada por DataRowView para projetar o esquema das linhas subjacentes. Uma implementação simples de ICustomTypeDescriptor é fornecida pela classe CustomTypeDescriptor.

    Observação

    Para dar suporte à associação de tempo de design a tipos que implementam ICustomTypeDescriptor, o tipo também deve implementar IComponent e existir como uma instância no Formulário.

  • Interface IListSource

    Uma classe que implementa a interface IListSource habilita a associação baseada em lista em objetos não listados. O método GetList de IListSource é usado para retornar uma lista vinculável de um objeto que não herda de IList. IListSource é usado pela classe DataSet.

  • Interface IRaiseItemChangedEvents

    Uma classe que implementa a interface IRaiseItemChangedEvents é uma lista associável que também implementa a interface IBindingList. Esta interface é usada para indicar se seu tipo gera eventos ListChanged do tipo ItemChanged por meio da respectiva propriedade RaisesItemChangedEvents.

    Observação

    Você deve implementar o IRaiseItemChangedEvents se a sua fonte de dados fornece a propriedade para listar a conversão de eventos descrita anteriormente e está interagindo com o componente BindingSource. Caso contrário, o BindingSource também realizará o evento de conversão de propriedade em lista, resultando em desempenho mais lento.

  • Interface ISupportInitialize

    Um componente que implementa a interface ISupportInitialize aproveita as otimizações em lotes para definir propriedades e inicializar propriedades co dependentes. O ISupportInitialize contém dois métodos:

    • BeginInit sinaliza que a inicialização do objeto está começando.

    • EndInit sinaliza que a inicialização do objeto está sendo concluída.

  • Interface ISupportInitializeNotification

    Um componente que implementa a interface ISupportInitializeNotification também implementa a interface ISupportInitialize. Essa interface permite que você notifique outros componentes ISupportInitialize que a inicialização está concluída. A interface ISupportInitializeNotification contém dois membros:

  • Interface INotifyPropertyChanged

    Uma classe que implementa essa interface é um tipo que gera um evento quando qualquer um de seus valores de propriedade é alterado. Essa interface foi projetada para substituir o padrão de ter um evento de alteração para cada propriedade de um controle. Quando usado em um BindingList<T>, um objeto de negócios deve implementar a interface INotifyPropertyChanged e o BindingList`1 converterá eventos PropertyChanged em eventos ListChanged do tipo ItemChanged.

    Observação

    Para que a notificação de alteração ocorra em uma ligação entre um cliente vinculado e uma fonte de dados, o tipo da sua fonte de dados vinculada deve implementar a interface INotifyPropertyChanged (preferencialmente) ou você pode fornecer eventos propertyNameChanged para o tipo vinculado, mas não deve fazer ambas.

Interfaces para implementação por autores de componentes

As interfaces a seguir são projetadas para consumo pelo mecanismo de associação de dados do Windows Forms:

  • Interface IBindableComponent

    Uma classe que implementa essa interface é um componente sem controle que dá suporte à associação de dados. Essa classe retorna as associações de dados e o contexto de associação do componente por meio das propriedades DataBindings e BindingContext dessa interface.

    Observação

    Se o componente herdar de Control, você não precisará implementar a interface IBindableComponent.

  • Interface ICurrencyManagerProvider

    Uma classe que implementa a interface ICurrencyManagerProvider é um componente que fornece seu próprio CurrencyManager para gerenciar as associações associadas a esse componente específico. O acesso ao CurrencyManager personalizado é fornecido pela propriedade CurrencyManager.

    Observação

    Uma classe que herda de Control gerencia associações automaticamente por meio de sua propriedade BindingContext, portanto, os casos em que você precisa implementar o ICurrencyManagerProvider são bastante raros.

Fontes de dados com suporte do Windows Forms

Tradicionalmente, a associação de dados tem sido usada em aplicativos para aproveitar os dados armazenados em bancos de dados. Com a associação de dados do Windows Forms, você pode acessar dados de bancos de dados e dados em outras estruturas, como matrizes e coleções, desde que determinados requisitos mínimos tenham sido atendidos.

Estruturas às quais associar

No Windows Forms, você pode associar a uma ampla variedade de estruturas, desde objetos simples (associação simples) até listas complexas, como tabelas de dados ADO.NET (associação complexa). Para associação simples, os Windows Forms dão suporte à associação às propriedades públicas no objeto simples. A associação baseada em lista do Windows Forms geralmente requer que o objeto dê suporte à interface IList ou à interface IListSource. Além disso, se estiver vinculando por meio de um componente BindingSource, poderá vincular a um objeto que dê suporte à interface IEnumerable.

A lista a seguir mostra as estruturas às quais você pode associar nos Windows Forms.

  • BindingSource

    Um BindingSource é a fonte de dados mais comum do Windows Forms e atua um proxy entre uma fonte de dados e controles do Windows Forms. O padrão geral de uso BindingSource é associar seus controles à BindingSource e associar o BindingSource à fonte de dados (por exemplo, uma tabela de dados ADO.NET ou um objeto de negócios). O BindingSource fornece serviços que habilitam e melhoram o nível de suporte à associação de dados. Por exemplo, controles baseados em listas do Windows Forms, como o DataGridView e ComboBox não dão suporte diretamente à associação a fontes de dados IEnumerable, no entanto, você pode habilitar esse cenário associando-se por meio de um BindingSource. Nesse caso, o BindingSource converterá a fonte de dados em um IList.

  • Objetos simples

    Os Windows Forms dão suporte a propriedades de controle de associação de dados a propriedades públicas na instância de um objeto usando o tipo Binding. Os Windows Forms também dão suporte a controles baseados em lista de associação, como um ListControl para uma instância de objeto quando um BindingSource é usado.

  • Matriz ou coleção

    Para atuar como uma fonte de dados, uma lista deve implementar a interface IList; um exemplo seria uma matriz que é uma instância da classe Array. Para obter mais informações sobre matrizes, consulte Como criar uma matriz de objetos (Visual Basic).

    Em geral, você deve usar BindingList<T> ao criar listas de objetos para associação de dados. BindingList é uma versão genérica da interface IBindingList. A interface IBindingList estende a interface IList adicionando propriedades, métodos e eventos necessários para associação de dados bidirecional.

  • IEnumerable

    Os controles do Windows Forms podem ser associados a fontes de dados que só dão suporte à interface IEnumerable se estiverem associadas por meio de um componente BindingSource.

  • ADO.NET objetos de dados

    ADO.NET fornece muitas estruturas de dados adequadas para associação. Cada um varia em sua sofisticação e complexidade.

    • DataColumn

      Um DataColumn é o bloco de construção essencial de um DataTable, em que várias colunas compõem uma tabela. Cada DataColumn tem uma propriedade DataType que determina o tipo de dados que a coluna armazena (por exemplo, a marca de um automóvel em uma tabela que descreve carros). Você pode associar de maneira simples um controle (como a propriedade TextBox de um controle Text) a uma coluna dentro de uma tabela de dados.

    • DataTable

      Um DataTable é a representação de uma tabela, com linhas e colunas, em ADO.NET. Uma tabela de dados contém duas coleções: DataColumn, representando as colunas de dados em uma determinada tabela (que, em última análise, determina os tipos de dados que podem ser inseridos nessa tabela) e DataRow, representando as linhas de dados em uma determinada tabela. Você pode associar um controle complexo às informações contidas em uma tabela de dados (como associar o controle DataGridView a uma tabela de dados). No entanto, quando você associa a um DataTable, você está associando à exibição padrão da tabela.

    • DataView

      Um DataView é uma exibição personalizada de uma única tabela de dados que pode ser filtrada ou classificada. Uma exibição de dados é o "instantâneo" dos dados usado por controles associados de maneira complexa. Você pode associar simples ou complexamente os dados em uma exibição de dados, mas observe que você está associando a uma "imagem" fixa dos dados em vez de uma fonte de dados limpa e atualizada.

    • DataSet

      Um DataSet é uma coleção de tabelas, relações e restrições dos dados em um banco de dados. Você pode associar de maneira simples ou complexa aos dados em um conjunto de dados, mas esteja ciente de que está associando ao DataViewManager padrão para o DataSet (veja o próximo ponto de marcador).

    • DataViewManager

      Um DataViewManager é uma exibição personalizada de toda a DataSet, análoga a um DataView, mas com relações incluídas. Com uma coleção de DataViewSettings, você pode definir filtros padrão e opções de classificação para quaisquer exibições que o DataViewManager tenha para uma determinada tabela.

Tipos de associação de dados

Os Windows Forms podem aproveitar dois tipos de associação de dados: associação simples e associação complexa. Cada um oferece vantagens diferentes.

Tipo de associação de dados Descrição
Associação de dados simples A capacidade de um controle de vincular-se a um único elemento de dados, como um valor em uma coluna em uma tabela de conjunto de dados. Associação de dados simples é o tipo de associação típico para controles como um controle TextBox ou controle Label, que são controles que normalmente exibem apenas um único valor. Na verdade, qualquer propriedade em um controle pode ser associada a um campo em um banco de dados. Há amplo suporte para esse recurso no Visual Studio.

Para obter mais informações, consulte Navegar em dados e Criar um controle com associação simples (Windows Forms .NET).
Associação de dados complexa A capacidade de um controle de associar a mais de um elemento de dados, normalmente mais de um registro em um banco de dados. A associação complexa também é chamada de associação baseada em lista. Exemplos de controles que dão suporte à associação complexa são os controles DataGridView, ListBoxe ComboBox. Para obter um exemplo de associação de dados complexa, consulte Como: Associar um controle ComboBox ou ListBox do Windows Forms a Dados.

Componente de origem de associação

Para simplificar a associação de dados, o Windows Forms permite associar uma fonte de dados ao componente BindingSource e associar controles ao BindingSource. Você pode usar o BindingSource em cenários de associação simples ou complexos. Em ambos os casos, a BindingSource atua como intermediário entre a fonte de dados e os controles de vinculação, fornecendo gerenciamento de moeda para notificação de alteração e outros serviços.

Cenários comuns que empregam associação de dados

Quase todos os aplicativos comerciais usam informações lidas de fontes de dados de um tipo ou de outro, geralmente por meio da associação de dados. A lista a seguir mostra alguns dos cenários mais comuns que utilizam a associação de dados como o método de apresentação e manipulação de dados.

Cenário Descrição
Reportagem Os relatórios fornecem uma maneira flexível de exibir e resumir seus dados em um documento impresso. É comum criar um relatório que imprime o conteúdo selecionado de uma fonte de dados na tela ou em uma impressora. Relatórios comuns incluem listas, faturas e resumos. Os itens são formatados em colunas de listas, com subitens organizados em cada item de lista, mas você deve escolher o layout mais adequado aos dados.
Entrada de dados Uma maneira comum de inserir grandes quantidades de dados relacionados ou solicitar informações aos usuários é por meio de um formulário de entrada de dados. Os usuários podem inserir informações ou selecionar opções usando caixas de texto, botões de opção, listas suspensas e caixas de seleção. Em seguida, as informações são enviadas e armazenadas em um banco de dados, cuja estrutura é baseada nas informações inseridas.
Relação mestre/detalhe Um aplicativo mestre/detalhes é um formato para pesquisa em dados relacionados. Especificamente, há duas tabelas de dados com uma relação conectada no exemplo de negócios clássico, uma tabela "Clientes" e uma tabela "Pedidos" com uma relação entre eles vinculando clientes e seus respectivos pedidos. Para obter mais informações sobre como criar um aplicativo mestre/detalhe com dois controles do Windows Forms DataGridView , consulte Como criar um formulário mestre/detalhe usando dois controles DataGridView dos Windows Forms.
Tabela de consulta Outro cenário comum de apresentação/manipulação de dados é a consulta em tabela. Muitas vezes, como parte de uma exibição de dados maior, um controle de ComboBox é usado para exibir e manipular dados. A chave é que os dados exibidos no controle ComboBox são diferentes dos dados gravados no banco de dados. Por exemplo, se você tiver um controle ComboBox exibindo os itens disponíveis em um supermercado, provavelmente gostaria de ver os nomes dos produtos (pão, leite, ovos). No entanto, para facilitar a recuperação de informações dentro do banco de dados e para a normalização do banco de dados, você provavelmente armazenaria as informações para os itens específicos de uma determinada ordem como números de item (nº 501, nº 603 e assim por diante). Portanto, há uma conexão implícita entre o "nome amigável" do item de supermercado no controle ComboBox em seu formulário e o número de item relacionado que está presente em um pedido. É a essência de uma consulta de tabela. Para obter mais informações, consulte Como criar uma tabela de pesquisa com o componente BindingSource do Windows Forms.

Consulte também