0% found this document useful (0 votes)
301 views229 pages

Documentação Do Windows Forms

The document provides information about new features and improvements to Windows Forms in .NET 7, including: - Improved high DPI rendering that correctly scales nested controls. - Accessibility improvements like better screen reader support and color contrast fixes. - Preview of new data binding features that allow embracing MVVM in Windows Forms. - Other changes like drag and drop matching Windows functionality and additional options for file dialogs.

Uploaded by

Marcos Souza
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
301 views229 pages

Documentação Do Windows Forms

The document provides information about new features and improvements to Windows Forms in .NET 7, including: - Improved high DPI rendering that correctly scales nested controls. - Accessibility improvements like better screen reader support and color contrast fixes. - Preview of new data binding features that allow embracing MVVM in Windows Forms. - Other changes like drag and drop matching Windows functionality and additional options for file dialogs.

Uploaded by

Marcos Souza
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 229

Dê a sua opinião sobre a experiência de download do PDF.

Documentação do Windows Forms


Saiba mais sobre como usar Windows Forms, uma interface gráfica do usuário de
software livre para Windows, no .NET 7.

Saiba mais sobre o Windows Forms

h NOVIDADES

Novidades

e VISÃO GERAL

Visão geral do Windows Forms

g TUTORIAL

Criar um novo aplicativo

Migrar do .NET Framework

a BAIXAR

Visual Studio 2022 versão 17.4

Controles

e VISÃO GERAL

Sobre controles

p CONCEITO

Layout

c GUIA DE INSTRUÇÕES

Adiciona um controle

Adicionar chaves de acesso (atalho)


Entrada por teclado

e VISÃO GERAL

Sobre o teclado

p CONCEITO

Eventos de teclado

c GUIA DE INSTRUÇÕES

Manipular a entrada do teclado

Modificar eventos-chave

Entrada por mouse

e VISÃO GERAL

Sobre o mouse

p CONCEITO

Eventos de mouse

Arrastar e soltar

c GUIA DE INSTRUÇÕES

Gerenciar o cursor

Simular eventos de mouse


What's new for .NET 7 (Windows Forms
.NET)
Article • 02/14/2023 • 4 minutes to read

This article describes some of the new Windows Forms features and enhancements in
.NET 7.

There are a few breaking changes you should be aware of when migrating from .NET
Framework to .NET 7. For more information, see Breaking changes in Windows Forms.

High DPI improvements


High DPI rendering with PerMonitorV2 has been improved:

Correctly scale nested controls. For example, a button that's in a panel, which is
placed on a tab page.

Scale Form.MaximumSize and Form.MinimumSize properties based on the current


monitor DPI settings for applications that run ApplicationHighDpiMode set to
PerMonitorV2 .

In .NET 7, this feature is disabled by default and you must opt in to receive this
change. Starting with .NET 8, this feature is enabled by default and you need to opt
out of it to revert to the previous behavior.

To enable feature, set the configProperties setting in runtimeconfig.json:

JSON

{
"runtimeOptions": {
"tfm": "net7.0",
"frameworks": [
...
],
"configProperties": {
"System.Windows.Forms.ScaleTopLevelFormMinMaxSizeForDpi": true,
}
}
}

Accessibility improvements and fixes


This release adds further improvements to accessibility, including but not limited to the
following items:

Many announcement-related issues observed in screen readers have been


addressed, ensuring the information about controls is correct. For example,
ListView now correctly announces when a group is expanded or collapsed.

More controls now provide UI Automation support:


TreeView
DateTimePicker
ToolStripContainer
ToolStripPanel
FlowLayoutPanel
TableLayoutPanel
SplitContainer
PrintPreviewControl
WebBrowser

Memory leaks related to running a Windows Forms application under assistive


tools, such as Narrator, have been fixed.

Assistive tools now accurately draw focus indicators and report correct bounding
rectangles for nested forms and some elements of composite controls, such as
DataGridView, ListView, and TabControl.

The Automation UI ExpandCollapse Control Pattern has been properly


implemented in ListView, TreeView, and PropertyGrid controls, and only activates
for expandable items.

Various color contrast ratio corrections in controls.

Visibility improvements for ToolStripTextBox and ToolStripButton in high-contrast


themes.

Data binding improvements (preview)


While Windows Forms already had a powerful binding engine, a more modern form of
data binding, similar to data binding provided by WPF, is being introduced.

The new data binding features allow you to fully embrace the MVVM pattern and the
use of object-relational mappers from ViewModels in Windows Forms easier than
before. This, in turn, makes it possible to reduce code in the code-behind files, and
opens new testing possibilities. More importantly, it enables code sharing between
Windows Forms and other .NET GUI frameworks such as WPF, UWP/WinUI, and MAUI.
And to clarify a commonly asked question, there aren't any plans to introduce XAML in
Windows Forms.

These new data binding features are in preview for .NET 7, and more work on this
feature will happen in .NET 8.

To enable the new binding, add the EnablePreviewFeatures setting to your project file.
This is supported in both C# and Visual Basic.

XML

<Project Sdk="Microsoft.NET.Sdk">

<!-- other settings -->

<PropertyGroup>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>

</Project>

The following code snippet demonstrates the new properties, events, and methods
added to the various classes in Windows Forms. Even though the following code
example is in C#, it also applies to Visual Basic.

C#

public class Control {


[BindableAttribute(true)]
public virtual object DataContext { get; set; }
[BrowsableAttribute(true)]
public event EventHandler DataContextChanged;
protected virtual void OnDataContextChanged(EventArgs e);
protected virtual void OnParentDataContextChanged(EventArgs e);
}

[RequiresPreviewFeaturesAttribute]
public abstract class BindableComponent : Component, IBindableComponent,
IComponent, IDisposable {
protected BindableComponent();
public BindingContext? BindingContext { get; set; }
public ControlBindingsCollection DataBindings { get; }
public event EventHandler BindingContextChanged;
protected virtual void OnBindingContextChanged(EventArgs e);
}

public abstract class ButtonBase : Control {


[BindableAttribute(true)]
[RequiresPreviewFeaturesAttribute]
public ICommand? Command { get; set; }
[BindableAttribute(true)]
public object? CommandParameter { [RequiresPreviewFeaturesAttribute]
get; [RequiresPreviewFeaturesAttribute] set; }
[RequiresPreviewFeaturesAttribute]
public event EventHandler? CommandCanExecuteChanged;
[RequiresPreviewFeaturesAttribute]
public event EventHandler? CommandChanged;
[RequiresPreviewFeaturesAttribute]
public event EventHandler? CommandParameterChanged;
[RequiresPreviewFeaturesAttribute]
protected virtual void OnCommandCanExecuteChanged(EventArgs e);
[RequiresPreviewFeaturesAttribute]
protected virtual void OnCommandChanged(EventArgs e);
[RequiresPreviewFeaturesAttribute]
protected virtual void OnCommandParameterChanged(EventArgs e);
[RequiresPreviewFeaturesAttribute]
protected virtual void OnRequestCommandExecute(EventArgs e);
}

public abstract class ToolStripItem : BindableComponent, IComponent,


IDisposable, IDropTarget {
[BindableAttribute(true)]
[RequiresPreviewFeaturesAttribute]
public ICommand Command { get; set; }
[BindableAttribute(true)]
public object CommandParameter { [RequiresPreviewFeaturesAttribute] get;
[RequiresPreviewFeaturesAttribute] set; }
[RequiresPreviewFeaturesAttribute]
public event EventHandler CommandCanExecuteChanged;
[RequiresPreviewFeaturesAttribute]
public event EventHandler CommandChanged;
[RequiresPreviewFeaturesAttribute]
public event EventHandler CommandParameterChanged;
[RequiresPreviewFeaturesAttribute]
protected virtual void OnCommandCanExecuteChanged(EventArgs e);
[RequiresPreviewFeaturesAttribute]
protected virtual void OnCommandChanged(EventArgs e);
[RequiresPreviewFeaturesAttribute]
protected virtual void OnCommandParameterChanged(EventArgs e);
[RequiresPreviewFeaturesAttribute]
protected virtual void OnRequestCommandExecute(EventArgs e);
}

Miscellaneous improvements
Here are some other notable changes:

Drag-and-drop handling matches the Windows drag-and-drop functionality with


richer display effects such as icons and text labels.
Folder and file dialogs allow for more options:
Add to recent
Check write access
Expanded mode
OK requires interaction
Select read-only
Show hidden files
Show pinned places
Show preview
ErrorProvider has a HasErrors property now.
Form's snap layout is fixed for Windows 11.

See also
.NET Blog - What's new in Windows Forms in .NET 7
Breaking changes in Windows Forms
Tutorial: Create a new WinForms app
How to migrate a Windows Forms desktop app to .NET 5
Novidades do .NET 6 (Windows Forms
.NET)
Artigo • 14/02/2023 • 5 minutos para o fim da leitura

Este artigo descreve alguns dos novos recursos e aprimoramentos do Windows Forms no
.NET 6.

Há algumas alterações interruptivas que você deve estar ciente ao migrar do .NET
Framework para o .NET 6. Para obter mais informações, consulte Alterações interruptivas
no Windows Forms.

Modelos atualizados para C #


O .NET 6 introduziu muitas alterações nos modelos de aplicativo de console padrão. De
acordo com essas alterações, os modelos de Windows Forms para C# foram atualizados
para habilitar global using diretivas, namespaces com escopo de arquivo e tipos de
referência anuláveis por padrão.

Um recurso dos novos modelos C# que não foram levados adiante com Windows Forms
são as instruções de nível superior. O aplicativo de Windows Forms típico requer o
[STAThread] atributo e consiste em vários tipos divididos em vários arquivos, como os
arquivos de código do designer, portanto, o uso de instruções de nível superior não faz
sentido.

Nova inicialização de aplicativo


Os modelos que geram uma nova Windows Forms aplicativo criam um Main método que
serve como o ponto de entrada para seu aplicativo quando ele é executado. Esse método
contém código que configura Windows Forms e exibe o primeiro formulário, conhecido
como o código de inicialização:

C#

class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}

No .NET 6, esses modelos foram modificados para usar o novo código de inicialização,
invocado pelo ApplicationConfiguration.Initialize método .

C#

class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}

Esse método é gerado automaticamente no tempo de compilação e contém o código


para configurar Windows Forms. O arquivo de projeto também pode controlar essas
configurações e você pode evitar configurá-las no código. Por exemplo, o método
gerado é semelhante ao seguinte código:

C#

public static void Initialize()


{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.SystemAware);
}

O novo código de inicialização é usado pelo Visual Studio para configurar o Windows
Forms Visual Designer. Se você recusar o uso do novo código de inicialização,
restaurando o código antigo e ignorando o ApplicationConfiguration.Initialize
método , o Windows Forms Visual Designer não respeitará as configurações de
inicialização definidas.

As configurações geradas no Initialize método são controladas pelo arquivo de


projeto.

Configurações de aplicativo no nível do projeto


Para complementar o novo recurso de inicialização de aplicativo de Windows Forms,
algumas Application configurações definidas anteriormente no código de inicialização
do aplicativo devem ser definidas no arquivo de projeto. O arquivo de projeto pode
definir as seguintes configurações de aplicativo:

Configuração do projeto Valor API correspondente


padrão

ApplicationVisualStyles true Application.EnableVisualStyles

ApplicationUseCompatibleTextRendering false Application.SetCompatibleTextRenderingDefault

ApplicationHighDpiMode SystemAware Application.SetHighDpiMode

ApplicationDefaultFont Segoe UI, Application.SetDefaultFont


9pt

O exemplo a seguir demonstra um arquivo de projeto que define essas propriedades


relacionadas ao aplicativo:

XML

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>

<ApplicationVisualStyles>true</ApplicationVisualStyles>

<ApplicationUseCompatibleTextRendering>false</ApplicationUseCompatibleTextRen
dering>
<ApplicationHighDpiMode>SystemAware</ApplicationHighDpiMode>
<ApplicationDefaultFont>Microsoft Sans Serif,
8.25pt</ApplicationDefaultFont>

</PropertyGroup>

</Project>

O Windows Forms Visual Designer usa essas configurações. Para obter mais informações,
consulte a seção Aprimoramentos do designer do Visual Studio.

Alterar a fonte padrão


Windows Forms no .NET Core 3.0 introduziu uma nova fonte padrão para Windows
Forms: Segoe UI, 9pt. Essa fonte está mais alinhada às diretrizes de experiência do
usuário (UX) do Windows. No entanto, .NET Framework usa o Microsoft Sans Serif,
8.25pt como a fonte padrão. Essa alteração tornou mais difícil para alguns clientes migrar
seus aplicativos grandes que utilizavam um layout perfeito de pixels de .NET Framework
para .NET. A única maneira de alterar a fonte de todo o aplicativo era editar todos os
formulários do projeto, definindo a Font propriedade como uma fonte alternativa.

A fonte padrão agora pode ser definida de duas maneiras:

Defina a fonte padrão no arquivo de projeto a ser usada pelo código de


inicialização do aplicativo :

) Importante

Essa é a maneira preferida. Usar o projeto para configurar o novo sistema de


inicialização de aplicativos permite que o Visual Studio use essas configurações
no designer.

No exemplo a seguir, o arquivo de projeto configura Windows Forms para usar a


mesma fonte que .NET Framework usa.

XML

<Project Sdk="Microsoft.NET.Sdk">

<!-- other settings -->

<PropertyGroup>
<ApplicationDefaultFont>Microsoft Sans Serif,
8.25pt</ApplicationDefaultFont>
</PropertyGroup>

</Project>

- ou -

Chame a Application.SetDefaultFont API da maneira antiga (mas sem suporte para


designer):

C#

class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.SetDefaultFont(new Font(new FontFamily("Microsoft
Sans Serif"), 8.25f));
Application.Run(new Form1());
}
}

Melhorias no designer do Visual Studio


O Windows Forms Visual Designer agora reflete com precisão a fonte padrão. As versões
anteriores do Windows Forms para .NET não exibiam corretamente a fonte segoe da
interface do usuário no Designer Visual e, na verdade, estavam projetando o formulário
com a fonte padrão do .NET Framework. Devido ao novo recurso de inicialização de
aplicativo , o Visual Designer reflete com precisão a fonte padrão. Além disso, o Designer
Visual respeita a fonte padrão definida no arquivo de projeto.

Mais designers de runtime


Os designers que existiam no .NET Framework e habilitaram a criação de um designer de
uso geral, por exemplo, a criação de um designer de relatórios, foram adicionados ao
.NET 6:

System.ComponentModel.Design.ComponentDesigner
System.Windows.Forms.Design.ButtonBaseDesigner
System.Windows.Forms.Design.ComboBoxDesigner
System.Windows.Forms.Design.ControlDesigner
System.Windows.Forms.Design.DocumentDesigner
System.Windows.Forms.Design.DocumentDesigner
System.Windows.Forms.Design.FormDocumentDesigner
System.Windows.Forms.Design.GroupBoxDesigner
System.Windows.Forms.Design.LabelDesigner
System.Windows.Forms.Design.ListBoxDesigner
System.Windows.Forms.Design.ListViewDesigner
System.Windows.Forms.Design.MaskedTextBoxDesigner
System.Windows.Forms.Design.PanelDesigner
System.Windows.Forms.Design.ParentControlDesigner
System.Windows.Forms.Design.ParentControlDesigner
System.Windows.Forms.Design.PictureBoxDesigner
System.Windows.Forms.Design.RadioButtonDesigner
System.Windows.Forms.Design.RichTextBoxDesigner
System.Windows.Forms.Design.ScrollableControlDesigner
System.Windows.Forms.Design.ScrollableControlDesigner
System.Windows.Forms.Design.TextBoxBaseDesigner
System.Windows.Forms.Design.TextBoxDesigner
System.Windows.Forms.Design.ToolStripDesigner
System.Windows.Forms.Design.ToolStripDropDownDesigner
System.Windows.Forms.Design.ToolStripItemDesigner
System.Windows.Forms.Design.ToolStripMenuItemDesigner
System.Windows.Forms.Design.TreeViewDesigner
System.Windows.Forms.Design.UpDownBaseDesigner
System.Windows.Forms.Design.UserControlDocumentDesigner

Altas melhorias de DPI para PerMonitorV2


A renderização de alto DPI com PerMonitorV2 foi aprimorada:

Os controles são criados com o mesmo reconhecimento de DPI que o aplicativo.

Os controles de contêiner e as janelas filho MDI melhoraram os comportamentos


de dimensionamento.

Por exemplo, no .NET 5, mover um aplicativo Windows Forms de um monitor com


dimensionamento de 200% para um monitor com dimensionamento de 100%
resultaria em controles incorretos. Isso foi muito aprimorado no .NET 6:
Novas APIs
System.Windows.Forms.Application.SetDefaultFont
System.Windows.Forms.Control.IsAncestorSiteInDesignMode
System.Windows.Forms.ProfessionalColors.StatusStripBorder
System.Windows.Forms.ProfessionalColorTable.StatusStripBorder

Novas APIs do Visual Basic


Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventHandler
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.Minim
umSplashScreenDisplayTime
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.Minim
umSplashScreenDisplayTime
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.Font
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.Font
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.HighD
piMode
Microsoft.VisualBasic.ApplicationServices.ApplyApplicationDefaultsEventArgs.HighD
piMode
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.ApplyAppli
cationDefaults
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HighDpiM
ode
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HighDpiM
ode

APIs atualizadas
System.Windows.Forms.Control.Invoke agora aceita System.Action e
System.Func<TResult> como parâmetros de entrada.

System.Windows.Forms.Control.BeginInvoke agora aceita System.Action como um


parâmetro de entrada.

System.Windows.Forms.DialogResult é estendido com os seguintes membros:


TryAgain

Continue

System.Windows.Forms.Form tem uma nova propriedade:


MdiChildrenMinimizedAnchorBottom

System.Windows.Forms.MessageBoxButtons é estendido com o seguinte membro:


CancelTryContinue

System.Windows.Forms.MessageBoxDefaultButton é estendido com o seguinte


membro:
Button4

System.Windows.Forms.LinkClickedEventArgs agora tem um novo construtor e


estendido com as seguintes propriedades:
System.Windows.Forms.LinkClickedEventArgs.LinkLength
System.Windows.Forms.LinkClickedEventArgs.LinkStart

System.Windows.Forms.NotifyIcon.Text agora está limitado a 127 caracteres (de 63).

Acessibilidade aprimorada
Os padrões de Automação da Interface do Usuário da Microsoft funcionam melhor com
ferramentas de acessibilidade, como Narrador e Jaws.

Confira também
Alterações interruptivas no Windows Forms
Tutorial: Criar um aplicativo WinForms
Como migrar um aplicativo da área de trabalho do Windows Forms para o .NET 5
o que há de novo no .net 5 (Windows
Forms .net)
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

o Windows Forms para .net 5 adiciona os seguintes recursos e aprimoramentos em .NET


Framework.

há algumas alterações significativas que você deve estar atento ao migrar do .NET
Framework para o .net 5. para obter mais informações, consulte alterações significativas
em Windows Forms.

Recursos avançados
Os padrões de automação da interface do usuário da Microsoft funcionam melhor
com ferramentas de acessibilidade como Narrator e Jaws.

Melhor desempenho.

O modelo de projeto VB.NET usa como padrão as configurações de DPI


SystemAware para resoluções de DPI alto, como monitores de 4K.

a fonte padrão corresponde às recomendações de design de Windows atuais.

U Cuidado

Isso pode afetar o layout dos aplicativos migrados do .NET Framework.

Novos controles
os seguintes controles foram adicionados desde que Windows Forms foi transportado
para .NET Framework:

System.Windows.Forms.TaskDialog

Um diálogo de tarefa é uma caixa de diálogo que pode ser usada para exibir
informações e receber a entrada simples do usuário. Como uma caixa de
mensagem, ela é formatada pelo sistema operacional de acordo com os
parâmetros definidos. A caixa de diálogo de tarefa tem mais recursos do que uma
mensagem. Para obter mais informações, consulte o exemplo da caixa de diálogo
tarefa .
Microsoft.Web.WebView2.WinForms.WebView2

Um novo controle de navegador da Web com suporte da Web moderno. Com


base na borda (Chromium). para obter mais informações, consulte introdução ao
WebView2 no Windows Forms.

Controles aprimorados
System.Windows.Forms.ListView
Dá suporte a grupos recolhíveis
Rodapés
Subtítulo de grupo, tarefa e imagens de título

System.Windows.Forms.FolderBrowserDialog

esta caixa de diálogo foi atualizada para usar a experiência de Windows moderna
em vez da experiência antiga Windows 7.

System.Windows.Forms.FileDialog

Adicionado suporte para ClientGuid .

ClientGuid permite que um aplicativo de chamada associe um GUID ao estado

persistente de uma caixa de diálogo. O estado de uma caixa de diálogo pode


incluir fatores como a última pasta visitada e a posição e o tamanho da caixa de
diálogo. Normalmente, esse estado é persistido com base no nome do arquivo
executável. Com ClientGuid o, um aplicativo pode persistir Estados diferentes
da caixa de diálogo dentro do mesmo aplicativo.

System.Windows.Forms.TextRenderer

Suporte adicionado para ReadOnlySpan<T> para aprimorar o desempenho do


processamento de texto.

Confira também
alterações recentes no Windows Forms
Tutorial: criar um novo aplicativo winforms (Windows Forms .net)
como migrar um aplicativo de área de trabalho Windows Forms para o .net 5
Guia da área de trabalho (Windows
Forms .NET)
Artigo • 15/02/2023 • 6 minutos para o fim da leitura

Bem-vindo ao Guia da Área de Trabalho para Windows Forms, uma estrutura de


interface do usuário que cria aplicativos cliente de área de trabalho avançados para
Windows. A plataforma de desenvolvimento Windows Forms dá suporte a uma ampla
gama de recursos de desenvolvimento do aplicativo, incluindo controles, grafos,
associação de dados e entrada de usuário. O Windows Forms apresenta um designer
visual de arrastar e soltar no Visual Studio para criar facilmente aplicativos do Windows
Forms.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Há duas implementações do Windows Forms:

1. A implementação de software livre hospedada no GitHub .

Essa versão é executada no .NET 5+ (e no .NET Core 3.1). O Designer Visual do


Windows Forms requer, no mínimo, o Visual Studio 2019 versão 16.8.

A versão mais recente do Windows Forms é para .NET 6 usando o Visual Studio
2022 versão 17.0.

2. A implementação do .NET Framework 4 compatível com o Visual Studio 2022, o


Visual Studio 2019 e o Visual Studio 2017.

O .NET Framework 4 é uma versão exclusiva do Windows do .NET e é considerado


um componente do Sistema Operacional Windows. Esta versão do Windows Forms
é distribuída com o .NET Framework.

Este Guia da Área de Trabalho é escrito para Windows Forms no .NET 5 e versões
posteriores. Para obter mais informações sobre a versão do .NET Framework do
Windows Forms, confira Windows Forms para .NET Framework.

Introdução
O Windows Forms é uma estrutura de interface do usuário para a criação de aplicativos
da área de trabalho do Windows. Ele fornece uma das maneiras mais produtivas de criar
aplicativos da área de trabalho com base no designer visual fornecido no Visual Studio.
A funcionalidade, como o posicionamento de arrastar e soltar de controles visuais,
facilita a criação de aplicativos da área de trabalho.

Com o Windows Forms, você desenvolve aplicativos graficamente avançados que são
fáceis de implantar, atualizar e trabalhar enquanto estão offline ou enquanto estão
conectados à Internet. Os aplicativos do Windows Forms podem acessar o hardware
local e o sistema de arquivos do computador em que o aplicativo está em execução.

Para saber como criar um aplicativo do Windows Forms, confira Tutorial: Criar um
aplicativo WinForms.

Por que migrar do .NET Framework


O Windows Forms para .NET 6.0 fornece novos recursos e aprimoramentos no .NET
Framework. Para obter mais informações, confira Novidades nos Windows Forms para
.NET 6 e .NET 5. Para saber como migrar um aplicativo, confira Como migrar um
aplicativo da área de trabalho do Windows Forms para o .NET 5.

Criar interfaces de usuário avançadas e


interativas
O Windows Forms é uma tecnologia de interface do usuário para .NET, um conjunto de
bibliotecas gerenciadas que simplificam tarefas comuns do aplicativo, como ler e gravar
no sistema de arquivos. Ao usar um ambiente de desenvolvimento como o Visual
Studio, você pode criar aplicativos cliente inteligente do Windows Forms que exibem
informações, solicitam entrada de usuários e se comunicam com computadores remotos
em uma rede.

nos Windows Forms, um formulário é uma superfície visual na qual são exibidas
informações para o usuário. Normalmente, você cria aplicativos do Windows Forms
adicionando controles a formulários e desenvolvendo respostas a ações do usuário,
como cliques do mouse ou pressionamentos de teclas. Um controle é um elemento de
interface do usuário discreto que exibe dados ou aceita a entrada de dados.

Quando um usuário executa alguma ação em seu formulário ou em um de seus


controles, a ação gera um evento. Seu aplicativo reage a esses eventos com código e
processa os eventos quando eles ocorrem.
O Windows Forms contém uma variedade de controles que você pode adicionar aos
formulários: controles que exibem caixas de texto, botões, caixas suspensas, botões de
opção e até páginas da Web. Se um controle existente não atender às suas
necessidades, o Windows Forms também oferecerá suporte à criação de seus próprios
controles personalizados usando a classe UserControl.

O Windows Forms tem controles avançados de interface do usuário que emulam


recursos em aplicativos high-end como o Microsoft Office. Ao usar os controles
ToolStrip e MenuStrip, você pode criar barras de ferramentas e menus que contêm texto
e imagens, exibir submenus e hospedar outros controles, como caixas de texto e caixas
de combinação.

Com o Designer de Formulários do Windows no Visual Studio, você pode facilmente


criar aplicativos do Windows Forms. Basta selecionar os controles com o cursor e
colocá-los onde desejar no formulário. O designer oferece ferramentas como linhas de
grade e linhas de alinhamento para facilitar o alinhamento dos controles. Você pode
usar os controles FlowLayoutPanel, TableLayoutPanel e SplitContainer para criar layouts
de formulário avançados em menos tempo.

Por fim, se você precisar criar seus próprios elementos de interface do usuário
personalizados, o namespace System.Drawing conterá uma grande seleção de classes
para renderizar linhas, círculos e outras formas diretamente em um formulário.

Criar formulários e controles


Para obter informações passo a passo sobre como usar esses recursos, consulte os
seguintes tópicos da Ajuda.

Como adicionar um formulário a um projeto


Como adicionar controles a um formulário

Exibir e manipular dados


Muitos aplicativos devem exibir dados de um banco de dados, arquivo XML ou JSON,
serviço Web ou outra fonte de dados. O Windows Forms fornece um controle flexível
que é nomeado o controle DataGridView para exibir esses dados tabulares em um
formato de linha e coluna tradicional, de modo que cada parte dos dados ocupe sua
própria célula. Ao usar DataGridView, você pode personalizar a aparência de células
individuais, bloquear linhas e colunas arbitrárias no local e exibir controles complexos
dentro das células, entre outros recursos.
Conectar-se a fontes de dados em uma rede é uma tarefa simples com o Windows
Forms. O componente BindingSource representa uma conexão com uma fonte de dados
e expõe métodos para associar dados a controles, navegar até os registros anteriores e
próximos, editar registros e salvar alterações de volta para a fonte original. O controle
BindingNavigator fornece uma interface simples pelo componente BindingSource para
que os usuários naveguem entre os registros.

Você pode criar controles associados a dados facilmente usando a janela Fontes de
Dados no Visual Studio. A janela exibe fontes de dados, como bancos de dados, serviços
Web e objetos em seu projeto. Você pode criar controles de associação de dados ao
arrastar itens dessa janela para os formulários do seu projeto. Você também pode
associar controles existentes a dados ao arrastar objetos da janela Fontes de Dados para
eles.

Outro tipo de vinculação de dados que você pode gerenciar nos Windows Forms é
chamado de configurações. A maioria dos aplicativos deve reter algumas informações
sobre seu estado de tempo de execução, como o último tamanho conhecido dos
formulários, e reter dados de preferência do usuário, como locais padrão para arquivos
salvos. O recurso de configuração de aplicativo lida com esses requisitos ao oferecer
uma forma fácil de armazenar ambos os tipos de configuração no computador cliente.
Depois de definir essas configurações usando o Visual Studio ou um editor de código,
as configurações são mantidas como XML e automaticamente lidas novamente na
memória em tempo de execução.

Implantar aplicativos em computadores cliente


Depois de escrever seu aplicativo, você deve enviar o aplicativo aos usuários para que
eles possam instalá-lo e executá-lo em seus próprios computadores cliente. Ao usar a
tecnologia ClickOnce, você pode implantar seus aplicativos de dentro do Visual Studio
usando apenas alguns cliques e fornecer aos usuários uma URL que aponte para seu
aplicativo na Web. O ClickOnce gerencia todos os elementos e dependências em seu
aplicativo e garante que o aplicativo esteja instalado corretamente no computador
cliente.

Os aplicativos ClickOnce podem ser configurados para serem executados somente


quando o usuário estiver conectado à rede ou para executar online e offline. Quando
você especifica que um aplicativo deve dar suporte à operação offline, o ClickOnce
adiciona um link ao seu aplicativo no menu Iniciar do usuário. O usuário pode abrir o
aplicativo sem usar a URL.

Ao atualizar seu aplicativo, você publica um novo manifesto de implantação e uma nova
cópia do aplicativo no servidor Web. O ClickOnce detectará que há uma atualização
disponível e atualizará a instalação do usuário. Nenhuma programação personalizada é
necessária para atualizar aplicativos antigos.

Confira também
Tutorial: Criar um aplicativo WinForms
Como adicionar um formulário a um projeto
Adiciona um controle
Tutorial: Criar um aplicativo Windows
Forms com o .NET
Artigo • 09/02/2023 • 5 minutos para o fim da leitura

Neste breve tutorial, você aprenderá a criar um novo aplicativo Windows Forms com o
Visual Studio. Depois que o aplicativo inicial for gerado, você aprenderá a adicionar
controles e como lidar com eventos. Ao final deste tutorial, você terá um aplicativo
simples que adiciona nomes a uma caixa de listagem.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Neste tutorial, você aprenderá como:

" Criar um novo aplicativo Windows Forms


" Adicionar controles a um formulário
" Manipular eventos de controle para fornecer a funcionalidade do aplicativo
" Executar o aplicativo

Pré-requisitos
Visual Studio 2022 versão 17.4 ou versões posteriores
Selecione a carga de trabalho de desenvolvimento da área de trabalho do .NET
Selecione o componente individual do .NET 7

 Dica

Use o Visual Studio 2022 versão 17.4 ou posterior e instale os componentes


individuais do .NET 7 e do .NET 6. O suporte para .NET 7 foi adicionado ao Visual
Studio 2022 versão 17.4.

Criar um aplicativo do Windows Forms


A primeira etapa para criar um novo aplicativo é abrir o Visual Studio e gerar o
aplicativo de um modelo.
1. Abra o Visual Studio.

2. Selecione Criar um novo projeto.

3. Na caixa Pesquisar modelos , digite winforms e aguarde até que os resultados da


pesquisa sejam exibidos.

4. Na lista suspensa linguagem de código , escolha C# ou Visual Basic.

5. Na lista de modelos, selecione Windows Forms Aplicativo e clique em Avançar.

) Importante

Não selecione o modelo Windows Forms App (.NET Framework).

A imagem a seguir mostra os modelos de projeto do C# e do Visual Basic .NET. Se


você aplicou o filtro de linguagem de código , verá o modelo correspondente.
6. Na janela Configurar seu novo projeto , defina o Nome do projeto como Nomes e
clique em Avançar.

Você também pode salvar seu projeto em uma pasta diferente ajustando o
caminho local .

7. Por fim, na janela Informações adicionais , selecione .NET 7.0 (Suporte a Termos
Padrão) para a configuração da Estrutura e clique em Criar.
Depois que o aplicativo for gerado, o Visual Studio deverá abrir o painel de designer
para o formulário padrão, Form1. Se o designer de formulários não estiver visível, clique
duas vezes no formulário no painel Gerenciador de Soluções para abrir a janela do
designer.

Partes importantes do Visual Studio


O suporte para Windows Forms no Visual Studio tem quatro componentes importantes
com os quais você interagirá ao criar um aplicativo:
1. Gerenciador de Soluções

Todos os arquivos de projeto, código, formulários, recursos serão exibidos neste


painel.

2. Propriedades

Este painel mostra as configurações de propriedade que você pode definir com
base no item selecionado. Por exemplo, se você selecionar um item de
Gerenciador de Soluções, verá as configurações de propriedade relacionadas ao
arquivo. Se você selecionar um objeto no Designer, verá as configurações do
controle ou formulário.

3. Designer de Formulários

Este é o designer do formulário. Ele é interativo e você pode arrastar e soltar


objetos da Caixa de Ferramentas. Selecionando e movendo itens no designer,
você pode compor visualmente a interface do usuário para seu aplicativo.

4. Caixa de Ferramentas

A caixa de ferramentas contém todos os controles que você pode adicionar a um


formulário. Para adicionar um controle ao formulário atual, clique duas vezes em
um controle ou arraste e solte o controle.

 Dica
Se a caixa de ferramentas não estiver visível, você poderá exibi-la por meio do item
de menu Exibir>Caixa de Ferramentas .

Adicionar controles ao formulário


Com o designer de formulários Form1 aberto, use o painel Caixa de Ferramentas para
adicionar os seguintes controles ao formulário:

Rotular
Botão
Listbox
Caixa de texto

Você pode posicionar e dimensionar os controles de acordo com as configurações a


seguir. Mova-os visualmente para corresponder à captura de tela a seguir ou clique em
cada controle e defina as configurações no painel Propriedades . Você também pode
clicar na área de título do formulário para selecionar o formulário:

Objeto Configuração Valor


Objeto Configuração Valor

Formulário Texto Names

Tamanho 268, 180

Rótulo Local 12, 9

Texto Names

Listbox Nome lstNames

Location 12, 27

Tamanho 120, 94

Caixa de texto Nome txtName

Location 138, 26

Tamanho 100, 23

Botão Nome btnAdd

Location 138, 55

Tamanho 100, 23

Texto Add Name

Você deve ter um formulário no designer semelhante ao seguinte:

Tratar eventos
Agora que o formulário tem todos os seus controles dispostos, você precisa lidar com
os eventos dos controles para responder à entrada do usuário. Com o designer de
formulário ainda aberto, execute as seguintes etapas:
1. Selecione o controle de botão no formulário.

2. No painel Propriedades , clique no ícone de eventos para listar os eventos do


botão.

3. Localize o evento Clique e clique duas vezes nele para gerar um manipulador de
eventos.

Essa ação adiciona o seguinte código ao formulário:

C#

private void btnAdd_Click(object sender, EventArgs e)


{

O código que colocaremos nesse manipulador adicionará o nome especificado


pelo controle de txtName caixa de texto ao lstNames controle de caixa de listagem.
No entanto, queremos que haja duas condições para adicionar o nome: o nome
fornecido não deve estar em branco e o nome ainda não deve existir.

4. O código a seguir demonstra a adição de um nome ao lstNames controle:

C#

private void btnAdd_Click(object sender, EventArgs e)


{
if (!string.IsNullOrWhiteSpace(txtName.Text) &&
!lstNames.Items.Contains(txtName.Text))
lstNames.Items.Add(txtName.Text);
}

Executar o aplicativo
Agora que o evento foi codificado, você pode executar o aplicativo pressionando a tecla
F5 ou selecionando Depurar>Iniciar Depuração no menu. O formulário é exibido e
você pode inserir um nome na caixa de texto e adicioná-lo clicando no botão.
Próximas etapas
Saiba mais sobre Windows Forms
Como migrar um aplicativo da área de
trabalho do Windows Forms para o .NET
5
Artigo • 16/03/2023 • 10 minutos para o fim da leitura

Este artigo descreve como migrar um aplicativo da área de trabalho do Windows Forms
do .NET Framework para o .NET 5 ou posterior. O SDK do .NET Core 3.0 inclui suporte
para aplicativos do Windows Forms. O Windows Forms ainda é uma estrutura somente
do Windows e só é executado nessa plataforma.

Migrar seu aplicativo do .NET Framework para o .NET 5 geralmente requer um novo
arquivo de projeto. O .NET 5 usa arquivos de projeto no estilo SDK, enquanto o .NET
Framework normalmente usa o arquivo de projeto mais antigo do Visual Studio. Se você
já abriu um arquivo de projeto do Visual Studio em um editor de texto, sabe o quão
detalhado ele é. Os projetos no estilo SDK são menores e não exigem tantas entradas
quanto o formato de arquivo de projeto mais antigo.

Para saber mais sobre o .NET 5, confira Introdução ao .NET.

Experimente o assistente de atualização


O Assistente de Atualização do .NET é uma ferramenta de linha de comando que pode
ser executada em diferentes tipos de aplicativos do .NET Framework. Ele foi projetado
para ajudar na atualização de aplicativos do .NET Framework para o .NET 5. Depois de
executar a ferramenta, na maioria dos casos, o aplicativo exigirá esforço adicional para
concluir a migração. A ferramenta inclui a instalação de analisadores que podem ajudar
na conclusão da migração.

Para obter mais informações, confira Atualizar um aplicativo WPF para o .NET 5 com o
Assistente de Atualização do .NET.

Pré-requisitos
Visual Studio 2019 versão 16.11 ou posterior.

Selecione a carga de trabalho do Visual Studio Desktop.

Selecione o componente individual .NET 5.

Visualize o designer WinForms no Visual Studio.


Para habilitar o designer, vá para Ferramentas>Opções>Ambiente>Visualizações
do Recurso e selecione a opção Usar o designer de visualização do Windows
Forms para aplicativos .NET Core.

Este artigo usa o aplicativo de exemplo Matching game . Se você quiser


acompanhar, baixe e abra o aplicativo no Visual Studio. Caso contrário, use seu
próprio aplicativo.

Considerações
Ao portar um aplicativo do Windows Forms do .NET Framework, há alguns pontos a
serem considerados.

1. Verifique se o seu aplicativo é um bom candidato para a migração.

Use o Analisador de Portabilidade do .NET para determinar se o seu projeto será


migrado para o .NET 5. Se seu projeto tiver problemas com o .NET 5, o analisador
ajudará a identificar esses problemas. A ferramenta Analisador de Portabilidade do
.NET pode ser instalada como uma extensão do Visual Studio ou usada na linha de
comando. Para obter mais informações, consulte Analisador de Portabilidade do
.NET.

2. Você está usando uma versão diferente do Windows Forms.

Quando o .NET Core 3.0 foi lançado, o Windows Forms passou a ser um código
aberto no GitHub . O código para o Windows Forms para .NET 5 é uma
bifurcação do código base do Windows Forms do .NET Framework. É possível que
existam algumas diferenças e seu aplicativo será difícil de migrar.

3. O Pacote de Compatibilidade do Windows pode ajudar você na migração.

Algumas APIs disponíveis no .NET Framework não estão disponíveis no .NET 5. O


Pacote de Compatibilidade do Windows adiciona muitas dessas APIs e pode ajudar
o aplicativo do Windows Forms a se tornar compatível com o .NET 5.

4. Atualize os pacotes do NuGet usados pelo seu projeto.

É sempre uma boa prática usar as versões mais recentes dos pacotes do NuGet
antes de qualquer migração. Se seu aplicativo faz referência a pacotes do NuGet,
atualize-os para a versão mais recente. Certifique-se de que seu aplicativo foi
compilado com êxito. Após a atualização, se houver erros de pacote, faça
downgrade do pacote para a versão mais recente que não interrompa seu código.
Fazer backup dos seus projetos
A primeira etapa para migrar um projeto é fazer backup do projeto! Se algo der errado,
você poderá restaurar seu código ao estado original restaurando seu backup. Não
confie em ferramentas como o Analisador de Portabilidade do .NET para fazer backup
do projeto, mesmo que pareçam seguros. É melhor criar pessoalmente uma cópia do
projeto original.

Pacotes NuGet
Se o projeto estiver fazendo referência a pacotes NuGet, você provavelmente terá um
arquivo packages.config na pasta do projeto. Com projetos no estilo SDK, as referências
do pacote NuGet são configuradas no arquivo de projeto. Os arquivos de projeto do
Visual Studio também podem definir pacotes NuGet no arquivo de projeto. O .NET 5
não usa packages.config para pacotes NuGet. As referências do pacote NuGet devem
ser migradas para o arquivo de projeto antes da migração.

Para migrar o arquivo packages.config, execute as seguintes etapas:

1. No Gerenciador de Soluções, localize o projeto que você está migrando.


2. Clique com o botão direito do mouse em packages.config>Migrar
packages.config para PackageReference.
3. Selecione todos os pacotes de nível superior.

Um relatório de build é gerado para informar sobre os problemas de migração dos


pacotes NuGet.

Arquivo de projeto
A próxima etapa na migração do aplicativo é converter o arquivo de projeto. Conforme
indicado anteriormente, o .NET 5 usa arquivos de projeto no estilo SDK e não carregará
os arquivos de projeto do Visual Studio usados pelo .NET Framework. No entanto, há a
possibilidade de você já estar usando projetos no estilo SDK. Você pode detectar
facilmente a diferença no Visual Studio. Clique com o botão direito do mouse no
arquivo de projeto no Gerenciador de Soluções e procure a opção de menu Editar
Arquivo de Projeto. Se esse item de menu estiver ausente, você estará usando o
formato de projeto antigo do Visual Studio e precisará atualizar.

Converta cada projeto em sua solução. Se você estiver usando o aplicativo de exemplo
referenciado anteriormente, os projetos MatchingGame e MatchingGame.Logic serão
convertidos.
Para converter um projeto, execute as seguintes etapas:

1. No Gerenciador de Soluções, localize o projeto que você está migrando.

2. Clique com o botão direito do mouse no projeto e selecione Descarregar Projeto.

3. Clique com o botão direito do mouse no projeto e selecione Editar Arquivo de


Projeto.

4. Copie e cole o XML do projeto em um editor de texto. Você desejará uma cópia
para que seja fácil mover o conteúdo para o novo projeto.

5. Apague o conteúdo do arquivo e cole o seguinte XML:

XML

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

</Project>

) Importante

As bibliotecas não precisam definir uma configuração <OutputType> . Remova


essa entrada se você estiver atualizando um projeto de biblioteca.

Esse XML fornece a estrutura básica do projeto. No entanto, ele não contém nenhuma
das configurações do arquivo de projeto antigo. Usando as informações antigas do
projeto copiadas anteriormente para um editor de texto, execute as seguintes etapas:

1. Copie os seguintes elementos do arquivo de projeto antigo para o elemento


<PropertyGroup> no novo arquivo de projeto:

<RootNamespace>

<AssemblyName>

O arquivo de projeto deve ser semelhante ao seguinte XML:

XML
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

<RootNamespace>MatchingGame</RootNamespace>
<AssemblyName>MatchingGame</AssemblyName>
</PropertyGroup>

</Project>

2. Copie os elementos <ItemGroup> do arquivo de projeto antigo que contém


<ProjectReference> ou <PackageReference> no novo arquivo após a marca de

fechamento </PropertyGroup> .

O arquivo de projeto deve ser semelhante ao seguinte XML:

XML

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
(contains settings previously described)
</PropertyGroup>

<ItemGroup>
<ProjectReference
Include="..\MatchingGame.Logic\MatchingGame.Logic.csproj">
<Project>{36b3e6e2-a9ae-4924-89ae-7f0120ce08bd}</Project>
<Name>MatchingGame.Logic</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="MetroFramework">
<Version>1.2.0.3</Version>
</PackageReference>
</ItemGroup>

</Project>

Os elementos <ProjectReference> não precisam dos <Project> e <Name> filhos


para que você possa remover essas configurações:

XML
<ItemGroup>
<ProjectReference
Include="..\MatchingGame.Logic\MatchingGame.Logic.csproj" />
</ItemGroup>

Recursos e configurações
Algo a observar sobre a diferença entre projetos do .NET Framework e os projetos no
estilo SDK usados pelo .NET 5 é que os projetos do .NET Framework usam um modelo
de aceitação para arquivos de código. Qualquer arquivo de código que você deseja
compilar precisa ser definido explicitamente em seu arquivo de projeto. Os projetos no
estilo SDK são o inverso, são padrão para recusar o comportamento: todos os arquivos
de código que começam no diretório do projeto e abaixo são incluídos
automaticamente em seu projeto. Você não precisará migrar essas entradas se elas
forem simples e sem configurações. Isso é o mesmo para outros arquivos comuns,
como resx.

Os projetos do Windows Forms também podem fazer referência aos seguintes arquivos:

Properties\Settings.settings
Properties\Resources.resx
Properties\app.manifest

O arquivo app.manifest é referenciado automaticamente pelo seu projeto e você não


precisa fazer nada especial para migrá-lo.

Quaisquer arquivos *.resx e *.settings na pasta Propriedades precisam ser migrados no


projeto. Copie essas entradas do arquivo de projeto antigo para um elemento
<ItemGroup> no novo projeto. Depois de copiar as entradas, altere todos os elementos

<Compile Include="value"> para usar o atributo Update em vez de Include .

Importe a configuração para o arquivo Settings.settings.

XML

<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Update="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>

) Importante

Os projetos do Visual Basic normalmente usam a pasta My Project, enquanto


projetos C# normalmente usam a pasta Properties para o arquivo de
configurações de projeto padrão.

Importe a configuração para qualquer arquivo resx, como o arquivo


properties\Resources.resx. Observe que o atributo Include foi definido como
Update no elemento <Compile> e <EmbeddedResource> , e <SubType> foi removido
de <EmbeddedResource> :

XML

<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Update="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
</ItemGroup>

) Importante

Normalmente, os projetos do Visual Basic usam a pasta My Project, enquanto


os projetos C# normalmente usam a pasta Properties para o arquivo de
recurso de projeto padrão.

Visual Basic
Os projetos da linguagem Visual Basic exigem uma configuração extra.

1. Importe o arquivo de configuração My Project\Application.myapp. Observe que o


elemento <Compile> usa o atributo Update em vez do atributo Include .

XML
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
<Compile Update="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
</ItemGroup>

2. Adicione a configuração <MyType>WindowsForms</MyType> ao elemento


<PropertyGroup> :

XML

<PropertyGroup>
(contains settings previously described)

<MyType>WindowsForms</MyType>
</PropertyGroup>

Essa configuração importa o namespace My , conhecido dos programadores do


Visual Basic.

3. Importe os namespaces definidos pelo projeto.

Os projetos do Visual Basic podem importar namespaces automaticamente para


cada arquivo de código. Copie os elementos <ItemGroup> do arquivo de projeto
antigo que contém <Import> no novo arquivo após a marca de fechamento
</PropertyGroup> .

XML

<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Drawing" />
<Import Include="System.Diagnostics" />
<Import Include="System.Windows.Forms" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
Se você não encontrar nenhuma instrução <Import> ou se o projeto não for
compilado, verifique se você pelo menos tem as seguintes instruções <Import>
definidas em seu projeto:

XML

<ItemGroup>
<Import Include="System.Data" />
<Import Include="System.Drawing" />
<Import Include="System.Windows.Forms" />
</ItemGroup>

4. No projeto original, copie as configurações <Option*> e <StartupObject> para o


elemento <PropertyGroup> :

XML

<PropertyGroup>
(contains settings previously described)

<OptionExplicit>On</OptionExplicit>
<OptionCompare>Binary</OptionCompare>
<OptionStrict>Off</OptionStrict>
<OptionInfer>On</OptionInfer>
<StartupObject>MatchingGame.My.MyApplication</StartupObject>
</PropertyGroup>

Recarregar o projeto
Depois de converter um projeto no novo formato estilo SDK, recarregue o projeto no
Visual Studio:

1. No Gerenciador de Soluções, localize o projeto que você converteu.

2. Clique com o botão direito do mouse no projeto e selecione Recarregar Projeto.

Se o projeto não for carregado, talvez você tenha introduzido um erro no XML do
projeto. Abra o arquivo de projeto para edição e tente identificar e corrigir o erro.
Se você não encontrar um erro, tente recomeçar.

Editar App.config
Se seu aplicativo tiver um arquivo App.config, remova o elemento <supportedRuntime> :
XML

<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />

Há algumas coisas que você deve considerar com o arquivo App.config. O arquivo
App.config no .NET Framework foi usado não apenas para configurar o aplicativo, mas
para definir configurações e comportamento de runtime, como registro em log. O
arquivo App.config no .NET 5+ (e no .NET Core) não é mais usado para configuração de
runtime. Se o arquivo App.config tiver essas seções, elas não serão respeitadas.

Adicionar o pacote de compatibilidade


Se o arquivo de projeto estiver carregando corretamente, mas a compilação falhar para
seu projeto e você receber erros semelhantes aos seguintes:

O tipo ou namespace <um nome> não foi encontrado


O nome <um nome> não existe no contexto atual

Talvez seja necessário adicionar o pacote Microsoft.Windows.Compatibility ao seu


aplicativo. Esse pacote adiciona cerca de 21.000 APIs do .NET desde o .NET Framework,
como a classe e APIS do System.Configuration.ConfigurationManager para interagir com
o Registro do Windows.

Para adicionar o pacote ao projeto, abra o arquivo de projeto em um editor e adicione o


seguinte <ItemGroup> elemento:

XML

<ItemGroup>
<PackageReference Include="Microsoft.Windows.Compatibility"
Version="5.0.0" />
</ItemGroup>

Testar seu aplicativo


Depois de terminar de migrar seu aplicativo, teste-o!

Próximas etapas
Experimente o Assistente de Atualização do .NET para migrar seu aplicativo.
Saiba mais sobre alterações interruptivas do Windows Forms.
Leia mais sobre o Pacote de Compatibilidade do Windows.
Visão geral de eventos (Windows Forms
.NET)
Artigo • 09/02/2023 • 3 minutos para o fim da leitura

Um evento é uma ação à qual você pode responder ou "manipular" no código. Os


eventos podem ser gerados por uma ação do usuário, como clicar no mouse ou
pressionar uma tecla, por código do programa ou pelo sistema.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Os aplicativos controlados por eventos executam código em resposta a um evento.


Cada formulário e controle expõe um conjunto predefinido de eventos com base nos
quais você pode programar. Se um desses eventos ocorrer e houver um código de um
manipulador de eventos associado, esse código será invocado.

Os tipos de eventos gerados por um objeto variam, mas muitos tipos são comuns à
maioria dos controles. Por exemplo, a maioria dos objetos lidará com um evento Click.
Se um usuário clicar em um formulário, o código no manipulador de eventos Click do
formulário é executado.

7 Observação

Muitos eventos ocorrem com outros eventos. Por exemplo, enquanto o evento
DoubleClick ocorre, os eventos MouseDown, MouseUp e Click ocorrem.

Para obter informações sobre como gerar e consumir um evento, consulte Manipulando
e gerando eventos.

Delegados e sua função


Delegados são classes comumente usadas no .NET para criar mecanismos de
manipulação de eventos. Os delegados equivalem aproximadamente a ponteiros de
função, comumente usados no Visual C++ e em outras linguagens orientadas a objeto.
No entanto, diferente dos ponteiros de função, as classes delegate são orientadas a
objeto, fortemente tipadas e seguras. Além disso, quando um ponteiro de função
contém apenas uma referência a uma função específica, um delegado consiste em uma
referência a um objeto e faz referência a um ou mais métodos dentro do objeto .

Esse modelo de evento usa delegados para associar eventos aos métodos usados para
tratá-los. A classe delegate permite que outras classes se registrem para a notificação de
eventos, especificando um método de manipulador. Quando o evento ocorre, a classe
delegate chama o método associado. Para obter mais informações sobre como definir
delegados, consulte Manipulando e gerando eventos.

Essas classes podem ser associadas a um único método ou a vários métodos, o que
chamamos de multicasting. Ao criar um delegado para um evento, você normalmente
cria um evento multicast. Uma exceção rara pode ser um evento que resulta em um
procedimento específico (como exibir uma caixa de diálogo) que não se repetiria
logicamente várias vezes por evento. Para obter informações sobre como criar um
delegado multicast, consulte Como combinar delegados (delegados multicast).

Um delegado multicast mantém uma lista de invocação dos métodos aos qual está
associado. Essa classe é compatível com um método Combine para adicionar um
método à lista de invocação e um método Remove para removê-lo.

Quando um evento é registrado pelo aplicativo, o controle gera o evento invocando a


classe delegate para esse evento. A classe delegate chama o método vinculado. No caso
mais comum (um delegado multicast), o delegado chama cada método associado na
lista de invocação, por sua vez, que fornece uma notificação de um para muitos. Essa
estratégia significa que o controle não precisa manter uma lista de objetos de destino
para notificação de eventos— o delegado lida com todo o registro e notificação.

Essas classes também permitem que vários eventos sejam associados ao mesmo
método, permitindo uma notificação muitos para um. Por exemplo, um evento de clique
de botão e um evento de clique de comando de menu podem invocar a mesma classe
delegate, que chama um único método para lidar com esses eventos separados da
mesma maneira.

O mecanismo de associação usado com delegados é dinâmico: um delegado pode ser


associado em tempo de execução a qualquer método cuja assinatura corresponda à do
manipulador de eventos. Com esse recurso, você pode configurar ou alterar o método
associado de acordo com uma condição e anexar dinamicamente um manipulador de
eventos a um controle.

Confira também
Manipulando e acionando eventos
Dimensionamento automático
(Windows Forms .NET)
Artigo • 10/02/2023 • 4 minutos para o fim da leitura

O dimensionamento automático permite que um formulário e seus controles,


projetados em um computador com uma determinada resolução de exibição ou fonte,
sejam exibidos adequadamente em outro computador com uma resolução de exibição
ou fonte diferente. Ele garante que o formulário e seus controles serão redimensionados
de forma inteligente para serem consistentes com janelas nativas e outros aplicativos
nos computadores dos usuários e de outros desenvolvedores. O dimensionamento
automático e os estilos visuais permitem que Windows Forms aplicativos mantenham
uma aparência consistente quando comparados com aplicativos nativos do Windows no
computador de cada usuário.

Na maioria das vezes, o dimensionamento automático funciona conforme o esperado


em Windows Forms. No entanto, as alterações no esquema de fontes podem ser
problemáticas.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Necessidade de dimensionamento automático


Sem o dimensionamento automático, um aplicativo projetado para uma resolução de
exibição ou fonte aparecerá muito pequeno ou muito grande quando essa resolução ou
fonte for alterada. Por exemplo, se o aplicativo for projetado usando Tahoma 9 ponto
como uma linha de base, sem ajuste ele aparecerá muito pequeno se executado em um
computador em que a fonte do sistema é Tahoma 12 pontos. Elementos de texto, como
títulos, menus, conteúdo de caixa de texto e assim por diante, renderizarão menos do
que outros aplicativos. Além disso, o tamanho dos elementos de interface do usuário
que contêm texto, como a barra de título, menus e muitos controles, depende da fonte
usada. Neste exemplo, esses elementos também aparecerão relativamente menores.

Uma situação análoga ocorre quando um aplicativo é projetado para uma determinada
resolução de exibição. A resolução de exibição mais comum é de 96 pontos por
polegada (DPI), que é igual a 100% de escala de exibição, mas telas de resolução mais
alta com suporte a 125%, 150%, 200% (que respectivamente são iguais a 120, 144 e 192
DPI) e acima estão se tornando mais comuns. Sem ajustes, um aplicativo, especialmente
um baseado em gráficos, projetado para uma resolução, aparecerá muito grande ou
muito pequeno quando executado em outra resolução.

O dimensionamento automático busca resolver esses problemas redimensionando


automaticamente o formulário e seus controles filho de acordo com o tamanho relativo
da fonte ou resolução de exibição. O sistema operacional Windows dá suporte ao
dimensionamento automático de caixas de diálogo usando uma unidade relativa de
medida chamada unidades de diálogo. Uma unidade de diálogo é baseada na fonte do
sistema e sua relação com pixels pode ser determinada por meio da função
GetDialogBaseUnits do SDK do Win32 . Quando um usuário altera o tema usado pelo

Windows, todas as caixas de diálogo são ajustadas automaticamente de acordo. Além


disso, Windows Forms dá suporte ao dimensionamento automático de acordo com a
fonte do sistema padrão ou a resolução de exibição. Opcionalmente, o
dimensionamento automático pode ser desabilitado em um aplicativo.

U Cuidado

Não há suporte para misturas arbitrárias de DPI e modos de dimensionamento de


fontes. Embora você possa dimensionar um controle de usuário usando um modo
(por exemplo, DPI) e colocá-lo em um formulário usando outro modo (Fonte) sem
problemas, mas misturar um formulário base em um modo e uma forma derivada
em outro pode levar a resultados inesperados.

Dimensionamento automático em ação


Windows Forms usa a seguinte lógica para dimensionar automaticamente formulários e
seu conteúdo:

1. Em tempo de design, cada ContainerControl um registra o modo de


dimensionamento e a resolução atual no AutoScaleMode e
AutoScaleDimensionsno , respectivamente.

2. Em tempo de execução, a resolução real é armazenada na


CurrentAutoScaleDimensions propriedade . A AutoScaleFactor propriedade calcula
dinamicamente a proporção entre o tempo de execução e a resolução de
dimensionamento de tempo de design.

3. Quando o formulário é carregado, se os valores de CurrentAutoScaleDimensions e


AutoScaleDimensions são diferentes, o PerformAutoScale método é chamado para
dimensionar o controle e seus filhos. Esse método suspende o layout e chama o
Scale método para executar o dimensionamento real. Posteriormente, o valor de
AutoScaleDimensions é atualizado para evitar o dimensionamento progressivo.

4. PerformAutoScale também é invocado automaticamente nas seguintes situações:

Em resposta ao OnFontChanged evento se o modo de dimensionamento for


Font.

Quando o layout do controle de contêiner é retomado e uma alteração é


detectada nas AutoScaleDimensions propriedades ou AutoScaleMode .

Conforme implícito acima, quando um pai ContainerControl está sendo


dimensionado. Cada controle de contêiner é responsável por dimensionar
seus filhos usando seus próprios fatores de dimensionamento e não aquele
de seu contêiner pai.

5. Os controles filho podem modificar seu comportamento de dimensionamento por


vários meios:

A ScaleChildren propriedade pode ser substituída para determinar se seus


controles filho devem ser dimensionados ou não.

O GetScaledBounds método pode ser substituído para ajustar os limites para


os quais o controle é dimensionado, mas não a lógica de dimensionamento.

O ScaleControl método pode ser substituído para alterar a lógica de


dimensionamento para o controle atual.

Confira também
AutoScaleMode
Scale
PerformAutoScale
AutoScaleDimensions
Como adicionar um formulário a um
projeto (Windows Forms .NET)
Artigo • 09/02/2023 • 2 minutos para o fim da leitura

Adicione formulários ao seu projeto com o Visual Studio. Quando seu aplicativo tem
vários formulários, você pode escolher qual é o formulário de inicialização para seu
aplicativo e pode exibir vários formulários ao mesmo tempo.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Adicionar um novo formulário


Adicione um novo formulário com o Visual Studio.

1. No Visual Studio, localize o painel Gerenciador de Projetos . Clique com o botão


direito do mouse no projeto e escolha Adicionar>Formulário (Windows Forms).
2. Na caixa Nome , digite um nome para seu formulário, como MyNewForm. O Visual
Studio fornecerá um nome padrão e exclusivo que você pode usar.
Depois que o formulário for adicionado, o Visual Studio abrirá o designer de formulário
para o formulário.

Adicionar uma referência de projeto a um


formulário
Se você tiver os arquivos de origem em um formulário, poderá adicionar o formulário ao
seu projeto copiando os arquivos para a mesma pasta do projeto. O projeto faz
referência automaticamente a todos os arquivos de código que estão na mesma pasta
ou pasta filho do seu projeto.

Os formulários são compostos por dois arquivos que compartilham o mesmo nome:
form2.cs (form2 sendo um exemplo de nome de arquivo) e form2. Designer.cs. Às vezes,
existe um arquivo de recurso, compartilhando o mesmo nome, form2.resx. No exemplo
anterior, form2 representa o nome do arquivo base. Você desejará copiar todos os
arquivos relacionados para a pasta do projeto.

Como alternativa, você pode usar o Visual Studio para importar um arquivo para seu
projeto. Quando você adiciona um arquivo existente ao seu projeto, o arquivo é
copiado para a mesma pasta que o projeto.

1. No Visual Studio, localize o painel Gerenciador de Projetos . Clique com o botão


direito do mouse no projeto e escolha Adicionar>Item Existente.
2. Navegue até a pasta que contém os arquivos de formulário.

3. Selecione o arquivo form2.cs , em que form2 é o nome de arquivo base dos


arquivos de formulário relacionados. Não selecione os outros arquivos, como
form2. Designer.cs.

Confira também
Como posicionar e dimensionar um formulário (Windows Forms .NET)
Visão geral de eventos (Windows Forms .NET)
Posição e layout de controles (Windows Forms .NET)
Como posicionar e dimensionar um
formulário (Windows Forms .NET)
Artigo • 09/02/2023 • 4 minutos para o fim da leitura

Quando um formulário é criado, o tamanho e o local são inicialmente definidos como


um valor padrão. O tamanho padrão de um formulário geralmente é uma largura e
altura de 800 x 500 pixels. O local inicial, quando o formulário é exibido, depende de
algumas configurações diferentes.

Você pode alterar o tamanho de um formulário em tempo de design com o Visual


Studio e em tempo de execução com código.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Redimensionar com o designer


Depois de adicionar um novo formulário ao projeto, o tamanho de um formulário é
definido de duas maneiras diferentes. Primeiro, você pode defini-lo com as alças de
tamanho no designer. Arrastando a borda direita, a borda inferior ou o canto, você pode
redimensionar o formulário.
A segunda maneira de redimensionar o formulário enquanto o designer estiver aberto é
por meio do painel de propriedades. Selecione o formulário e, em seguida, localize o
painel Propriedades no Visual Studio. Role para baixo até o tamanho e expanda-o. Você
pode definir a Largura e a Altura manualmente.

Redimensionar no código
Embora o designer defina o tamanho inicial de um formulário, você pode redimensioná-
lo por meio do código. Usar código para redimensionar um formulário é útil quando
algo sobre seu aplicativo determina que o tamanho padrão do formulário é insuficiente.

Para redimensionar um formulário, altere o Size, que representa a largura e a altura do


formulário.

Redimensionar o formulário atual


Você pode alterar o tamanho do formulário atual, desde que o código esteja em
execução dentro do contexto do formulário. Por exemplo, se você tiver Form1 com um
botão nele, quando clicado invocará o Click manipulador de eventos para
redimensionar o formulário:

C#
private void button1_Click(object sender, EventArgs e) =>
Size = new Size(250, 200);

Redimensionar um formulário diferente


Você pode alterar o tamanho de outro formulário depois que ele for criado usando a
variável referenciando o formulário. Por exemplo, digamos que você tenha dois
formulários, Form1 (o formulário de inicialização neste exemplo) e Form2 . Form1 tem um
botão que, quando clicado, invoca o Click evento. O manipulador desse evento cria
uma nova instância do Form2 formulário, define o tamanho e o exibe:

C#

private void button1_Click(object sender, EventArgs e)


{
Form2 form = new Form2();
form.Size = new Size(250, 200);
form.Show();
}

Se o Size não for definido manualmente, o tamanho padrão do formulário será o que
ele foi definido durante o tempo de design.

Posição com o designer


Quando uma instância de formulário é criada e exibida, o local inicial do formulário é
determinado pela StartPosition propriedade . A Location propriedade contém o local
atual do formulário. Ambas as propriedades podem ser definidas por meio do designer.
Enumeração Descrição
FormStartPosition

CenterParent O formulário é centralizado dentro dos limites do formulário pai.

CenterScreen O formulário é centralizado na exibição atual.

Manual A posição do formulário é determinada pela propriedade Location .

WindowsDefaultBounds O formulário é posicionado no local padrão do Windows e é


redimensionado para o tamanho padrão determinado pelo Windows.

WindowsDefaultLocation O formulário é posicionado no local padrão do Windows e não é


redimensionado.

O valor CenterParent só funciona com formulários que são um formulário filho MDI
(interface de documento múltiplo) ou um formulário normal exibido com o ShowDialog
método . CenterParent não tem nenhum efeito em um formulário normal que é exibido
com o Show método . Para centralizar um formulário ( form variável) para outro
formulário ( parentForm variável), use o seguinte código:

C#

form.StartPosition = FormStartPosition.Manual;
form.Location = new Point(parentForm.Width / 2 - form.Width / 2 +
parentForm.Location.X,
parentForm.Height / 2 - form.Height / 2 +
parentForm.Location.Y);
form.Show();
Posição com código
Embora o designer possa ser usado para definir o local inicial de um formulário, você
pode usar o código para alterar o modo de posição inicial ou definir o local
manualmente. Usar código para posicionar um formulário será útil se você precisar
posicionar e dimensionar manualmente um formulário em relação à tela ou a outros
formulários.

Mover o formulário atual


Você pode mover o formulário atual desde que o código esteja em execução dentro do
contexto do formulário. Por exemplo, se você tiver Form1 com um botão, isso quando
clicado invocará o Click manipulador de eventos. O manipulador neste exemplo altera
o local do formulário para o canto superior esquerdo da tela definindo a Location
propriedade :

C#

private void button1_Click(object sender, EventArgs e) =>


Location = new Point(0, 0);

Posicionar um formulário diferente


Você pode alterar o local de outro formulário depois que ele for criado usando a
variável referenciando o formulário. Por exemplo, digamos que você tenha dois
formulários, Form1 (o formulário de inicialização neste exemplo) e Form2 . Form1 tem um
botão que, quando clicado, invoca o Click evento. O manipulador desse evento cria
uma nova instância do Form2 formulário e define o local:

C#

private void button1_Click(object sender, EventArgs e)


{
Form2 form = new Form2();
form.Location = new Point(0, 0);
form.Show();
}

Se o Location não estiver definido, a posição padrão do formulário será baseada no


que a StartPosition propriedade foi definida como em tempo de design.
Confira também
Como adicionar um formulário a um projeto (Windows Forms .NET)
Visão geral de eventos (Windows Forms .NET)
Posição e layout de controles (Windows Forms .NET)
Como posicionar e dimensionar um
formulário (Windows Forms .NET)
Artigo • 09/02/2023 • 4 minutos para o fim da leitura

Quando um formulário é criado, o tamanho e o local são inicialmente definidos como


um valor padrão. O tamanho padrão de um formulário geralmente é uma largura e
altura de 800 x 500 pixels. O local inicial, quando o formulário é exibido, depende de
algumas configurações diferentes.

Você pode alterar o tamanho de um formulário em tempo de design com o Visual


Studio e em tempo de execução com código.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Redimensionar com o designer


Depois de adicionar um novo formulário ao projeto, o tamanho de um formulário é
definido de duas maneiras diferentes. Primeiro, você pode defini-lo com as alças de
tamanho no designer. Arrastando a borda direita, a borda inferior ou o canto, você pode
redimensionar o formulário.
A segunda maneira de redimensionar o formulário enquanto o designer estiver aberto é
por meio do painel de propriedades. Selecione o formulário e, em seguida, localize o
painel Propriedades no Visual Studio. Role para baixo até o tamanho e expanda-o. Você
pode definir a Largura e a Altura manualmente.

Redimensionar no código
Embora o designer defina o tamanho inicial de um formulário, você pode redimensioná-
lo por meio do código. Usar código para redimensionar um formulário é útil quando
algo sobre seu aplicativo determina que o tamanho padrão do formulário é insuficiente.

Para redimensionar um formulário, altere o Size, que representa a largura e a altura do


formulário.

Redimensionar o formulário atual


Você pode alterar o tamanho do formulário atual, desde que o código esteja em
execução dentro do contexto do formulário. Por exemplo, se você tiver Form1 com um
botão nele, quando clicado invocará o Click manipulador de eventos para
redimensionar o formulário:

C#
private void button1_Click(object sender, EventArgs e) =>
Size = new Size(250, 200);

Redimensionar um formulário diferente


Você pode alterar o tamanho de outro formulário depois que ele for criado usando a
variável referenciando o formulário. Por exemplo, digamos que você tenha dois
formulários, Form1 (o formulário de inicialização neste exemplo) e Form2 . Form1 tem um
botão que, quando clicado, invoca o Click evento. O manipulador desse evento cria
uma nova instância do Form2 formulário, define o tamanho e o exibe:

C#

private void button1_Click(object sender, EventArgs e)


{
Form2 form = new Form2();
form.Size = new Size(250, 200);
form.Show();
}

Se o Size não for definido manualmente, o tamanho padrão do formulário será o que
ele foi definido durante o tempo de design.

Posição com o designer


Quando uma instância de formulário é criada e exibida, o local inicial do formulário é
determinado pela StartPosition propriedade . A Location propriedade contém o local
atual do formulário. Ambas as propriedades podem ser definidas por meio do designer.
Enumeração Descrição
FormStartPosition

CenterParent O formulário é centralizado dentro dos limites do formulário pai.

CenterScreen O formulário é centralizado na exibição atual.

Manual A posição do formulário é determinada pela propriedade Location .

WindowsDefaultBounds O formulário é posicionado no local padrão do Windows e é


redimensionado para o tamanho padrão determinado pelo Windows.

WindowsDefaultLocation O formulário é posicionado no local padrão do Windows e não é


redimensionado.

O valor CenterParent só funciona com formulários que são um formulário filho MDI
(interface de documento múltiplo) ou um formulário normal exibido com o ShowDialog
método . CenterParent não tem nenhum efeito em um formulário normal que é exibido
com o Show método . Para centralizar um formulário ( form variável) para outro
formulário ( parentForm variável), use o seguinte código:

C#

form.StartPosition = FormStartPosition.Manual;
form.Location = new Point(parentForm.Width / 2 - form.Width / 2 +
parentForm.Location.X,
parentForm.Height / 2 - form.Height / 2 +
parentForm.Location.Y);
form.Show();
Posição com código
Embora o designer possa ser usado para definir o local inicial de um formulário, você
pode usar o código para alterar o modo de posição inicial ou definir o local
manualmente. Usar código para posicionar um formulário será útil se você precisar
posicionar e dimensionar manualmente um formulário em relação à tela ou a outros
formulários.

Mover o formulário atual


Você pode mover o formulário atual desde que o código esteja em execução dentro do
contexto do formulário. Por exemplo, se você tiver Form1 com um botão, isso quando
clicado invocará o Click manipulador de eventos. O manipulador neste exemplo altera
o local do formulário para o canto superior esquerdo da tela definindo a Location
propriedade :

C#

private void button1_Click(object sender, EventArgs e) =>


Location = new Point(0, 0);

Posicionar um formulário diferente


Você pode alterar o local de outro formulário depois que ele for criado usando a
variável referenciando o formulário. Por exemplo, digamos que você tenha dois
formulários, Form1 (o formulário de inicialização neste exemplo) e Form2 . Form1 tem um
botão que, quando clicado, invoca o Click evento. O manipulador desse evento cria
uma nova instância do Form2 formulário e define o local:

C#

private void button1_Click(object sender, EventArgs e)


{
Form2 form = new Form2();
form.Location = new Point(0, 0);
form.Show();
}

Se o Location não estiver definido, a posição padrão do formulário será baseada no


que a StartPosition propriedade foi definida como em tempo de design.
Confira também
Como adicionar um formulário a um projeto (Windows Forms .NET)
Visão geral de eventos (Windows Forms .NET)
Posição e layout de controles (Windows Forms .NET)
Visão geral do uso de controles
(Windows Forms .NET)
Artigo • 15/02/2023 • 2 minutos para o fim da leitura

Windows Forms controles são componentes reutilizáveis que encapsulam a


funcionalidade da interface do usuário e são usados em aplicativos do lado do cliente
baseados no Windows. O Windows Forms não só fornece vários controles prontos para
usar como também proporciona a infraestrutura para desenvolver seus próprios
controles. É possível combinar os controles existentes, ampliar os controles existentes e
fazer seus controles personalizados. Para obter mais informações, consulte Tipos de
controles personalizados.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Adicionando controles
Os controles são adicionados por meio do Visual Studio Designer. Com o Designer, você
pode colocar, dimensionar, alinhar e mover controles. Como alternativa, os controles
podem ser adicionados por meio do código. Para obter mais informações, consulte
Adicionar um controle (Windows Forms).

Opções de layout
A posição em que um controle aparece em um pai é determinada pelo valor da Location
propriedade em relação à parte superior esquerda da superfície pai. A coordenada de
posição superior esquerda no pai é (x0,y0) . O tamanho do controle é determinado
pela Size propriedade e representa a largura e a altura do controle.

Além do posicionamento manual e do dimensionamento, vários controles de contêiner


são fornecidos que ajudam no posicionamento automático de controles.

Para obter mais informações, consulte Posição e layout de controles e Como encaixar e
ancorar controles.
Eventos de controle
Os controles fornecem um conjunto de eventos comuns por meio da classe base:
Control. Nem todos os controles respondem a todos os eventos. Por exemplo, o Label
controle não responde à entrada do teclado, portanto, o Control.PreviewKeyDown
evento não é gerado. A maioria dos eventos compartilhados se enquadra nessas
categorias:

Eventos de mouse
Eventos de teclado
Eventos de propriedade alterados
Outros eventos

Para obter mais informações, consulte Controlar eventos e Como manipular um evento
de controle.

Controlar a acessibilidade
Windows Forms tem suporte de acessibilidade para leitores de tela e utilitários de
entrada de voz para comandos verbais. No entanto, você deve projetar sua interface do
usuário com acessibilidade em mente. Windows Forms controles expõem várias
propriedades para lidar com a acessibilidade. Para obter mais informações sobre essas
propriedades, consulte Fornecendo informações de acessibilidade para controles.

Confira também
Posição e layout de controles
Visão geral do controle de rótulo
Eventos de controle
Tipos de controles personalizados
Pintura e desenho em controles
Fornecendo informações de acessibilidade para controles
Posição e layout de controles (Windows
Forms .NET)
Artigo • 09/02/2023 • 12 minutos para o fim da leitura

O posicionamento do controle em Windows Forms é determinado não apenas pelo


controle, mas também pelo pai do controle. Este artigo descreve as diferentes
configurações fornecidas pelos controles e os diferentes tipos de contêineres pai que
afetam o layout.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Posição e tamanho fixos


A posição em que um controle aparece em um pai é determinada pelo valor da Location
propriedade em relação à parte superior esquerda da superfície pai. A coordenada de
posição superior esquerda no pai é (x0,y0) . O tamanho do controle é determinado
pela Size propriedade e representa a largura e a altura do controle.

Quando um controle é adicionado a um pai que impõe o posicionamento automático, a


posição e o tamanho do controle são alterados. Nesse caso, a posição e o tamanho do
controle podem não ser ajustados manualmente, dependendo do tipo de pai.

As MaximumSize propriedades e MinimumSize ajudam a definir o espaço mínimo e


máximo que um controle pode usar.
Margem e preenchimento
Há duas propriedades de controle que ajudam com o posicionamento preciso de
controles: Margin e Padding.

A Margin propriedade define o espaço ao redor do controle que mantém outros


controles a uma distância especificada das bordas do controle.

A Padding propriedade define o espaço no interior de um controle que mantém o


conteúdo do controle (por exemplo, o valor de sua Text propriedade) uma distância
especificada das bordas do controle.

A figura a seguir mostra as Margin propriedades e Padding em um controle .

O Designer do Visual Studio respeitará essas propriedades quando você estiver


posicionando e redimensionando controles. Os snaplines aparecem como guias para
ajudá-lo a permanecer fora da margem especificada de um controle. Por exemplo, o
Visual Studio exibe o snapline quando você arrasta um controle ao lado de outro
controle:

Posicionamento e tamanho automáticos


Os controles podem ser colocados automaticamente dentro de seus pais. Alguns
contêineres pai forçam o posicionamento, enquanto outros respeitam as configurações
de controle que orientam o posicionamento. Há duas propriedades em um controle que
ajudam o posicionamento e o tamanho automáticos em um pai: Dock e Anchor.

A ordem de desenho pode afetar o posicionamento automático. A ordem na qual um


controle é desenhado determinado pelo índice do controle na coleção pai Controls .
Esse índice é conhecido como .Z-order Cada controle é desenhado na ordem inversa
em que aparecem na coleção. Ou seja, a coleção é uma coleção desenhada primeiro na
última e última no primeiro desenho.

As MinimumSize propriedades e MaximumSize ajudam a definir o espaço mínimo e


máximo que um controle pode usar.

Dock
A Dock propriedade define qual borda do controle é alinhada ao lado correspondente
do pai e como o controle é redimensionado dentro do pai.

Quando um controle é encaixado, o contêiner determina o espaço que deve ocupar e


redimensiona e coloca o controle. A largura e a altura do controle ainda são respeitadas
com base no estilo de encaixe. Por exemplo, se o controle estiver encaixado na parte
superior, o Height do controle será respeitado, mas o Width será ajustado
automaticamente. Se um controle estiver encaixado à esquerda, o Width do controle
será respeitado, mas o Height será ajustado automaticamente.

O Location do controle não pode ser definido manualmente, pois encaixar um controle
controla automaticamente sua posição.

O Z-order do controle afeta o encaixe. À medida que os controles encaixados são


dispostos, eles usam qual espaço está disponível para eles. Por exemplo, se um controle
for desenhado primeiro e encaixado na parte superior, ele ocupará toda a largura do
contêiner. Se um próximo controle estiver encaixado à esquerda, ele terá menos espaço
vertical disponível para ele.

Se o controle Z-order for invertido, o controle encaixado à esquerda agora terá mais
espaço inicial disponível. O controle usa toda a altura do contêiner. O controle
encaixado na parte superior tem menos espaço horizontal disponível para ele.

À medida que o contêiner cresce e encolhe, os controles encaixados no contêiner são


reposicionados e redimensionados para manter suas posições e tamanhos aplicáveis.
Se vários controles estiverem encaixados no mesmo lado do contêiner, eles serão
empilhados de acordo com seu Z-order.

Âncora
Ancorar um controle permite que você vincule o controle a um ou mais lados do
contêiner pai. Conforme o contêiner muda de tamanho, qualquer controle filho manterá
sua distância para o lado ancorado.

Um controle pode ser ancorado em um ou mais lados, sem restrição. A âncora é


definida com a Anchor propriedade .
Dimensionamento automático
A AutoSize propriedade permite que um controle altere seu tamanho, se necessário,
para se ajustar ao tamanho especificado pela PreferredSize propriedade . Você ajusta o
comportamento de dimensionamento para controles específicos configurando a
propriedade AutoSizeMode .

Apenas alguns controles dão suporte à AutoSize propriedade . Além disso, alguns
controles que dão suporte à AutoSize propriedade também dão suporte à AutoSizeMode
propriedade .

Comportamento sempre Descrição


verdadeiro

O dimensionamento automático é Isso significa que ele nunca aumenta ou diminui um


um recurso de tempo de execução. controle e, em seguida, não tem mais efeito.

Se um controle mudar de tamanho, o Quando o conteúdo de um controle faz com que ele
valor de sua Location propriedade cresça, o controle aumenta para a direita e para baixo.
sempre permanecerá constante. Controles não crescem para a esquerda.
Comportamento sempre Descrição
verdadeiro

As Dock propriedades e Anchor são O valor da propriedade do Location controle é ajustado


honradas quando AutoSize é true . para o valor correto.

O Label controle é a exceção a essa regra. Quando você


definir o valor da propriedade de AutoSize um controle
encaixado Label como true , o Label controle não será
estendido.

As propriedades e MinimumSize de As MaximumSize propriedades e MinimumSize não são


MaximumSize um controle são afetadas pela AutoSize propriedade .
sempre honradas,
independentemente do valor de sua
AutoSize propriedade.

Não há um tamanho mínimo Isso significa que, se um controle for definido para reduzir
definido por padrão. AutoSize e não tiver conteúdo, o valor de sua Size
propriedade será (0x,0y) . Nesse caso, o controle será
reduzido a um ponto e não ficará visível imediatamente.

Se um controle não implementar o Isso significa que a configuração AutoSize como true
GetPreferredSize método , o método não terá efeito.
retornará o GetPreferredSize último
valor atribuído à Size propriedade .

Um controle em uma Esse tamanho é imposto como um tamanho máximo. Esse


TableLayoutPanel célula sempre não é o caso quando a célula faz parte de uma AutoSize
encolhe para caber na célula até que linha ou coluna.
ela MinimumSize seja atingida.

Propriedade AutoSizeMode
A AutoSizeMode propriedade fornece um controle mais refinado sobre o
comportamento padrão AutoSize . A propriedade AutoSizeMode especifica como um
controle dimensiona a si mesmo de acordo com seu conteúdo. O conteúdo, por
exemplo, pode ser o texto de um Button controle ou os controles filho de um contêiner.

A lista a seguir mostra os AutoSizeMode valores e seu comportamento.

AutoSizeMode.GrowAndShrink

O controle aumenta ou diminui para conter o conteúdo.

Os MinimumSize valores e MaximumSize são honrados, mas o valor atual da Size


propriedade é ignorado.
Esse é o mesmo comportamento que os controles com a AutoSize propriedade e
nenhuma AutoSizeMode propriedade.

AutoSizeMode.GrowOnly

O controle cresce tanto quanto necessário para abranger seu conteúdo, mas não
reduzirá menor que o valor especificado por sua Size propriedade.

Esse é o valor padrão de AutoSizeMode .

Controles que dão suporte à propriedade AutoSize


A tabela a seguir descreve o nível de suporte de dimensionamento automático por
controle:

Control AutoSize Suportado AutoSizeMode Suportado

Button ✔️ ✔️

CheckedListBox ✔️ ✔️

FlowLayoutPanel ✔️ ✔️

Form ✔️ ✔️

GroupBox ✔️ ✔️

Panel ✔️ ✔️

TableLayoutPanel ✔️ ✔️

CheckBox ✔️ ❌

DomainUpDown ✔️ ❌

Label ✔️ ❌

LinkLabel ✔️ ❌

MaskedTextBox ✔️ ❌

NumericUpDown ✔️ ❌

RadioButton ✔️ ❌

TextBox ✔️ ❌

TrackBar ✔️ ❌

CheckedListBox ❌ ❌
Control AutoSize Suportado AutoSizeMode Suportado

ComboBox ❌ ❌

DataGridView ❌ ❌

DateTimePicker ❌ ❌

ListBox ❌ ❌

ListView ❌ ❌

MaskedTextBox ❌ ❌

MonthCalendar ❌ ❌

ProgressBar ❌ ❌

PropertyGrid ❌ ❌

RichTextBox ❌ ❌

SplitContainer ❌ ❌

TabControl ❌ ❌

TabPage ❌ ❌

TreeView ❌ ❌

WebBrowser ❌ ❌

ScrollBar ❌ ❌

Dimensionamento automático no ambiente de design

A tabela a seguir descreve o comportamento de dimensionamento de um controle em


tempo de design, com base no valor de suas AutoSize propriedades e AutoSizeMode .

Substitua a SelectionRules propriedade para determinar se um determinado controle


está em um estado redimensionável pelo usuário. Na tabela a seguir, "não é possível
redimensionar" significa Moveable apenas " pode redimensionar" significa AllSizeable e
Moveable.

Configuração Configuração Comportamento


de AutoSize de
AutoSizeMode
Configuração Configuração Comportamento
de AutoSize de
AutoSizeMode

true Propriedade O usuário não pode redimensionar o controle em tempo de


não disponível. design, exceto pelos seguintes controles:

- TextBox
- MaskedTextBox
- RichTextBox
- TrackBar

true GrowAndShrink O usuário não pode redimensionar o controle em tempo de


design.

true GrowOnly O usuário pode redimensionar o controle em tempo de


design. Quando a Size propriedade é definida, o usuário só
pode aumentar o tamanho do controle.

false ou Não aplicável. O usuário pode redimensionar o controle em tempo de


AutoSize está design.
oculto

7 Observação

Para maximizar a produtividade, o Designer de Windows Forms no Visual Studio


sombreia a AutoSize propriedade da Form classe . Em tempo de design, o
formulário se comporta como se a AutoSize propriedade estivesse definida
false como , independentemente de sua configuração real. Em runtime, nenhuma
acomodação especial é feita e a AutoSize propriedade é aplicada conforme
especificado pela configuração da propriedade.

Contêiner: Formulário
O Form é o objeto principal do Windows Forms. Um aplicativo Windows Forms
geralmente terá um formulário exibido o tempo todo. Os formulários contêm controles
e respeitam as Location propriedades e Size do controle para posicionamento manual.
Os formulários também respondem à propriedade Dock para posicionamento
automático.

Na maioria das vezes, um formulário terá alças nas bordas que permitem ao usuário
redimensionar o formulário. A Anchor propriedade de um controle permitirá que o
controle cresça e diminua à medida que o formulário for redimensionado.
Contêiner: Painel
O Panel controle é semelhante a um formulário em que simplesmente agrupa controles.
Ele dá suporte aos mesmos estilos de posicionamento manual e automático que um
formulário. Para obter mais informações, consulte a seção Contêiner: Formulário .

Um painel se mistura perfeitamente com o pai e corta qualquer área de um controle


que cai fora dos limites do painel. Se um controle estiver fora dos limites do painel e
AutoScroll estiver definido true como , as barras de rolagem aparecerão e o usuário
poderá rolar o painel.

Ao contrário do controle de caixa de grupo , um painel não tem uma legenda e uma
borda.

A imagem acima tem um painel com a BorderStyle propriedade definida para


demonstrar os limites do painel.

Contêiner: Caixa de grupo


O GroupBox controle fornece um agrupamento identificável para outros controles.
Normalmente, você usa uma caixa de grupo para subdividir um formulário por função.
Por exemplo, você pode ter um formulário que representa informações pessoais e os
campos relacionados a um endereço seriam agrupados. Em tempo de design, é fácil
mover a caixa de grupo junto com seus controles contidos.

A caixa de grupo dá suporte aos mesmos estilos de posicionamento manual e


automático que um formulário. Para obter mais informações, consulte a seção
Contêiner: Formulário . Uma caixa de grupo também corta qualquer parte de um
controle que cai fora dos limites do painel.
Ao contrário do controle de painel , uma caixa de grupo não tem a capacidade de rolar
conteúdo e exibir barras de rolagem.

Contêiner: Layout de Fluxo


O FlowLayoutPanel controle organiza seu conteúdo em uma direção de fluxo horizontal
ou vertical. Você pode encapsular o conteúdo do controle de uma linha para outra ou
de uma coluna para a próxima. Como alternativa, você pode recortar, em vez de
encapsular seu conteúdo.

Você pode especificar a direção do fluxo definindo o valor da FlowDirection propriedade


. O FlowLayoutPanel controle inverte corretamente sua direção de fluxo em layouts da
direita para a esquerda (RTL). Você também pode especificar se o FlowLayoutPanel
conteúdo do controle é encapsulado ou recortado definindo o valor da WrapContents
propriedade.

O FlowLayoutPanel controle dimensiona automaticamente para seu conteúdo quando


você define a AutoSize propriedade como true . Ele também fornece uma FlowBreak
propriedade para seus controles filho. Definir o valor da FlowBreak propriedade como
true faz com que o FlowLayoutPanel controle pare de dispor controles na direção do

fluxo atual e encapsule para a próxima linha ou coluna.


A imagem acima tem dois FlowLayoutPanel controles com a BorderStyle propriedade
definida para demonstrar os limites do controle.

Contêiner: Layout da tabela


O TableLayoutPanel controle organiza seu conteúdo em uma grade. Como o layout é
feito no tempo de design e no tempo de execução, ele pode mudar dinamicamente
conforme o ambiente do aplicativo é alterado. Isso dá aos controles no painel a
capacidade de redimensionar proporcionalmente, para que eles possam responder a
alterações como o redimensionamento do controle pai ou a alteração do comprimento
do texto devido à localização.

Qualquer controle Windows Forms pode ser um filho do TableLayoutPanel controle ,


incluindo outras instâncias do TableLayoutPanel. Isso permite criar layouts sofisticados
que se adaptam às alterações no tempo de execução.

Você também pode controlar a direção da expansão (horizontal ou vertical) depois que
o TableLayoutPanel controle estiver cheio de controles filho. Por padrão, o
TableLayoutPanel controle se expande para baixo adicionando linhas.

Você pode controlar o tamanho e o estilo das linhas e colunas usando as RowStyles
propriedades e ColumnStyles . É possível definir as propriedades de linhas ou colunas
individualmente.

O TableLayoutPanel controle adiciona as seguintes propriedades aos controles filho:


Cell , Column , Row , ColumnSpan e RowSpan .
A imagem acima tem uma tabela com a CellBorderStyle propriedade definida para
demonstrar os limites de cada célula.

Contêiner: dividir contêiner


O controle Windows Forms SplitContainer pode ser considerado como um controle
composto; são dois painéis separados por uma barra móvel. Quando o ponteiro do
mouse passa sobre a barra, ele muda de forma para mostrar que a barra é móvel.

Com o SplitContainer controle, você pode criar interfaces de usuário complexas;


geralmente, uma seleção em um painel determina quais objetos são mostrados no
outro painel. Essa disposição é eficaz para exibir e navegar informações. Ter dois painéis
permite agregar as informações em áreas e a barra, ou “divisor”, tornando mais fácil
para os usuários redimensionar os painéis.

A imagem acima tem um contêiner dividido para criar um painel esquerdo e direito. O
painel direito contém um segundo contêiner dividido com o Orientation definido como
Vertical. A BorderStyle propriedade é definida para demonstrar os limites de cada painel.

Contêiner: controle guia


O TabControl exibe várias guias, como divisores em um bloco de anotações ou rótulos
em um conjunto de pastas em um armário de arquivamento. As guias podem conter
imagens e outros controles. Use o controle guia para produzir o tipo de caixa de
diálogo de várias páginas que aparece em muitos locais no sistema operacional
Windows, como as propriedades Painel de Controle e Display. Além disso, o TabControl
pode ser usado para criar páginas de propriedades, que são usadas para definir um
grupo de propriedades relacionadas.

A propriedade mais importante do TabControl é TabPages, que contém as guias


individuais. Cada guia individual é um TabPage objeto .
Visão geral do controle de rótulo
(Windows Forms .NET)
Artigo • 15/02/2023 • 2 minutos para o fim da leitura

Label Windows Forms controles são usados para exibir texto que não pode ser editado
pelo usuário. Eles são usados para identificar objetos em um formulário e para fornecer
uma descrição do que um determinado controle representa ou faz. Por exemplo, você
pode usar rótulos para adicionar legendas descritivas em caixas de texto, caixas de
listagem, caixas de combinação e assim por diante. Também é possível escrever código
para alterar o texto exibido por um rótulo em resposta a eventos em tempo de
execução.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Trabalhando com o controle de rótulo


Como o Label controle não pode receber o foco, ele pode ser usado para criar chaves
de acesso para outros controles. Uma tecla de acesso permite que um usuário
concentre o próximo controle na ordem de tabulação pressionando a tecla Alt com a
tecla de acesso escolhida. Para obter mais informações, consulte Usar um rótulo para
concentrar um controle.

A legenda exibida no rótulo está contida na Text propriedade . A TextAlign propriedade


permite que você defina o alinhamento do texto dentro do rótulo. Para obter mais
informações, consulte Como definir o texto exibido por um controle dos Windows
Forms.

Confira também
Usar um rótulo para concentrar um controle (Windows Forms .NET)
Como definir o texto exibido por um controle (Windows Forms .NET)
AutoScaleMode
Scale
PerformAutoScale
AutoScaleDimensions
Eventos de controle (Windows Forms
.NET)
Artigo • 10/02/2023 • 3 minutos para o fim da leitura

Os controles fornecem eventos gerados quando o usuário interage com o controle ou


quando o estado do controle é alterado. Este artigo descreve os eventos comuns
compartilhados pela maioria dos controles, eventos gerados pela interação do usuário e
eventos exclusivos de controles específicos. Para obter mais informações sobre eventos
em Windows Forms, consulte Visão geral de eventos e Manipulação e geração de
eventos.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Para obter mais informações sobre como adicionar ou remover um manipulador de


eventos de controle, consulte Como manipular um evento.

Eventos comuns
Os controles fornecem um conjunto de eventos comuns por meio da classe base:
Control. Nem todos os controles respondem a todos os eventos. Por exemplo, o Label
controle não responde à entrada do teclado, portanto, o Control.PreviewKeyDown
evento não é gerado. A maioria dos eventos compartilhados se enquadra nessas
categorias:

Eventos de mouse
Eventos de teclado
Eventos de propriedade alterada
Outros eventos

Eventos de mouse
Considerando Windows Forms é uma tecnologia de interface do usuário, a entrada do
mouse é a principal maneira como os usuários interagem com um aplicativo Windows
Forms. Todos os controles fornecem eventos básicos relacionados ao mouse:

MouseClick
MouseDoubleClick
MouseDown
MouseEnter
MouseHover
MouseLeave
MouseMove
MouseUp
MouseWheel
Click

Para obter mais informações, consulte Usando eventos do mouse.

Eventos de teclado
Se o controle responder à entrada do usuário, como um TextBox controle ou Button , o
evento de entrada apropriado será gerado para o controle. O controle deve estar
focado para receber eventos de teclado. Alguns controles, como o Label controle , não
podem ser focados e não podem receber eventos de teclado. Veja a seguir uma lista de
eventos de teclado:

KeyDown
KeyPress
KeyUp

Para obter mais informações, consulte Usando eventos de teclado.

Eventos de propriedade alterada


Windows Forms segue o padrão PropertyNameChanged para propriedades que têm
eventos de alteração. O mecanismo de associação de dados fornecido pelo Windows
Forms reconhece esse padrão e se integra bem a ele. Ao criar seus próprios controles,
implemente esse padrão.

Esse padrão implementa as seguintes regras, usando a propriedade FirstName como


exemplo:

Nomeie sua propriedade: FirstName .


Crie um evento para a propriedade usando o padrão PropertyNameChanged :
FirstNameChanged .

Crie um método privado ou protegido usando o padrão OnPropertyNameChanged :


OnFirstNameChanged .
Se o FirstName conjunto de propriedades modificar o valor de backup, o
OnFirstNameChanged método será chamado. O OnFirstNameChanged método gera o
FirstNameChanged evento .

Aqui estão alguns dos eventos de alteração de propriedade comuns para um controle:

Evento Descrição

BackColorChanged Ocorre quando o valor da propriedade BackColor muda.

BackgroundImageChanged Ocorre quando o valor da propriedade BackgroundImage muda.

BindingContextChanged Ocorre quando o valor da propriedade BindingContext muda.

DockChanged Ocorre quando o valor da propriedade Dock muda.

EnabledChanged Ocorre quando o valor da propriedade Enabled é alterado.

FontChanged Ocorre quando o valor da propriedade Font muda.

ForeColorChanged Ocorre quando o valor da propriedade ForeColor muda.

LocationChanged Ocorre quando o valor da propriedade Location é alterado.

SizeChanged Ocorre quando o valor da propriedade Size muda.

VisibleChanged Ocorre quando o valor da propriedade Visible muda.

Para obter uma lista completa de eventos, consulte a seção Eventos da Classe de
Controle.

Outros eventos
Os controles também gerarão eventos com base no estado do controle ou em outras
interações com o controle. Por exemplo, o HelpRequested evento será gerado se o
controle tiver foco e o usuário pressionar a tecla F1 . Esse evento também será gerado
se o usuário pressionar o botão de Ajuda contextual em um formulário e pressionar o
cursor de ajuda no controle.

Outro exemplo é quando um controle é alterado, movido ou redimensionado, o Paint


evento é gerado. Esse evento oferece ao desenvolvedor a oportunidade de desenhar no
controle e alterar sua aparência.

Para obter uma lista completa de eventos, consulte a seção Eventos da Classe de
Controle.
Confira também
Como manipular um evento
Visão geral de eventos
Usando eventos do mouse
Usando eventos de teclado
System.Windows.Forms.Control
System.Windows.Forms.Control.Click
System.Windows.Forms.Button
Tipos de controles personalizados
(Windows Forms .NET)
Artigo • 10/02/2023 • 5 minutos para o fim da leitura

Com Windows Forms, você pode desenvolver e implementar novos controles. Você
pode criar um novo controle de usuário, modificar controles existentes por meio de
herança e escrever um controle personalizado que faz sua própria pintura.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Decidir qual tipo de controle criar pode ser confuso. Este artigo destaca as diferenças
entre os vários tipos de controles dos quais você pode herdar e fornece informações
sobre como escolher um tipo específico de controle para seu projeto.

Se... Criar um...

Você deseja combinar a funcionalidade de vários Controle composto herdando de


controles dos Windows Forms em uma única System.Windows.Forms.UserControl.
unidade reutilizável.

A maioria da funcionalidade que você precisa já é Controle estendido herdando de


idêntica a um controle Windows Forms existente. um controle de Windows Forms
Você não precisa de uma interface gráfica específico.
personalizada do usuário ou deseja criar uma nova
interface gráfica do usuário para um controle
existente.

Você deseja fornecer uma representação gráfica Controle personalizado herdando


personalizada do seu controle. de System.Windows.Forms.Control.
Você precisa implementar funcionalidades
personalizadas que não estão disponíveis por meio
de controles padrão.

Classe de controle base


A Control classe é a classe base para controles Windows Forms. Ele fornece a
infraestrutura necessária para exibição visual em aplicativos Windows Forms e fornece
os seguintes recursos:

Expõe um identificador de janela.


Gerencia o roteamento de mensagens.
Fornece eventos de teclado e mouse, além de muitos outros eventos da interface
do usuário.
Fornece recursos de layout avançados.
Contém muitas propriedades específicas para exibição visual, como ForeColor,
BackColor, Heighte Width.
Fornece a segurança e o suporte a threading necessários para um controle dos
Windows Forms atuar como um controle do Microsoft® ActiveX®.

Como grande parte da infraestrutura é fornecida pela classe base, é relativamente fácil
desenvolver seus próprios controles Windows Forms.

Controles de composição
Um controle de composição é uma coleção de controles dos Windows Forms
encapsulados em um contêiner comum. Esse tipo de controle é, às vezes, chamado de
controle de usuário. Os controles contidos são chamados controles constituintes.

Um controle de composição contém todas as funcionalidades inerentes associadas a


cada um dos controles dos Windows Forms contidos e permite que você exponha
seletivamente e associe suas propriedades. Um controle de composição também é ideal
para a funcionalidade de manipulação do teclado padrão sem nenhum esforço adicional
de desenvolvimento de sua parte.

Por exemplo, um controle de composição poderia ser criado para exibir dados de
endereço de cliente de um banco de dados. Esse controle incluiria um DataGridView
controle para exibir os campos de banco de dados, um BindingSource para manipular a
associação a uma fonte de dados e um BindingNavigator controle para percorrer os
registros. Você pode expor seletivamente propriedades de vinculação de dados, além de
poder empacotar e reutilizar todo o controle do aplicativo para o aplicativo.

Para criar um controle composto, derive da UserControl classe . A UserControl classe


base fornece roteamento de teclado para controles filho e permite que os controles
filho funcionem como um grupo.

Controles estendidos
Você pode derivar um controle herdado de qualquer controle Windows Forms existente.
Com essa abordagem, você pode manter toda a funcionalidade inerente de um controle
Windows Forms e, em seguida, estender essa funcionalidade adicionando propriedades
personalizadas, métodos ou outros recursos. Com essa opção, você pode substituir a
lógica de pintura do controle base e estender a interface do usuário alterando sua
aparência.

Por exemplo, você pode criar um controle derivado do Button controle que rastreia
quantas vezes um usuário clicou nele.

Em alguns controles, você também pode adicionar uma aparência personalizada à


interface gráfica do usuário do controle substituindo o OnPaint método da classe base.
Para um botão estendido que rastreia cliques, você pode substituir o OnPaint método
para chamar a implementação base de OnPainte, em seguida, desenhar a contagem de
cliques em um canto da Button área de cliente do controle.

Controles personalizados
Outra maneira de criar um controle é criar um substancialmente desde o início
herdando de Control. A Control classe fornece toda a funcionalidade básica exigida
pelos controles, incluindo eventos de manipulação de mouse e teclado, mas nenhuma
funcionalidade específica do controle ou interface gráfica.

Criar um controle herdando da Control classe requer muito mais pensamento e esforço
do que herdar de UserControl ou de um controle Windows Forms existente. Como uma
grande quantidade de implementação é deixada para você, o controle pode ter maior
flexibilidade do que um controle de composição ou estendido e você pode personalizar
o controle para atender às suas necessidades.

Para implementar um controle personalizado, você deve escrever código para o OnPaint
evento do controle, bem como qualquer código específico do recurso necessário. Você
também pode substituir o método e manipular mensagens do WndProc Windows
diretamente. Essa é a maneira mais eficiente para criar um controle, mas, para usar essa
técnica com eficiência, você precisa estar familiarizado com a API do Win32® da
Microsoft.

Um exemplo de um controle personalizado é um controle de relógio que duplica a


aparência e o comportamento de um relógio analógico. A pintura personalizada é
invocada para fazer com que as mãos do relógio se movam em resposta a Tick eventos
de um componente interno Timer .

Controles ActiveX
Embora a infraestrutura dos Windows Forms tenha sido otimizada para hospedar
controles dos Windows Forms, você ainda poderá usar controles ActiveX. Há suporte
para essa tarefa no Visual Studio.

Controles sem janelas


As tecnologias Microsoft Visual Basic® 6.0 e ActiveX dão suporte a controles sem
janelas . Não há suporte para controles sem janelas no Windows Forms.

Experiência de design personalizado


Se você precisar implementar uma experiência de tempo de design personalizada, você
poderá criar seu próprio designer. Para controles compostos, derive sua classe de
designer personalizada das ParentControlDesigner classes ou DocumentDesigner . Para
controles estendidos e personalizados, derive sua classe de designer personalizado da
ControlDesigner classe .

Use o DesignerAttribute para associar seu controle ao designer.

As informações a seguir estão desatualizadas, mas podem ajudá-lo.

(Visual Studio 2013) Estendendo o suporte de Design-Time.


(Visual Studio 2013) Como criar um controle de Windows Forms que aproveita
Design-Time recursos.

Confira também
Visão geral do uso de controles (Windows Forms .NET)
Pintura e desenho em controles
(Windows Forms .NET)
Artigo • 11/02/2023 • 5 minutos para o fim da leitura

A pintura personalizada de controles é uma das muitas tarefas complicadas facilitadas


por Windows Forms. Ao criar um controle personalizado, você tem muitas opções
disponíveis para lidar com a aparência gráfica do controle. Se você estiver criando um
controle personalizado, ou seja, um controle herdado de Control, deverá fornecer
código para renderizar sua representação gráfica.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Se você estiver criando um controle composto, esse é um controle que herda de


UserControl ou um dos controles de Windows Forms existentes, você pode substituir a
representação gráfica padrão e fornecer seu próprio código gráfico.

Se você quiser fornecer renderização personalizada para um controle existente sem criar
um novo controle, suas opções se tornarão mais limitadas. No entanto, ainda há uma
ampla gama de possibilidades gráficas para seus controles e aplicativos.

Os elementos a seguir estão envolvidos na renderização de controles:

A funcionalidade de desenho fornecida pela classe


System.Windows.Forms.Controlbase .
Os elementos essenciais da biblioteca de elementos gráficos GDI.
A geometria da região de desenho.
O procedimento para liberar recursos gráficos.

Desenho fornecido pelo controle


A classe Control base fornece funcionalidade de desenho por meio de seu Paint evento.
Um controle aciona o Paint evento sempre que precisa atualizar sua exibição. Para obter
mais informações sobre eventos no .NET, consulte Manipulando e gerando eventos.

A classe de dados de evento para o Paint evento, PaintEventArgs, contém os dados


necessários para desenhar um controle – um identificador para um objeto gráfico e um
retângulo que representa a região na qual desenhar.
C#

public class PaintEventArgs : EventArgs, IDisposable


{

public System.Drawing.Rectangle ClipRectangle {get;}


public System.Drawing.Graphics Graphics {get;}

// Other properties and methods.


}

Graphics é uma classe gerenciada que encapsula a funcionalidade de desenho,


conforme descrito na discussão da GDI mais adiante neste artigo. O ClipRectangle é
uma instância da Rectangle estrutura e define a área disponível na qual um controle
pode desenhar. Um desenvolvedor de controle pode calcular o ClipRectangle usando a
ClipRectangle propriedade de um controle, conforme descrito na discussão sobre
geometria mais adiante neste artigo.

OnPaint
Um controle deve fornecer lógica de renderização substituindo o OnPaint método
herdado de Control. OnPaint obtém acesso a um objeto gráfico e um retângulo para
desenhar por meio do Graphics e as ClipRectangle propriedades da PaintEventArgs
instância passadas para ele.

O código a seguir usa o System.Drawing namespace :

C#

protected override void OnPaint(PaintEventArgs e)


{
// Call the OnPaint method of the base class.
base.OnPaint(e);

// Declare and instantiate a new pen that will be disposed of at the end
of the method.
using var myPen = new Pen(Color.Aqua);

// Create a rectangle that represents the size of the control, minus 1


pixel.
var area = new Rectangle(new Point(0, 0), new Size(this.Size.Width - 1,
this.Size.Height - 1));

// Draw an aqua rectangle in the rectangle represented by the control.


e.Graphics.DrawRectangle(myPen, area);
}
O OnPaint método da classe base Control não implementa nenhuma funcionalidade de
desenho, mas apenas invoca os delegados de eventos registrados com o Paint evento.
Ao substituir OnPaint, você normalmente deve invocar o OnPaint método da classe base
para que os delegados registrados recebam o Paint evento. No entanto, os controles
que pintam toda a superfície não devem invocar o da OnPaintclasse base, pois isso
introduz cintilação.

7 Observação

Não invoque OnPaint diretamente do controle; em vez disso, invoque o Invalidate


método (herdado de Control) ou algum outro método que invoque Invalidate. O
Invalidate método, por sua vez, invoca OnPaint. O Invalidate método é
sobrecarregado e, dependendo dos argumentos fornecidos para Invalidate e ,
redesenha parte ou toda a área da tela.

O código no OnPaint método do controle será executado quando o controle for


desenhado pela primeira vez e sempre que for atualizado. Para garantir que o controle
seja redesenhado sempre que ele for redimensionado, adicione a seguinte linha ao
construtor do seu controle:

C#

SetStyle(ControlStyles.ResizeRedraw, true);

Onpaintbackground
A classe base Control define outro método útil para desenhar, o OnPaintBackground
método .

C#

protected virtual void OnPaintBackground(PaintEventArgs e);

OnPaintBackground pinta a tela de fundo (e dessa forma, a forma) da janela e tem a


garantia de ser rápida, enquanto OnPaint pinta os detalhes e pode ser mais lenta
porque solicitações de pintura individuais são combinadas em um Paint evento que
abrange todas as áreas que precisam ser redesenhadas. Talvez você queira invocar o
OnPaintBackground se, por exemplo, quiser desenhar uma tela de fundo colorida de
gradiente para o controle.
Embora OnPaintBackground tenha uma nomenclatura semelhante a um evento e use o
mesmo argumento que o OnPaint método , OnPaintBackground não é um método de
evento verdadeiro. Não há nenhum PaintBackground evento e OnPaintBackground não
invoca delegados de eventos. Ao substituir o OnPaintBackground método , uma classe
derivada não é necessária para invocar o OnPaintBackground método de sua classe base.

Noções básicas sobre a GDI+


A Graphics classe fornece métodos para desenhar várias formas, como círculos,
triângulos, arcos e reticências e métodos para exibir texto. O System.Drawing
namespace contém namespaces e classes que encapsulam elementos gráficos, como
formas (círculos, retângulos, arcos e outros), cores, fontes, pincéis e assim por diante.

Geometria da região de desenho


A ClientRectangle propriedade de um controle especifica a região retangular disponível
para o controle na tela do usuário, enquanto a ClipRectangle propriedade de
PaintEventArgs especifica a área pintada. Um controle pode precisar pintar apenas uma
parte da sua área disponível, como é o caso quando uma pequena seção da exibição do
controle é alterada. Nessas situações, um desenvolvedor de controle deve calcular o
retângulo real para desenhar e passá-lo para Invalidate. As versões sobrecarregadas de
Invalidate que usam um Rectangle ou Region como argumento usam esse argumento
para gerar a ClipRectangle propriedade de PaintEventArgs.

Liberando recursos gráficos


Objetos gráficos são caros porque usam recursos do sistema. Esses objetos incluem
instâncias da System.Drawing.Graphics classe e instâncias de System.Drawing.Brush,
System.Drawing.Pene outras classes gráficas. É importante que você crie um recurso
gráfico somente quando precisar dele e libere-o assim que terminar de usá-lo. Se você
criar uma instância de um tipo que implementa a interface, chame seu
IDisposableDispose método quando terminar de usar para liberar recursos.

Confira também
Tipos de controles personalizados
Fornecendo informações de
acessibilidade para controles (Windows
Forms .NET)
Artigo • 10/02/2023 • 2 minutos para o fim da leitura

Os recursos de acessibilidade são programas e dispositivos especializados que ajudam


as pessoas com deficiência a usarem computadores de forma mais eficaz. Alguns
exemplos incluem leitores de tela para pessoas cegas e utilitários de entrada de voz
para as pessoas que fornecem comandos verbais em vez de usar o mouse ou teclado.
Esses recursos de acessibilidade interagem com as propriedades de acessibilidade
expostas pelos controles dos Windows Forms. Essas propriedades são:

System.Windows.Forms.AccessibleObject
System.Windows.Forms.Control.AccessibleDefaultActionDescription
System.Windows.Forms.Control.AccessibleDescription
System.Windows.Forms.Control.AccessibleName
System.Windows.Forms.AccessibleRole

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Propriedade AccessibilityObject
Essa propriedade somente leitura contém uma AccessibleObject instância. O
AccessibleObject implementa a IAccessible interface , que fornece informações sobre a

descrição do controle, o local da tela, as habilidades de navegação e o valor. O designer


define esse valor quando o controle é adicionado ao formulário.

Propriedade
AccessibleDefaultActionDescription
Essa cadeia de caracteres descreve as ações do controle. Ela não aparece na janela
Propriedades e só pode ser definido no código. O exemplo a seguir define a
AccessibleDefaultActionDescription propriedade para um controle de botão:
C#

button1.AccessibleDefaultActionDescription = "Closes the application.";

Propriedade AccessibleDescription
Essa cadeia de caracteres descreve o controle. A AccessibleDescription propriedade
pode ser definida no janela Propriedades ou no código da seguinte maneira:

C#

button1.AccessibleDescription = "A button with text 'Exit'";

Propriedade AccessibleName
Esse é o nome de um controle relatado para os recursos de acessibilidade. A
AccessibleName propriedade pode ser definida no janela Propriedades ou no código da
seguinte maneira:

C#

button1.AccessibleName = "Order";

Propriedade AccessibleRole
Essa propriedade, que contém uma AccessibleRole enumeração, descreve a função de
interface do usuário do controle. Um novo controle tem o valor definido como Default .
Isso significaria que, por padrão, um Button controle atua como um Button . Pode ser
útil redefinir essa propriedade se um controle tiver outra função. Por exemplo, você
pode estar usando um PictureBox controle como um Chart e talvez queira que os
auxílios de acessibilidade relatem a função como um Chart , não como um PictureBox .
Também pode ser útil especificar essa propriedade para controles personalizados
desenvolvidos por você. Essa propriedade pode ser definida na janela Propriedades ou
no código da seguinte maneira:

C#

pictureBox1.AccessibleRole = AccessibleRole.Chart;
Confira também
Visão geral do controle de rótulo (Windows Forms .NET)
AccessibleObject
Control.AccessibilityObject
Control.AccessibleDefaultActionDescription
Control.AccessibleDescription
Control.AccessibleName
Control.AccessibleRole
AccessibleRole
Adicionar um controle a um formulário
(Windows Forms .NET)
Artigo • 09/02/2023 • 2 minutos para o fim da leitura

A maioria dos formulários é projetada adicionando controles à superfície do formulário


para definir uma interface do usuário (IU). Um controle é um componente em um
formulário usado para exibir informações ou aceitar a entrada do usuário.

A principal maneira de um controle ser adicionado a um formulário é por meio do


Visual Studio Designer, mas você também pode gerenciar os controles em um
formulário em tempo de execução por meio do código.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Adicionar com o Designer


O Visual Studio usa o Designer de Formulários para criar formulários. Há um painel
Controles que lista todos os controles disponíveis para seu aplicativo. Você pode
adicionar controles do painel de duas maneiras:

Adicionar o controle clicando duas vezes em


Quando um controle é clicado duas vezes, ele é adicionado automaticamente ao
formulário aberto atual com configurações padrão.
Adicionar o controle desenhando
Selecione o controle clicando nele. No formulário, arraste e selecione uma região. O
controle será colocado para se ajustar ao tamanho da região selecionada.

Adicionar com código


Os controles podem ser criados e adicionados a um formulário em tempo de execução
com a coleção do Controls formulário. Essa coleção também pode ser usada para
remover controles de um formulário.

O código a seguir adiciona e posiciona dois controles, um Label e um TextBox:

C#
Label label1 = new Label()
{
Text = "&First Name",
Location = new Point(10, 10),
TabIndex = 10
};

TextBox field1 = new TextBox()


{
Location = new Point(label1.Location.X, label1.Bounds.Bottom +
Padding.Top),
TabIndex = 11
};

Controls.Add(label1);
Controls.Add(field1);

Confira também
Definir o texto exibido por um controle do Windows Forms
Adicionar um atalho de tecla de acesso a um controle
System.Windows.Forms.Label
System.Windows.Forms.TextBox
System.Windows.Forms.Button
Adicionar um atalho de chave de acesso
a um controle (Windows Forms .NET)
Artigo • 15/02/2023 • 2 minutos para o fim da leitura

Uma chave de acesso é um caractere de sublinhado no texto de um menu, item de menu


ou rótulo de um controle como um botão. Com uma chave de acesso, o usuário pode
"clicar" em um botão pressionando a tecla Alt em combinação com a chave de acesso
predefinida. Por exemplo, se um botão executar um procedimento para imprimir um
formulário e, portanto, sua Text propriedade for definida como "Imprimir", adicionar
um e comercial (&) antes da letra "P" fazer com que a letra "P" seja sublinhada no texto
do botão em tempo de execução. O usuário pode executar o comando associado ao
botão pressionando Alt .

Controles que não podem receber foco não podem ter chaves de acesso, exceto
controles de rótulo.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Designer
Na janela Propriedades do Visual Studio, defina a propriedade Text como uma cadeia
de caracteres que inclui um e comercial (&) antes da letra que será a chave de acesso.
Por exemplo, para definir a letra "P" como a chave de acesso, insira &Imprimir.
Programático
Defina a Text propriedade como uma cadeia de caracteres que inclui um e comercial
(&) antes da letra que será o atalho.

C#

// Set the letter "P" as an access key.


button1.Text = "&Print";

Usar um rótulo para concentrar um controle


Embora um rótulo não possa ser focado, ele tem a capacidade de concentrar o próximo
controle na ordem de tabulação do formulário. Cada controle recebe um valor à
TabIndex propriedade , geralmente em ordem sequencial crescente. Quando a chave de
acesso é atribuída à propriedade Label.Text , o próximo controle na ordem de tabulação
sequencial é focado.

Usando o exemplo da seção Programmatic , se o botão não tiver nenhum conjunto de


texto, mas, em vez disso, apresentasse uma imagem de uma impressora, você poderia
usar um rótulo para concentrar o botão.

C#

// Set the letter "P" as an access key.


label1.Text = "&Print";
label1.TabIndex = 9
button1.TabIndex = 10
Exibir um e comercial
Ao definir o texto ou a legenda de um controle que interpreta um e comercial (&) como
uma chave de acesso, use dois e comercials consecutivos (&&) para exibir um único e
comercial. Por exemplo, o texto de um botão definido como "Print && Close" é exibido
na legenda de Print & Close :

C#

// Set the letter "P" as an access key.


button1.Text = "Print && Close";

Confira também
Definir o texto exibido por um controle Windows Forms
System.Windows.Forms.Button
System.Windows.Forms.Label
Como definir o texto exibido por um
controle (Windows Forms .NET)
Artigo • 10/02/2023 • 2 minutos para o fim da leitura

Windows Forms controles geralmente exibem algum texto relacionado à função


primária do controle. Por exemplo, um Button controle geralmente exibe uma legenda
indicando qual ação será executada se o botão for clicado. Para todos os controles, você
pode definir ou retornar o texto usando a Text propriedade . Você pode alterar a fonte
usando a Font propriedade .

Você também pode definir o texto usando o designer .

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Designer
1. Na janela Propriedades no Visual Studio, defina a propriedade Text do controle
como uma cadeia de caracteres apropriada.

Para criar uma tecla de atalho sublinhada, inclua um e comercial (&) antes da letra
que será a tecla de atalho.
2. Na janela Propriedades , selecione o botão de reticências ( ) ao lado da
propriedade Font .

Na caixa de diálogo fonte padrão, ajuste a fonte com configurações como tipo,
tamanho e estilo.

Programático
1. Defina a Text propriedade como uma cadeia de caracteres.

Para criar uma chave de acesso sublinhada, inclua um e comercial (&) antes da
letra que será a chave de acesso.
2. Defina a Font propriedade como um objeto do tipo Font.

C#

button1.Text = "Click here to save changes";


button1.Font = new Font("Arial", 10, FontStyle.Bold,
GraphicsUnit.Point);

7 Observação

Você pode usar um caractere de escape para exibir um caractere especial nos
elementos de interface do usuário que seriam normalmente interpretados de
maneira diferente, como itens de menu. Por exemplo, a seguinte linha de
código define o texto do item de menu para ler "& Agora para algo
completamente diferente":

C#

mpMenuItem.Text = "&& Now For Something Completely Different";

Confira também
Criar chaves de acesso para controles do Windows Forms
System.Windows.Forms.Control.Text
Como definir a ordem de tabulação no
Windows Forms (Windows Forms .NET)
Artigo • 10/02/2023 • 2 minutos para o fim da leitura

A ordem de tabulação é a ordem na qual um usuário move o foco de um controle para


outro pressionando a tecla Tab . Cada formulário tem sua própria ordem de tabulação.
Por padrão, a ordem de tabulação é igual à ordem em que você criou os controles. A
numeração da ordem de tabulação começa com zero e sobe em valor e é definida com
a TabIndex propriedade .

Você também pode definir a ordem de tabulação usando o designer .

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

A ordem de tabulação pode ser definida na janela Propriedades do designer usando a


TabIndex propriedade . A TabIndex propriedade de um controle determina onde ele
está posicionado na ordem de tabulação. Por padrão, o primeiro controle adicionado ao
designer tem um TabIndex valor de 0, o segundo tem um TabIndex de 1 e assim por
diante. Depois que o mais TabIndex alto tiver sido focado, pressionar Tab alternará e
concentrará o controle com o valor mais baixo TabIndex .

Controles de contêiner, como um GroupBox controle, tratam seus filhos como


separados do restante do formulário. Cada filho no contêiner tem seu próprio TabIndex
valor. Como um controle de contêiner não pode ser focado, quando a ordem de
tabulação atinge o controle de contêiner, o controle filho do contêiner com o menor
TabIndex é focado. À medida que a guia é pressionada, cada controle filho é focado de

acordo com seu TabIndex valor até o último controle. Quando Tab é pressionado no
último controle, o foco é retomado para o próximo controle no pai do contêiner, com
base no próximo TabIndex valor.

Qualquer controle dos muitos em seu formulário pode ser ignorado na ordem de
tabulação. Normalmente, pressionar Tab sucessivamente em tempo de execução
seleciona cada controle na ordem de tabulação. Ao desativar a TabStop propriedade, um
controle é passado na ordem de tabulação do formulário.
Designer
Use a janela Propriedades do designer do Visual Studio para definir a ordem de
tabulação de um controle.

1. Selecione o controle no designer.

2. Na janela Propriedades no Visual Studio, defina a propriedade TabIndex do


controle como um número apropriado.

Programático
1. Defina a TabIndex propriedade como um valor numérico.

C#

Button1.TabIndex = 1;

Remover um controle da ordem de tabulação


Você pode impedir que um controle receba o foco quando a tecla Tab é pressionada,
definindo a TabStop propriedade false como . O controle é ignorado quando você
percorre os controles com a tecla Tab . O controle não perde sua ordem de tabulação
quando essa propriedade é definida false como .
7 Observação

Um grupo de botões de opção tem uma única parada de tabulação em tempo de


execução. O botão selecionado, o botão com sua Checked propriedade definida
true como , tem sua TabStop propriedade definida automaticamente como true .
Outros botões no grupo de botões de opção têm sua propriedade definida
false como TabStop .

Definir TabStop com o designer


1. Selecione o controle no designer.

2. Na janela Propriedades no Visual Studio, defina a propriedade TabStop como


False .

Definir TabStop programaticamente


1. Defina a propriedade TabStop como false .

C#

Button1.TabStop = false;

Confira também
Adicionar um controle para um formulário
System.Windows.Forms.Control.TabIndex
System.Windows.Forms.Control.TabStop
Como encaixar e ancorar controles
(Windows Forms .NET)
Artigo • 10/02/2023 • 2 minutos para o fim da leitura

Se você estiver projetando um formulário que o usuário pode redimensionar em tempo


de execução, os controles no formulário deverão redimensionar e reposicionar
corretamente. Os controles têm duas propriedades que ajudam com o posicionamento
e o dimensionamento automáticos, quando o formulário muda de tamanho.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Control.Dock

Os controles encaixados preenchem as bordas do contêiner do controle, seja o


formulário ou um controle de contêiner. Por exemplo, o Windows Explorer encaixa
seu TreeView controle no lado esquerdo da janela e seu ListView controle no lado
direito da janela. O modo de encaixe pode ser qualquer lado do contêiner do
controle ou definido para preencher o espaço restante do contêiner.

Os controles são encaixados na ordem z inversa e a Dock propriedade interage


com a AutoSize propriedade . Para obter mais informações, consulte
Dimensionamento automático.

Control.Anchor
Quando o formulário de um controle ancorado é redimensionado, o controle
mantém a distância entre o controle e as posições de âncora. Por exemplo, se você
tiver um TextBox controle ancorado nas bordas esquerda, direita e inferior do
formulário, conforme o formulário for redimensionado, o TextBox controle será
redimensionado horizontalmente para manter a mesma distância dos lados direito
e esquerdo do formulário. O controle também se posiciona verticalmente para que
sua localização seja sempre a mesma distância da borda inferior do formulário. Se
um controle não estiver ancorado e o formulário for redimensionado, a posição do
controle em relação às bordas do formulário será alterada.

Para obter mais informações, consulte Posição e layout de controles.

Encaixar um controle
Um controle é encaixado definindo sua Dock propriedade.

7 Observação

Controles herdados devem ser Protected para poderem ser encaixados. Para
alterar o nível de acesso de um controle, defina sua propriedade Modificador na
janela Propriedades .
Usar o designer
Use a janela Propriedades do designer do Visual Studio para definir o modo de encaixe
de um controle.

1. Selecione o controle no designer.

2. Na janela Propriedades , selecione a seta à direita da propriedade Dock .

3. Selecione o botão que representa a borda do contêiner em que você deseja


encaixar o controle. Para preencher o conteúdo do formulário ou controle de
contêiner do controle, pressione a caixa central. Pressione (nenhum) para
desabilitar o encaixe.
O controle é redimensionado automaticamente para ajustar os limites da borda
encaixada.

Definir o Dock programaticamente


1. Defina a Dock propriedade em um controle . Neste exemplo, um botão é
encaixado no lado direito de seu contêiner:

C#

button1.Dock = DockStyle.Right;

Ancorar um controle
Um controle é ancorado em uma borda definindo sua Anchor propriedade como um ou
mais valores.

7 Observação

Determinados controles, como o ComboBox controle, têm um limite para sua


altura. Ancorar o controle na parte inferior do formulário ou contêiner não pode
forçar o controle a exceder o limite de altura.

Controles herdados devem ser Protected para serem ancorados. Para alterar o
nível de acesso de um controle, defina sua propriedade Modifiers na janela
Propriedades.

Usar o designer
Use a janela Propriedades do designer do Visual Studio para definir as bordas
ancoradas de um controle.

1. Selecione o controle no designer.

2. Na janela Propriedades , selecione a seta à direita da propriedade Âncora .

3. Para definir ou desafina uma âncora, selecione o braço superior, esquerdo, direito
ou inferior da cruz.
Definir Âncora programaticamente
1. Defina a Anchor propriedade em um controle . Neste exemplo, um botão é
ancorado nos lados direito e inferior de seu contêiner:

C#

button1.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;

Confira também
Posição e layout de controles.
System.Windows.Forms.Control.Anchor
System.Windows.Forms.Control.Dock
Como exibir uma imagem em um
controle (Windows Forms .NET)
Artigo • 10/02/2023 • 2 minutos para o fim da leitura

Vários controles Windows Forms podem exibir imagens. Essas imagens podem ser
ícones que esclarecem a finalidade do controle, como um ícone de diskette em um
botão que indica o comando Salvar. Como alternativa, os ícones podem ser imagens de
plano de fundo para dar ao controle a aparência e o comportamento desejados.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Exibir uma imagem – designer


No Visual Studio, use o Visual Designer para exibir uma imagem.

1. Abra o Designer Visual do formulário que contém o controle a ser alterado.

2. Selecione o controle .

3. No painel Propriedades , selecione a propriedade Image ou BackgroundImage do


controle .

4. Selecione as reticências ( ) para exibir a caixa de diálogo Selecionar Recurso e,


em seguida, selecione a imagem que você deseja exibir.
Exibir uma imagem – código
Defina a propriedade ou BackgroundImage do Image controle como um objeto do tipo
Image. Em geral, você carregará a imagem de um arquivo usando o FromFile método .

No exemplo de código a seguir, o caminho definido para o local da imagem é a pasta


Minhas Imagens . A maioria dos computadores que executam o sistema operacional
Windows inclui esse diretório. Isso também permite que usuários com níveis mínimos
de acesso do sistema executem o aplicativo com segurança. O exemplo de código a
seguir exige que você já tenha um formulário com um PictureBox controle adicionado.

C#

// Replace the image named below with your own icon.


// Note the escape character used (@) when specifying the path.
pictureBox1.Image = Image.FromFile
(System.Environment.GetFolderPath
(System.Environment.SpecialFolder.MyPictures)
+ @"\Image.gif");

Confira também
System.Drawing.Image.FromFile
System.Drawing.Image
System.Windows.Forms.Control.BackgroundImage
Como manipular um evento de controle
(Windows Forms .NET)
Artigo • 15/02/2023 • 5 minutos para o fim da leitura

Os eventos para controles (e para formulários) geralmente são definidos por meio do
Visual Designer do Visual Studio para Windows Forms. A configuração de um evento
por meio do Designer Visual é conhecida como manipulação de um evento em tempo
de design. Você também pode lidar com eventos dinamicamente no código, conhecido
como manipulação de eventos em tempo de execução. Um evento criado em tempo de
execução permite que você conecte manipuladores de eventos dinamicamente com
base no que seu aplicativo está fazendo no momento.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Manipular um evento – designer


No Visual Studio, use o Visual Designer para gerenciar manipuladores para eventos de
controle. O Designer Visual gerará o código do manipulador e o adicionará ao evento
para você.

Definir o manipulador
Use o painel Propriedades para adicionar ou definir o manipulador de um evento:

1. Abra o Designer Visual do formulário que contém o controle a ser alterado.

2. Selecione o controle .

3. Altere o modo do painel Propriedades para Eventos pressionando o botão de


eventos ( ).

4. Localize o evento ao qual você deseja adicionar um manipulador, por exemplo, o


evento Click :
5. Realize um dos seguintes procedimentos:

Clique duas vezes no evento para gerar um novo manipulador, ele ficará em
branco se nenhum manipulador for atribuído. Se não estiver em branco, essa
ação abrirá o código do formulário e navegará até o manipulador existente.

Use a caixa de seleção ( ) para escolher um manipulador existente.

A caixa de seleção listará todos os métodos que têm uma assinatura de


método compatível para o manipulador de eventos.

Limpar o manipulador
Para remover um manipulador de eventos, você não pode simplesmente excluir o
código do manipulador que está no arquivo code-behind do formulário, ele ainda é
referenciado pelo evento . Use o painel Propriedades para remover o manipulador de
um evento:

1. Abra o Designer Visual do formulário que contém o controle a ser alterado.

2. Selecione o controle .

3. Altere o modo do painel Propriedades para Eventos pressionando o botão de


eventos ( ).

4. Localize o evento que contém o manipulador que você deseja remover, por
exemplo, o evento Click :
5. Clique com o botão direito do mouse no evento e escolha Redefinir.

Manipular um evento – código


Normalmente, você adiciona manipuladores de eventos a controles em tempo de
design por meio do Visual Designer. No entanto, você pode criar controles em tempo
de execução, o que exige que você adicione manipuladores de eventos no código.
Adicionar manipuladores no código também oferece a chance de adicionar vários
manipuladores ao mesmo evento.

Adicionar um manipulador
O exemplo a seguir mostra como criar um controle e adicionar um manipulador de
eventos. Esse controle é criado no Button.Click manipulador de eventos com um botão
diferente. Quando Button1 é pressionado. O código move e dimensiona um novo
botão. O evento do Click novo botão é tratado pelo MyNewButton_Click método . Para
que o novo botão apareça, ele é adicionado à coleção do Controls formulário. Também
há código para remover o Button1.Click manipulador do evento, que é discutido na
seção Remover o manipulador .

C#

private void button1_Click(object sender, EventArgs e)


{
// Create and add the button
Button myNewButton = new()
{
Location = new Point(10, 10),
Size = new Size(120, 25),
Text = "Do work"
};

// Handle the Click event for the new button


myNewButton.Click += MyNewButton_Click;
this.Controls.Add(myNewButton);

// Remove this button handler so the user cannot do this twice


button1.Click -= button1_Click;
}

private void MyNewButton_Click(object sender, EventArgs e)


{

Para executar esse código, faça o seguinte em um formulário com o Visual Designer do
Visual Studio:

1. Adicione um novo botão ao formulário e nomeie-o como Button1.


2. Altere o modo do painel Propriedades para Eventos pressionando o botão de
evento ( ).
3. Clique duas vezes no evento Click para gerar um manipulador. Essa ação abre a
janela de código e gera um método em branco Button1_Click .
4. Substitua o código do método pelo código anterior acima.

Para obter mais informações sobre eventos C#, consulte Eventos (C#) Para obter mais
informações sobre eventos do Visual Basic, consulte Eventos (Visual Basic)

Remover o manipulador
A seção Adicionar um manipulador usou algum código para demonstrar a adição de um
manipulador. Esse código também continha uma chamada para remover um
manipulador:

C#

button1.Click -= button1_Click;

Essa sintaxe pode ser usada para remover qualquer manipulador de eventos de
qualquer evento.

Para obter mais informações sobre eventos C#, consulte Eventos (C#) Para obter mais
informações sobre eventos do Visual Basic, consulte Eventos (Visual Basic)
Como usar vários eventos com o mesmo
manipulador
Com o painel Propriedades do Visual Studio Visual Designer, você pode selecionar o
mesmo manipulador já em uso por um evento diferente. Siga as instruções na seção
Definir o manipulador para selecionar um manipulador existente em vez de criar um
novo.

Em C#, o manipulador é anexado ao evento de um controle no código do designer do


formulário, que foi alterado por meio do Visual Designer. Para obter mais informações
sobre eventos C#, consulte Eventos (C#)

Visual Basic
No Visual Basic, o manipulador é anexado ao evento de um controle no arquivo code-
behind do formulário, em que o código do manipulador de eventos é declarado. Várias
Handles palavras-chave podem ser adicionadas ao código do manipulador de eventos

para usá-lo com vários eventos. O Designer Visual gerará a Handles palavra-chave para
você e a adicionará ao manipulador de eventos. No entanto, você pode fazer isso
facilmente por conta própria para qualquer manipulador de eventos e eventos de
controle, desde que a assinatura do método do manipulador corresponda ao evento.
Para obter mais informações sobre eventos do Visual Basic, consulte Eventos (Visual
Basic)

Esse código demonstra como o mesmo método pode ser usado como um manipulador
para dois eventos diferentes Button.Click :

VB

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles


Button1.Click, Button2.Click
'Do some work to handle the events
End Sub

Confira também
Eventos de controle
Visão geral de eventos
Usando eventos do mouse
Usando eventos de teclado
System.Windows.Forms.Button
Como fazer chamadas thread-safe para
controles (Windows Forms .NET)
Artigo • 15/02/2023 • 4 minutos para o fim da leitura

O multithreading pode melhorar o desempenho de aplicativos Windows Forms, mas o


acesso a controles Windows Forms não é inerentemente thread-safe. O multithreading
pode expor seu código a bugs sérios e complexos. Dois ou mais threads que manipulam
um controle podem forçar o controle a um estado inconsistente e levar a condições de
corrida, deadlocks e congelamentos ou travamentos. Se você implementar o
multithreading em seu aplicativo, certifique-se de chamar controles entre threads de
uma maneira thread-safe. Para obter mais informações, consulte Práticas recomendadas
de threading gerenciado.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Há duas maneiras de chamar com segurança um controle Windows Forms de um thread


que não criou esse controle. Use o System.Windows.Forms.Control.Invoke método para
chamar um delegado criado no thread principal, que, por sua vez, chama o controle. Ou
implemente um System.ComponentModel.BackgroundWorker, que usa um modelo
controlado por eventos para separar o trabalho feito no thread em segundo plano dos
relatórios sobre os resultados.

Chamadas entre threads não seguras


Não é seguro chamar um controle diretamente de um thread que não o criou. O snippet
de código a seguir ilustra uma chamada não segura para o
System.Windows.Forms.TextBox controle. O Button1_Click manipulador de eventos cria
um novo WriteTextUnsafe thread, que define diretamente a propriedade do
TextBox.Text thread principal.

C#

private void button1_Click(object sender, EventArgs e)


{
var thread2 = new System.Threading.Thread(WriteTextUnsafe);
thread2.Start();
}
private void WriteTextUnsafe() =>
textBox1.Text = "This text was set unsafely.";

O depurador do Visual Studio detecta essas chamadas de thread não seguras gerando
uma InvalidOperationException com a mensagem, operação entre threads inválida.
Controle acessado de um thread diferente do thread no qual ele foi criado. O
InvalidOperationException sempre ocorre para chamadas entre threads não seguras
durante a depuração do Visual Studio e pode ocorrer no runtime do aplicativo. Você
deve corrigir o problema, mas pode desabilitar a exceção definindo a
Control.CheckForIllegalCrossThreadCalls propriedade como false .

Chamadas entre threads seguras


Os exemplos de código a seguir demonstram duas maneiras de chamar com segurança
um controle Windows Forms de um thread que não o criou:

1. O System.Windows.Forms.Control.Invoke método , que chama um delegado do


thread principal para chamar o controle.
2. Um System.ComponentModel.BackgroundWorker componente, que oferece um
modelo controlado por eventos.

Em ambos os exemplos, o thread em segundo plano dorme por um segundo para


simular o trabalho que está sendo feito nesse thread.

Exemplo: usar o método Invoke


O exemplo a seguir demonstra um padrão para garantir chamadas thread-safe para um
controle Windows Forms. Ele consulta a System.Windows.Forms.Control.InvokeRequired
propriedade , que compara a criação da ID do thread do controle com a ID do thread de
chamada. Se eles forem diferentes, você deverá chamar o Control.Invoke método .

O WriteTextSafe permite definir a TextBox propriedade do Text controle como um novo


valor. O método consulta InvokeRequired. Se InvokeRequired retornar true ,
WriteTextSafe chama-se recursivamente, passando o método como um delegado para

o Invoke método . Se InvokeRequired retornar false , WriteTextSafe definirá o


TextBox.Text diretamente. O Button1_Click manipulador de eventos cria o novo thread
e executa o WriteTextSafe método .

C#
private void button1_Click(object sender, EventArgs e)
{
var threadParameters = new System.Threading.ThreadStart(delegate {
WriteTextSafe("This text was set safely."); });
var thread2 = new System.Threading.Thread(threadParameters);
thread2.Start();
}

public void WriteTextSafe(string text)


{
if (textBox1.InvokeRequired)
{
// Call this same method but append THREAD2 to the text
Action safeWrite = delegate { WriteTextSafe($"{text} (THREAD2)"); };
textBox1.Invoke(safeWrite);
}
else
textBox1.Text = text;
}

Exemplo: usar um BackgroundWorker


Uma maneira fácil de implementar o multithreading é com o
System.ComponentModel.BackgroundWorker componente , que usa um modelo
controlado por eventos. O thread em segundo plano gera o BackgroundWorker.DoWork
evento, que não interage com o thread principal. O thread principal executa os
BackgroundWorker.ProgressChanged manipuladores de eventos e
BackgroundWorker.RunWorkerCompleted , que podem chamar os controles do thread
principal.

Para fazer uma chamada thread-safe usando BackgroundWorker, manipule o DoWork


evento. Há dois eventos que o trabalho em segundo plano usa para relatar o status:
ProgressChanged e RunWorkerCompleted. O ProgressChanged evento é usado para
comunicar atualizações de status para o thread principal e o RunWorkerCompleted evento
é usado para sinalizar que o trabalho em segundo plano concluiu seu trabalho. Para
iniciar o thread em segundo plano, chame BackgroundWorker.RunWorkerAsync.

O exemplo conta de 0 a 10 no DoWork evento, pausando por um segundo entre


contagens. Ele usa o ProgressChanged manipulador de eventos para relatar o número
de volta ao thread principal e definir a TextBox propriedade do Text controle. Para que o
ProgressChanged evento funcione, a BackgroundWorker.WorkerReportsProgress
propriedade deve ser definida como true .

C#
private void button1_Click(object sender, EventArgs e)
{
if (!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)


{
int counter = 0;
int max = 10;

while (counter <= max)


{
backgroundWorker1.ReportProgress(0, counter.ToString());
System.Threading.Thread.Sleep(1000);
counter++;
}
}

private void backgroundWorker1_ProgressChanged(object sender,


ProgressChangedEventArgs e) =>
textBox1.Text = (string)e.UserState;
Visão geral do uso do teclado (Windows
Forms .NET)
Artigo • 15/02/2023 • 7 minutos para o fim da leitura

Em Windows Forms, a entrada do usuário é enviada para aplicativos na forma de


mensagens do Windows. Uma série de métodos substituíveis processam essas
mensagens no nível do aplicativo, formulário e controle. Quando esses métodos
recebem mensagens de teclado, eles geram eventos que podem ser manipulados para
obter informações sobre a entrada do teclado. Em muitos casos, os aplicativos do
Windows Forms serão capazes de processar todas as entradas do usuário simplesmente
manipulando esses eventos. Em outros casos, um aplicativo pode precisar substituir um
dos métodos que processam mensagens para interceptar uma mensagem específica
antes de ela ser recebida pelo aplicativo, formulário ou controle.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Eventos de teclado
Todos os controles do Windows Forms herdam um conjunto de eventos relacionados às
entradas de mouse e teclado. Por exemplo, um controle pode manipular o KeyPress
evento para determinar o código de caractere de uma tecla que foi pressionada. Para
obter mais informações, consulte Usando eventos de teclado.

Métodos que processam mensagens de


entrada do usuário
Formulários e controles têm acesso à IMessageFilter interface e a um conjunto de
métodos substituíveis que processam mensagens do Windows em diferentes pontos na
fila de mensagens. Todos esses métodos têm um Message parâmetro , que encapsula os
detalhes de baixo nível das mensagens do Windows. É possível implementar ou
substituir esses métodos para analisar a mensagem e, então, consumi-la ou passá-la
para o próximo consumidor na fila de mensagens. A tabela a seguir apresenta os
métodos que processam todas as mensagens do Windows no Windows Forms.
Método Observações

PreFilterMessage Este método intercepta mensagens do Windows que estão na fila (também
chamadas de postadas) no nível do aplicativo.

PreProcessMessage Este método intercepta as mensagens do Windows no nível do formulário e


do controle antes que elas sejam processadas.

WndProc Este método processa mensagens do Windows no nível do formulário e do


controle.

DefWndProc Esse método realiza o processamento padrão de mensagens do Windows


no nível do formulário e do controle. Isso fornece a funcionalidade mínima
de uma janela.

OnNotifyMessage Este método intercepta as mensagens do Windows no nível do formulário e


do controle após o seu processamento. O EnableNotifyMessage bit de
estilo deve ser definido para que esse método seja chamado.

Mensagens de teclado e mouse também são processadas por um conjunto adicional de


métodos substituíveis específicos para esses tipos de mensagens. Para obter mais
informações, consulte a seção Chaves de pré-processamento . .

Tipos de chaves
Windows Forms identifica a entrada do teclado como códigos de tecla virtual
representados pela enumeração bit a bitKeys. Com a Keys enumeração , você pode
combinar uma série de teclas pressionadas para resultar em um único valor. Esses
valores correspondem aos valores que acompanham o WM_KEYDOWN e
WM_SYSKEYDOWN mensagens do Windows. Você pode detectar a maioria das teclas
físicas pressionando os KeyDown eventos ou KeyUp . As teclas de caractere são um
subconjunto da Keys enumeração e correspondem aos valores que acompanham o
WM_CHAR e WM_SYSCHAR mensagens do Windows. Se a combinação de teclas
pressionadas resultar em um caractere, você poderá detectar o caractere manipulando o
KeyPress evento.

Ordem dos eventos de teclado


Conforme listado anteriormente, existem três eventos relacionados que podem ocorrer
em um controle. A sequência a seguir mostra a ordem geral dos eventos:

1. O usuário envia por push a chave "a", a chave é pré-processada, expedida e ocorre
um KeyDown evento.
2. O usuário mantém a chave "a", a chave é pré-processada, expedida e ocorre um
KeyPress evento. Esse evento ocorre várias vezes enquanto o usuário pressiona
uma tecla.
3. O usuário libera a chave "a", a chave é pré-processada, expedida e ocorre um
KeyUp evento.

Chaves de pré-processamento
Assim como outras mensagens, as mensagens de teclado são processadas no WndProc
método de um formulário ou controle. No entanto, antes que as mensagens de teclado
sejam processadas, o PreProcessMessage método chama um ou mais métodos que
podem ser substituídos para lidar com teclas de caracteres especiais e teclas físicas.
Você pode substituir esses métodos para detectar e filtrar certas teclas antes que as
mensagens sejam processadas pelo controle. A tabela a seguir mostra a ação que está
sendo executada e o método relacionado que ocorre, na ordem em que o método
ocorre.

Pré-processamento de um evento KeyDown

Ação Método Observações


relacionado

Verifique se há uma ProcessCmdKey Este método processa uma chave de comando, que
chave de comando tem precedência sobre teclas regulares. Se esse
como um acelerador método retornar true , a mensagem principal não
ou um atalho de menu. será enviada e um evento de tecla não ocorrerá. Se
retornar false , IsInputKey será chamado .

Verifique se há uma IsInputKey Se o método retornar true , isso significa que o


chave especial que controle é um caractere regular e um KeyDown
exija pré- evento é gerado. Se false , ProcessDialogKey será
processamento ou chamado. Nota: Para garantir que um controle
uma chave de obtenha uma chave ou combinação de teclas, você
caractere normal que pode manipular o PreviewKeyDown evento e o
deve gerar um PreviewKeyDownEventArgs conjunto IsInputKey do
KeyDown evento e ser como true para a chave ou as chaves desejadas.
expedida para um
controle.
Ação Método Observações
relacionado

Verifique se há uma ProcessDialogKey Este método processa uma tecla física que utiliza
tecla de navegação uma funcionalidade especial dentro do controle,
(teclas ESC, TAB, Enter como alternar o foco entre o controle e seu pai. Se
ou teclas de seta). o controle imediato não manipular a chave, o
ProcessDialogKey será chamado no controle pai e
assim por diante para o controle superior na
hierarquia. Se esse método retornar true , o pré-
processamento estará completo e um evento de
tecla não será gerado. Se ele retornar false ,
ocorrerá um KeyDown evento .

Pré-processamento para um evento KeyPress

Ação Método Observações


relacionado

Verifique se a IsInputChar Se o caractere for um caractere normal, esse método


chave é um retornará true , o KeyPress evento será gerado e
caractere normal nenhum pré-processamento adicional ocorrerá. Caso
que deve ser contrário ProcessDialogChar , será chamado.
processado pelo
controle

Verifique se o ProcessDialogChar Esse método, semelhante a ProcessDialogKey, será


caractere é chamado de hierarquia de controle. Se o controle for
mnemônico um controle de contêiner, ele verificará se há
(como &OK em mnemônicos chamando ProcessMnemonic em si
um botão) mesmo e seus controles filho. Se ProcessDialogChar
retornar true , um KeyPress evento não ocorrerá.

Processando mensagens de teclado


Depois que as mensagens de teclado atingem o WndProc método de um formulário ou
controle, elas são processadas por um conjunto de métodos que podem ser
substituídos. Cada um desses métodos retorna um Boolean valor que especifica se a
mensagem de teclado foi processada e consumida pelo controle. Se um dos métodos
retornar true , então a mensagem será considerada tratada e ela não será passada para
a base ou pai do controle para processamento adicional. Caso contrário, a mensagem
permanecerá na fila e poderá ser processada em outro método da base ou pai do
controle. A tabela a seguir apresenta os métodos que processam mensagens do teclado.
Método Observações

ProcessKeyMessage Esse método processa todas as mensagens de teclado recebidas pelo


WndProc método do controle .

ProcessKeyPreview Esse método envia a mensagem do teclado para o pai do controle. Se


ProcessKeyPreview retornar true , nenhum evento de chave será gerado;
caso contrário ProcessKeyEventArgs , será chamado.

ProcessKeyEventArgs Esse método gera os KeyDowneventos , KeyPresse KeyUp , conforme


apropriado.

Substituindo métodos de teclado


Há vários métodos disponíveis para substituição quando uma mensagem do teclado é
pré-processada e processada. No entanto, alguns métodos são opções muito melhores
do que outros. A tabela a seguir mostra tarefas que você talvez queira realizar e a
melhor maneira de substituir os métodos do teclado. Para obter mais informações sobre
como substituir métodos, consulte Herança (Guia de Programação em C#) ou Herança
(Visual Basic)

Tarefa Método

Intercepte uma chave de navegação e gere um Substitua IsInputKey. Nota: Como alternativa,
KeyDown evento. Por exemplo, você deseja que você pode manipular o PreviewKeyDown
as teclas TAB e Enter sejam identificadas em uma evento e definir IsInputKey o
caixa de texto. PreviewKeyDownEventArgs como true para a
chave ou as chaves desejadas.

Execute tratamento de navegação ou entrada Substituir ProcessDialogKey


especial em um controle. Por exemplo, você
deseja usar as teclas de seta no controle de lista
para alterar o item selecionado.

Intercepte uma chave de navegação e gere um Substitua IsInputChar.


KeyPress evento. Por exemplo, em um controle
de caixa de rotação você deseja o
pressionamento de várias teclas de seta para
acelerar a progressão pelos itens.

Execute uma manipulação especial de entrada ou Substituir ProcessDialogChar


navegação durante um KeyPress evento. Por
exemplo, em uma controle de lista, manter
pressionada a tecla "r" ignora os itens que
começam com a letra r.
Tarefa Método

Execute o tratamento mnemônico personalizado. Substitua ProcessMnemonic.


Por exemplo, você deseja manipular
mnemônicos em botões desenhados pelo
proprietário contidos em uma barra de
ferramentas.

Confira também
Keys
WndProc
PreProcessMessage
Usando eventos de teclado (Windows Forms .NET)
Como modificar eventos de tecla de teclado (Windows Forms .NET)
Como verificar se há pressionamentos de tecla modificadora (Windows Forms
.NET)
Como simular eventos de teclado (Windows Forms .NET)
Como manipular mensagens de entrada de teclado no formulário (Windows Forms
.NET)
Adicionar um controle (Windows Forms .NET)
Usando eventos de teclado (Windows
Forms .NET)
Artigo • 15/02/2023 • 2 minutos para o fim da leitura

A maioria dos programas do Windows Forms processa a entrada do teclado tratando


eventos de teclado. Este artigo fornece uma visão geral dos eventos de teclado,
incluindo detalhes sobre quando usar cada evento e os dados fornecidos para cada
evento. Para obter mais informações sobre eventos em geral, consulte Visão geral de
eventos (Windows Forms .NET).

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Eventos de teclado
O Windows Forms fornece dois eventos que ocorrem quando um usuário pressiona
uma tecla do teclado e um evento quando um usuário libera uma tecla do teclado:

O KeyDown evento ocorre uma vez.


O KeyPress evento , que pode ocorrer várias vezes quando um usuário mantém a
mesma chave pressionada.
O KeyUp evento ocorre uma vez quando um usuário libera uma chave.

Quando um usuário pressiona uma tecla, o Windows Forms determina qual evento deve
ser gerado com base em se a mensagem do teclado especifica uma tecla de caractere
ou uma tecla física. Para obter mais informações sobre teclas físicas e de caracteres,
consulte Visão geral do teclado, eventos de teclado.

A tabela a seguir descreve os três eventos de teclado.

Evento Descrição Resultados


de
teclado
Evento Descrição Resultados
de
teclado

KeyDown Esse evento é gerado quando um O manipulador para KeyDown


usuário pressiona uma tecla física. recebimentos:

Um KeyEventArgs parâmetro , que


fornece a KeyCode propriedade (que
especifica um botão de teclado
físico).
A Modifiers propriedade (SHIFT,
CTRL ou ALT).
A KeyData propriedade (que
combina o código de chave e o
modificador). O KeyEventArgs
parâmetro também fornece:

A Handled propriedade , que


pode ser definida para impedir
que o controle subjacente receba
a chave.
A SuppressKeyPress propriedade
, que pode ser usada para
suprimir os KeyPress eventos e
KeyUp para esse pressionamento
de tecla.
Evento Descrição Resultados
de
teclado

KeyPress Esse evento é gerado quando as teclas KeyPress é gerado após KeyDown.
são pressionadas resultam em um
caractere. Por exemplo, um usuário
pressiona as teclas SHIFT e a letra “a” O manipulador para KeyPress
minúscula, o que resulta em uma letra recebimentos:
“A” maiúscula. Um KeyPressEventArgs parâmetro ,
que contém o código de caractere
da tecla que foi pressionada. Esse
código de caractere é exclusivo para
cada combinação de uma tecla de
caractere e tecla modificadora.

Por exemplo, a tecla “A” gerará:

O código de caractere 65, se ela


estiver pressionada com a tecla
SHIFT
Ou a tecla CAPS LOCK, 97 se ela
for pressionada sozinha,
E 1 se ela estiver pressionada
com a tecla CTRL.

KeyUp Esse evento é gerado quando um O manipulador para KeyUp recebimentos:


usuário libera uma tecla física.

Um KeyEventArgs parâmetro:

Que fornece a KeyCode


propriedade (que especifica um
botão de teclado físico).
A Modifiers propriedade (SHIFT,
CTRL ou ALT).
A KeyData propriedade (que
combina o código de chave e o
modificador).

Confira também
Visão geral do uso do teclado (Windows Forms .NET)
Como modificar eventos de tecla de teclado (Windows Forms .NET)
Como verificar se há pressionamentos de tecla modificadora (Windows Forms
.NET)
Como simular eventos de teclado (Windows Forms .NET)
Como manipular mensagens de entrada de teclado no formulário (Windows Forms
.NET)
Visão geral de como validar a entrada
do usuário (Windows Forms .NET)
Artigo • 10/02/2023 • 6 minutos para o fim da leitura

Quando os usuários inserem dados em seu aplicativo, convém verificar se os dados são
válidos antes de seu aplicativo utilizá-los. Você pode exigir que determinados campos
de texto não sejam de comprimento zero, que um campo formatado como um número
de telefone ou que uma cadeia de caracteres não contenha caracteres inválidos. O
Windows Forms fornece várias maneiras para validar a entrada em seu aplicativo.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Controle MaskedTextBox
Se você precisar exigir que os usuários insiram dados em um formato bem definido,
como um número de telefone ou um número de parte, você pode fazer isso
rapidamente e com o mínimo de código usando o MaskedTextBox controle . Uma
máscara é uma cadeia de caracteres composta de caracteres de uma linguagem de
mascaramento que especifica quais caracteres podem ser inseridos em qualquer
posição determinada de uma caixa de texto. O controle exibe um conjunto de avisos
para o usuário. Se o usuário digita uma entrada incorreta, como digitar uma letra
quando é necessário um dígito, o controle rejeitará automaticamente a entrada.

A linguagem de mascaramento usada por MaskedTextBox é flexível. Ela permite que


você especifique os caracteres exigidos, caracteres opcionais, caracteres literais como
hifens e parênteses, caracteres de moeda e separadores de data. O controle também
funciona bem quando associado a uma fonte de dados. O Format evento em uma
associação de dados pode ser usado para reformatar dados de entrada para cumprir a
máscara e o Parse evento pode ser usado para reformatar dados de saída para atender
às especificações do campo de dados.

Validação controlada por eventos


Se você quiser ter controle programático completo sobre a validação ou precisar de
verificações de validação complexas, deverá usar os eventos de validação integrados à
maioria dos controles Windows Forms. Cada controle que aceita entrada de usuário de
forma livre tem um Validating evento que ocorrerá sempre que o controle exigir
validação de dados. Validating No método de manipulação de eventos, você pode
validar a entrada do usuário de várias maneiras. Por exemplo, se você tiver uma caixa de
texto que deve conter um código postal, poderá fazer a validação das seguintes
maneiras:

Se o código postal precisar pertencer a um grupo específico de cep, você poderá


fazer uma comparação de cadeia de caracteres na entrada para validar os dados
inseridos pelo usuário. Por exemplo, se o código postal precisar estar no conjunto
{10001, 10002, 10003} , você poderá usar uma comparação de cadeia de

caracteres para validar os dados.

Se o código postal precisar estar em um formulário específico, você poderá usar


expressões regulares para validar os dados inseridos pelo usuário. Por exemplo,
para validar a forma ##### ou #####-#### , você pode usar a expressão regular
^(\d{5})(-\d{4})?$ . Para validar a forma A#A #A# , você pode usar a expressão

regular [A-Z]\d[A-Z] \d[A-Z]\d . Para obter mais informações sobre expressões


regulares, consulte Expressões regulares do .NET e exemplos de expressões
regulares.

Se o código postal deve ser um CEP válido dos Estados Unidos, você poderia
chamar um serviço Web de código postal para validar os dados inseridos pelo
usuário.

O Validating evento é fornecido um objeto do tipo CancelEventArgs. Se você determinar


que os dados do controle não são válidos, cancele o Validating evento definindo a
propriedade desse Cancel objeto como true . Se você não definir a Cancel propriedade,
Windows Forms assumirá que a validação foi bem-sucedida para esse controle e gerará
o Validated evento.

Para obter um exemplo de código que valida um endereço de email em um TextBox,


consulte a referência de Validating evento.

Controles associados a dados de validação controlada por


eventos
A validação é útil quando você associa seus controles a uma fonte de dados, como uma
tabela de banco de dados. Usando a validação, você pode garantir que os dados do
controle satisfaçam o formato exigido pela fonte de dados e que ele não contenha
caracteres especiais, como aspas e barras traseiras que podem não ser seguras.
Quando você usa a associação de dados, os dados em seu controle são sincronizados
com a fonte de dados durante a execução do Validating evento. Se você cancelar o
Validating evento, os dados não serão sincronizados com a fonte de dados.

) Importante

Se você tiver uma validação personalizada que ocorre após o Validating evento, ela
não afetará a associação de dados. Por exemplo, se você tiver código em um
Validated evento que tente cancelar a associação de dados, a associação de dados
ainda ocorrerá. Nesse caso, para executar a Validated validação no evento, altere a
propriedade do Binding.DataSourceUpdateMode controle de
DataSourceUpdateMode.OnValidation para DataSourceUpdateMode.Nevere
adicione your-control.DataBindings["field-name"].WriteValue() ao código de
validação.

Validação implícita e explícita


Então quando os dados de um controle são validados? Isso cabe a você, o
desenvolvedor. Você pode usar a validação implícita ou explícita, dependendo das
necessidades do seu aplicativo.

Validação implícita
A abordagem de validação implícita valida os dados enquanto o usuário os digita.
Valide os dados lendo as teclas conforme elas são pressionadas ou mais comumente
sempre que o usuário tira o foco de entrada do controle. Essa abordagem é útil quando
você deseja fornecer ao usuário comentários imediatos sobre os dados enquanto eles
estão funcionando.

Se você quiser usar a validação implícita para um controle, deverá definir a propriedade
desse AutoValidate controle como EnablePreventFocusChange ou
EnableAllowFocusChange. Se você cancelar o Validating evento, o comportamento do
controle será determinado pelo valor atribuído a AutoValidate. Se você atribuiu
EnablePreventFocusChange, cancelar o evento fará com que o Validated evento não
ocorra. O foco de entrada permanecerá no controle atual até que o usuário altere os
dados para um formato válido. Se você atribuiu EnableAllowFocusChange, o Validated
evento não ocorrerá quando você cancelar o evento, mas o foco ainda será alterado
para o próximo controle.
Atribuir Disable à AutoValidate propriedade impede completamente a validação
implícita. Para validar seus controles, você precisará usar a validação explícita.

Validação explícita
A abordagem de validação explícita valida os dados de uma só vez. Você pode validar
os dados em resposta a uma ação do usuário, como clicar em um botão Salvar ou em
um link Avançar . Quando a ação do usuário ocorre, você pode disparar a validação
explícita de uma das seguintes maneiras:

Chame Validate para validar o último controle que perdeu o foco.


Chame ValidateChildren para validar todos os controles filho em um formulário ou
controle de contêiner.
Chamar um método personalizado para validar manualmente os dados nos
controles.

Comportamento de validação implícita padrão para


controles
Controles de Windows Forms diferentes têm padrões diferentes para sua AutoValidate
propriedade. A tabela a seguir mostra os controles mais comuns e seus valores padrão.

Control Comportamento de validação padrão

ContainerControl Inherit

Form EnableAllowFocusChange

PropertyGrid Propriedade não exposta no Visual Studio

ToolStripContainer Propriedade não exposta no Visual Studio

SplitContainer Inherit

UserControl EnableAllowFocusChange

Fechando o formulário e substituindo


Validação
Quando um controle mantém o foco porque os dados que ele contém são inválidos, é
impossível fechar o formulário pai de uma das maneiras usuais:

Clicando no botão Fechar.


Selecionando o menu Fechar Sistema>.
Chamando o Close método programaticamente.

No entanto, em alguns casos, você talvez queira permitir que o usuário feche o
formulário independentemente se os valores nos controles são válidos. Você pode
substituir a validação e fechar um formulário que ainda contém dados inválidos criando
um manipulador para o evento do FormClosing formulário. No evento, defina a Cancel
propriedade como false . Isso força o formulário a fechar. Para obter mais informações
e um exemplo, consulte Form.FormClosing.

7 Observação

Se você forçar o formulário a fechar desta maneira, todos os dados nos controles
do formulário que ainda não tiverem sido salvos serão perdidos. Além disso, os
formulários modais não validam o conteúdo dos controles quando são fechados.
Você ainda pode usar a validação de controle para bloquear o foco em um
controle, mas não precisa se preocupar com o comportamento associado ao
fechamento do formulário.

Confira também
Usando eventos de teclado (Windows Forms .NET)
Control.Validating
Form.FormClosing
System.Windows.Forms.FormClosingEventArgs
Como modificar eventos de tecla de
teclado (Windows Forms .NET)
Artigo • 09/02/2023 • 3 minutos para o fim da leitura

O Windows Forms fornece a capacidade de consumir e modificar as entradas do


teclado. Consumir uma chave refere-se ao tratamento de uma chave dentro de um
método ou manipulador de eventos para que outros métodos e eventos mais abaixo da
fila de mensagens não recebam o valor da chave. Além disso, modificar uma chave
refere-se à modificação do valor de uma chave para que métodos e manipuladores de
eventos mais abaixo na fila de mensagens recebam um valor de chave diferente. Este
artigo mostra como realizar essas tarefas.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Consumir uma chave


Em um KeyPress manipulador de eventos, defina a Handled propriedade da
KeyPressEventArgs classe como true .

-ou-

Em um KeyDown manipulador de eventos, defina a Handled propriedade da


KeyEventArgs classe como true .

7 Observação

Definir a Handled propriedade no KeyDown manipulador de eventos não impede


que os KeyPress eventos e KeyUp sejam gerados para o pressionamento de tecla
atual. Use a SuppressKeyPress propriedade para essa finalidade.

O exemplo a seguir manipula o KeyPress evento para consumir as A teclas de caractere


e a . Essas chaves não podem ser digitada na caixa de texto:

C#
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 'a' || e.KeyChar == 'A')
e.Handled = true;
}

Modificar uma chave de caractere padrão


Em um KeyPress manipulador de eventos, defina a KeyChar propriedade da
KeyPressEventArgs classe como o valor da nova chave de caractere.

O exemplo a seguir manipula o KeyPress evento para alterar as teclas de A caractere e


a para ! :

C#

private void textBox2_KeyPress(object sender, KeyPressEventArgs e)


{
if (e.KeyChar == 'a' || e.KeyChar == 'A')
{
e.KeyChar = '!';
e.Handled = false;
}
}

Modificar uma chave que não é de caracteres


Você só pode modificar pressionamentos de teclas que não são caracteres herdando do
controle e substituindo o PreProcessMessage método . À medida que a entrada
Message é enviada para o controle, ela é processada antes do controle gerar eventos.
Você pode interceptar essas mensagens para modificá-las ou bloqueá-las.

O exemplo de código a seguir demonstra como usar a WParam propriedade do


Message parâmetro para alterar a tecla pressionada. Esse código detecta uma chave de
F1 a F10 e converte a chave em uma chave numérica que varia de 0 a 9 (em que
F10 é mapeado para 0 ).

C#

public override bool PreProcessMessage(ref Message m)


{
const int WM_KEYDOWN = 0x100;

if (m.Msg == WM_KEYDOWN)
{
Keys keyCode = (Keys)m.WParam & Keys.KeyCode;

// Detect F1 through F9.


m.WParam = keyCode switch
{
Keys.F1 => (IntPtr)Keys.D1,
Keys.F2 => (IntPtr)Keys.D2,
Keys.F3 => (IntPtr)Keys.D3,
Keys.F4 => (IntPtr)Keys.D4,
Keys.F5 => (IntPtr)Keys.D5,
Keys.F6 => (IntPtr)Keys.D6,
Keys.F7 => (IntPtr)Keys.D7,
Keys.F8 => (IntPtr)Keys.D8,
Keys.F9 => (IntPtr)Keys.D9,
Keys.F10 => (IntPtr)Keys.D0,
_ => m.WParam
};
}

// Send all other messages to the base method.


return base.PreProcessMessage(ref m);
}

Confira também
Visão geral do uso do teclado (Windows Forms .NET)
Usando eventos de teclado (Windows Forms .NET)
Keys
KeyDown
KeyPress
Como verificar se há pressionamentos
de tecla modificador (Windows Forms
.NET)
Artigo • 15/02/2023 • 2 minutos para o fim da leitura

À medida que o usuário digita chaves em seu aplicativo, você pode monitorar as teclas
modificadoras pressionadas, como SHIFT , ALT e CTRL . Quando uma tecla modificadora
é pressionada em combinação com outras teclas ou até mesmo um clique do mouse,
seu aplicativo pode responder adequadamente. Por exemplo, pressionar a tecla S pode
fazer com que um "s" apareça na tela. Se as teclas CTRL+S forem pressionadas, o
documento atual poderá ser salvo.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Se você manipular o KeyDown evento, a KeyEventArgs.Modifiers propriedade recebida


pelo manipulador de eventos especifica quais teclas modificadoras serão pressionadas.
Além disso, a KeyEventArgs.KeyData propriedade especifica o caractere que foi
pressionado junto com as teclas modificadoras combinadas com um OR bit a bit.

Se você estiver tratando o KeyPress evento ou um evento do mouse, o manipulador de


eventos não receberá essas informações. Use a ModifierKeys propriedade da Control
classe para detectar um modificador de chave. Em ambos os casos, você deve executar
um AND bit a bit do valor apropriado Keys e o valor que está testando. A Keys
enumeração oferece variações de cada chave modificadora, portanto, é importante que
você faça a verificação AND bit a bit com o valor correto.

Por exemplo, a chave SHIFT é representada pelos seguintes valores de chave:

Keys.Shift
Keys.ShiftKey
Keys.RShiftKey
Keys.LShiftKey

O valor correto para testar SHIFT como uma chave modificadora é Keys.Shift. Da mesma
forma, para testar CTRL e ALT como modificadores, você deve usar os Keys.Control
valores e Keys.Alt , respectivamente.
Detectar chave modificadora
Detecte se uma tecla modificadora é pressionada comparando a ModifierKeys
propriedade e o valor de Keys enumeração com um operador AND bit a bit.

O exemplo de código a seguir mostra como determinar se a tecla SHIFT é pressionada


dentro dos KeyPress manipuladores de eventos e KeyDown .

C#

// Event only raised when non-modifier key is pressed


private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
MessageBox.Show("KeyPress " + Keys.Shift);
}

// Event raised as soon as shift is pressed


private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if ((Control.ModifierKeys & Keys.Shift) == Keys.Shift)
MessageBox.Show("KeyDown " + Keys.Shift);
}

Confira também
Visão geral do uso do teclado (Windows Forms .NET)
Usando eventos de teclado (Windows Forms .NET)
Keys
ModifierKeys
KeyDown
KeyPress
Como manipular mensagens de entrada
de teclado no formulário (Windows
Forms .NET)
Artigo • 15/02/2023 • 2 minutos para o fim da leitura

Os Windows Forms proporcionam a capacidade de manipular mensagens de teclado no


nível do formulário, antes que as mensagens cheguem a um controle. Este artigo mostra
como realizar essa tarefa.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Manipular uma mensagem de teclado


Manipule o KeyPress evento ou KeyDown do formulário ativo e defina a KeyPreview
propriedade do formulário como true . Essa propriedade faz com que o teclado seja
recebido pelo formulário antes de alcançar qualquer controle no formulário. O exemplo
de código a seguir manipula o KeyPress evento detectando todas as chaves numéricas e
consumindo 1 , 4 e 7 .

C#

// Detect all numeric characters at the form level and consume 1,4, and 7.
// Form.KeyPreview must be set to true for this event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar >= 48 && e.KeyChar <= 57)
{
MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.");

switch (e.KeyChar)
{
case (char)49:
case (char)52:
case (char)55:
MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.");
e.Handled = true;
break;
}
}
}

Confira também
Visão geral do uso do teclado (Windows Forms .NET)
Usando eventos de teclado (Windows Forms .NET)
Keys
ModifierKeys
KeyDown
KeyPress
Como simular eventos de teclado
(Windows Forms .NET)
Artigo • 10/02/2023 • 3 minutos para o fim da leitura

Windows Forms fornece algumas opções para simular programaticamente a entrada do


teclado. Este artigo fornece uma visão geral dessas opções.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Usar SendKeys
Windows Forms fornece a System.Windows.Forms.SendKeys classe para enviar
pressionamentos de tecla para o aplicativo ativo. Há dois métodos para enviar
pressionamentos de tecla para um aplicativo: SendKeys.Send e SendKeys.SendWait. A
diferença entre os dois métodos é que SendWait bloqueia o thread atual quando o
pressionamento de tecla é enviado, aguardando uma resposta, enquanto Send não o
faz. Para obter mais informações sobre SendWait , consulte Para enviar um
pressionamento de tecla para um aplicativo diferente.

U Cuidado

Se seu aplicativo for destinado ao uso internacional com uma variedade de


teclados, o uso de SendKeys.Send poderá produzir resultados imprevisíveis e deve
ser evitado.

Nos bastidores, SendKeys o usa uma implementação mais antiga do Windows para
enviar entradas, o que pode falhar no Windows moderno em que se espera que o
aplicativo não esteja em execução com direitos administrativos. Se a implementação
mais antiga falhar, o código tentará automaticamente a implementação mais recente do
Windows para enviar entrada. Além disso, quando a SendKeys classe usa a nova
implementação, o SendWait método não bloqueia mais o thread atual ao enviar
pressionamentos de tecla para outro aplicativo.

) Importante
Se o aplicativo depender de um comportamento consistente, independentemente
do sistema operacional, você poderá forçar a SendKeys classe a usar a nova
implementação adicionando a seguinte configuração de aplicativo ao arquivo
app.config.

XML

<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>

Para forçar a SendKeys classe a usar apenas a implementação anterior, use o valor
"JournalHook" em vez disso.

Para enviar um pressionamento de tecla para o mesmo


aplicativo
Chame o SendKeys.Send método ou SendKeys.SendWait da SendKeys classe . Os
pressionamentos de teclas especificados serão recebidos pelo controle ativo do
aplicativo.

O exemplo de código a seguir usa para simular pressionar as teclas Send ALT e DOWN

juntas. Esses pressionamentos de tecla fazem com que o ComboBox controle exiba sua
lista suspensa. Este exemplo pressupõe um Form com um Button e ComboBox.

C#

private void button1_Click(object sender, EventArgs e)


{
comboBox1.Focus();
SendKeys.Send("%+{DOWN}");
}

Para enviar um pressionamento de tecla para um


aplicativo diferente
Os SendKeys.Send métodos e SendKeys.SendWait enviam pressionamentos de tecla
para o aplicativo ativo, que geralmente é o aplicativo do qual você está enviando
pressionamentos de tecla. Para enviar pressionamentos de tecla para outro aplicativo,
primeiro você precisa ativá-lo. Como não há nenhum método gerenciado para ativar
outro aplicativo, você deve usar métodos nativos do Windows para concentrar o outro
aplicativo. O exemplo de código a seguir usa a invocação de plataforma para chamar os
FindWindow métodos e SetForegroundWindow para ativar a janela do aplicativo

Calculadora e, em seguida, chama Send para emitir uma série de cálculos para o
aplicativo Calculadora.

O exemplo de código a seguir usa para simular teclas Send de pressionamento no


aplicativo calculadora de Windows 10. Ele primeiro pesquisa uma janela de aplicativo
com o título de Calculator e, em seguida, a ativa. Depois de ativados, os
pressionamentos de tecla são enviados para calcular 10 mais 10.

C#

[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]


public static extern IntPtr FindWindow(string lpClassName, string
lpWindowName);

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);

private void button1_Click(object sender, EventArgs e)


{
IntPtr calcWindow = FindWindow(null, "Calculator");

if (SetForegroundWindow(calcWindow))
SendKeys.Send("10{+}10=");
}

Usar métodos OnEventName


A maneira mais fácil de simular eventos de teclado é chamar um método no objeto que
aciona o evento. A maioria dos eventos tem um método correspondente que os invoca,
nomeado no padrão de On seguido por EventName , como OnKeyPress . Essa opção só é
possível em formulários ou controles personalizados, pois esses métodos são
protegidos e não podem ser acessados de fora do contexto do controle ou formulário.

Esses métodos protegidos estão disponíveis para simular eventos de teclado.

OnKeyDown

OnKeyPress
OnKeyUp

Para obter mais informações sobre esses eventos, consulte Usando eventos de teclado
(Windows Forms .NET).

Confira também
Visão geral do uso do teclado (Windows Forms .NET)
Usando eventos de teclado (Windows Forms .NET)
Usando eventos do mouse (Windows Forms .NET)
SendKeys
Keys
KeyDown
KeyPress
Visão geral do uso do mouse (Windows
Forms .NET)
Artigo • 09/02/2023 • 4 minutos para o fim da leitura

Receber e manipular entradas de mouse é uma parte importante qualquer aplicativo do


Windows. Você pode manipular eventos do mouse para executar uma ação em seu
aplicativo ou usar informações de localização do mouse para executar testes de clique
ou outras ações. Além disso, você pode alterar a maneira como os controles em seu
aplicativo lidam com a entrada do mouse. Este artigo descreve esses eventos do mouse
em detalhes e como obter e alterar as configurações do sistema para o mouse.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Em Windows Forms, a entrada do usuário é enviada para aplicativos na forma de


mensagens do Windows. Uma série de métodos substituíveis processam essas
mensagens no nível do aplicativo, formulário e controle. Quando esses métodos
recebem mensagens do mouse, eles geram eventos que podem ser manipulados para
obter informações sobre a entrada do mouse. Em muitos casos, Windows Forms
aplicativos podem processar toda a entrada do usuário simplesmente manipulando
esses eventos. Em outros casos, um aplicativo pode substituir um dos métodos que
processam mensagens para interceptar uma mensagem específica antes de ser recebida
pelo aplicativo, formulário ou controle.

Eventos de mouse
Todos os controles do Windows Forms herdam um conjunto de eventos relacionados às
entradas de mouse e teclado. Por exemplo, um controle pode manipular o MouseClick
evento para determinar o local de um clique do mouse. Para obter mais informações
sobre os eventos do mouse, consulte Usando eventos do mouse.

Localização do mouse e teste de clique


Quando o usuário move o mouse, o sistema operacional move o ponteiro do mouse. O
ponteiro do mouse contém um único pixel, chamado de ponto de acesso, que o sistema
operacional rastreia e reconhece como a posição do ponteiro. Quando o usuário move
o mouse ou pressiona um botão do mouse, o Control que contém o HotSpot aciona o
evento do mouse apropriado.

Você pode obter a posição atual do mouse com a Location propriedade do


MouseEventArgs ao manipular um evento do mouse ou usando a Position propriedade
da Cursor classe . Em seguida, você pode usar informações de localização do mouse
para realizar testes de clique e, em seguida, executar uma ação com base no local do
mouse. A funcionalidade de teste de clique é integrada a vários controles em Windows
Forms como os ListViewcontroles , TreeViewMonthCalendar e DataGridView .

Usado com o evento do mouse apropriado, MouseHover por exemplo, o teste de clique
é muito útil para determinar quando seu aplicativo deve executar uma ação específica.

Alterando as configurações de entrada do


mouse
Você pode detectar e alterar a maneira como um controle manipula a entrada do mouse
derivando do controle e usando os GetStyle métodos e SetStyle . O SetStyle método usa
uma combinação bit a bit de ControlStyles valores para determinar se o controle terá
um clique padrão, um comportamento de clique duplo ou se o controle manipulará seu
próprio processamento do mouse. Além disso, a SystemInformation classe inclui
propriedades que descrevem os recursos do mouse e especificam como o mouse
interage com o sistema operacional. A tabela a seguir resume essas propriedades.

Propriedade Descrição

DoubleClickSize Obtém as dimensões, em pixels, da área em que o usuário deve clicar


duas vezes para que o sistema operacional considere os dois cliques
um clique duplo.

DoubleClickTime Obtém o número máximo de milissegundos que podem decorrer entre


um primeiro clique e um segundo clique para que a ação do mouse
seja considerada um clique duplo.

MouseButtons Obtém o número de botões do mouse.

MouseButtonsSwapped Obtém um valor que indica se as funções dos botões esquerdo e


direito do mouse foram trocadas.

MouseHoverSize Obtém as dimensões, em pixels, do retângulo no qual o ponteiro do


mouse deve permanecer pelo tempo de foco do mouse antes que uma
mensagem de foco do mouse seja gerada.
Propriedade Descrição

MouseHoverTime Obtém o tempo, em milissegundos, que o ponteiro do mouse deve


permanecer no retângulo de foco antes que uma mensagem de foco
do mouse seja gerada.

MousePresent Obtém um valor que indica se um mouse está instalado.

MouseSpeed Obtém um valor que indica a velocidade atual do mouse, de 1 a 20.

MouseWheelPresent Obtém um valor que indica se um mouse com botão de rolagem está
instalado.

MouseWheelScrollDelta Obtém o valor delta do incremento de uma única rotação da roda do


mouse.

MouseWheelScrollLines Obtém o número de linhas a rolar quando o botão de rolagem do


mouse é girado.

Métodos que processam mensagens de


entrada do usuário
Formulários e controles têm acesso à IMessageFilter interface e a um conjunto de
métodos substituíveis que processam mensagens do Windows em diferentes pontos na
fila de mensagens. Todos esses métodos têm um Message parâmetro , que encapsula os
detalhes de baixo nível das mensagens do Windows. É possível implementar ou
substituir esses métodos para analisar a mensagem e, então, consumi-la ou passá-la
para o próximo consumidor na fila de mensagens. A tabela a seguir apresenta os
métodos que processam todas as mensagens do Windows no Windows Forms.

Método Observações

PreFilterMessage Este método intercepta mensagens do Windows que estão na fila (também
chamadas de postadas) no nível do aplicativo.

PreProcessMessage Este método intercepta as mensagens do Windows no nível do formulário e


do controle antes que elas sejam processadas.

WndProc Este método processa mensagens do Windows no nível do formulário e do


controle.

DefWndProc Esse método realiza o processamento padrão de mensagens do Windows


no nível do formulário e do controle. Isso fornece a funcionalidade mínima
de uma janela.
Método Observações

OnNotifyMessage Esse método intercepta as mensagens no nível do formulário e do controle,


depois que elas são processadas. O EnableNotifyMessage bit de estilo deve
ser definido para que esse método seja chamado.

Confira também
Usando eventos do mouse (Windows Forms .NET)
Visão geral do comportamento do mouse de arrastar e soltar (Windows Forms
.NET)
Gerenciar ponteiros do mouse (Windows Forms .NET)
Usando eventos do mouse (Windows
Forms .NET)
Artigo • 10/02/2023 • 6 minutos para o fim da leitura

A maioria dos programas Windows Forms processam a entrada do mouse manipulando


os eventos do mouse. Este artigo fornece uma visão geral dos eventos do mouse,
incluindo detalhes sobre quando usar cada evento e os dados fornecidos para cada
evento. Para obter mais informações sobre eventos em geral, consulte Visão geral de
eventos (Windows Forms .NET).

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Eventos de mouse
A principal maneira de responder a entradas de mouse é manipular eventos de mouse.
A tabela a seguir mostra os eventos do mouse e descreve quando eles são gerados.

Eventos de Descrição
mouse

Click Esse evento ocorre quando o botão do mouse é liberado, normalmente


antes do MouseUp evento. O manipulador para esse evento recebe um
argumento do tipo EventArgs. Manipule este evento quando você só
precisar determinar quando um clique ocorrer.

MouseClick Este evento ocorre quando o usuário clica no controle com o mouse. O
manipulador para esse evento recebe um argumento do tipo
MouseEventArgs. Manipule este evento quando você precisar obter
informações sobre o mouse quando um clique ocorrer.

DoubleClick Este evento ocorre quando um usuário clica duas vezes no controle. O
manipulador para esse evento recebe um argumento do tipo EventArgs.
Manipule este evento quando você só precisar determinar quando um
clique duplo ocorrer.

MouseDoubleClick Este evento ocorre quando o usuário clica duas vezes no controle com o
mouse. O manipulador para esse evento recebe um argumento do tipo
MouseEventArgs. Manipule este evento quando você precisar obter
informações sobre o mouse quando um clique duplo ocorrer.
Eventos de Descrição
mouse

MouseDown Este evento ocorre quando o ponteiro do mouse está sobre o controle e um
botão do mouse é pressionado. O manipulador para esse evento recebe um
argumento do tipo MouseEventArgs.

MouseEnter Este evento ocorre quando o ponteiro do mouse entra na borda ou na área
de cliente do controle, dependendo do tipo de controle. O manipulador
para esse evento recebe um argumento do tipo EventArgs.

MouseHover Este evento ocorre quando o ponteiro do mouse para e permanece sobre o
controle. O manipulador para esse evento recebe um argumento do tipo
EventArgs.

MouseLeave Este evento ocorre quando o ponteiro do mouse deixa a borda ou a área de
cliente do controle, dependendo do tipo de controle. O manipulador para
esse evento recebe um argumento do tipo EventArgs.

MouseMove Este evento ocorre quando o ponteiro do mouse se move enquanto está
sobre um controle. O manipulador para esse evento recebe um argumento
do tipo MouseEventArgs.

MouseUp Este evento ocorre quando o ponteiro do mouse está sobre o controle e o
usuário libera um botão do mouse. O manipulador para esse evento recebe
um argumento do tipo MouseEventArgs.

MouseWheel Este evento ocorre quando o usuário gira o botão de rolagem do mouse
enquanto o controle está em foco. O manipulador para esse evento recebe
um argumento do tipo MouseEventArgs. Você pode usar a Delta
propriedade de MouseEventArgs para determinar até que ponto o mouse
foi rolado.

Informações do mouse
Um MouseEventArgs é enviado para os manipuladores de eventos do mouse
relacionados a clicar em um botão do mouse e acompanhar os movimentos do mouse.
MouseEventArgs fornece informações sobre o estado atual do mouse, incluindo o local
do ponteiro do mouse nas coordenadas do cliente, quais botões do mouse são
pressionados e se a roda do mouse rolou. Vários eventos do mouse, como aqueles que
são gerados quando o ponteiro do mouse inseriu ou saiu dos limites de um controle,
enviam um EventArgs para o manipulador de eventos sem mais informações.

Se você quiser saber o estado atual dos botões do mouse ou o local do ponteiro do
mouse e quiser evitar manipular um evento do mouse, também poderá usar as
MouseButtons propriedades e MousePosition da Control classe . MouseButtons retorna
informações sobre quais botões do mouse estão pressionados no momento. O
MousePosition retorna as coordenadas de tela do ponteiro do mouse e é equivalente ao
valor retornado por Position.

Convertendo entre coordenadas de cliente e da


tela
Como algumas informações de localização do mouse estão em coordenadas de cliente
e algumas estão em coordenadas de tela, talvez seja necessário converter um ponto de
um sistema de coordenadas para outro. Você pode fazer isso facilmente usando os
PointToClient métodos e PointToScreen disponíveis na Control classe .

Comportamento do evento Clique Padrão


Se quiser manipular eventos de clique do mouse na ordem correta, você precisará
conhecer a ordem em que os eventos de clique são gerados em controles dos Windows
Forms. Todos os controles Windows Forms geram eventos de clique na mesma ordem
quando qualquer botão do mouse com suporte é pressionado e liberado, exceto
quando indicado na lista a seguir para controles individuais. A lista a seguir mostra a
ordem dos eventos gerados por um único clique do botão do mouse:

1. MouseDown .
2. Click .
3. MouseClick .
4. MouseUp .

Veja a seguir a ordem dos eventos gerados para um clique duplo no botão do mouse:

1. MouseDown .

2. Click .

3. MouseClick .

4. MouseUp .

5. MouseDown .

6. DoubleClick .

Isso pode variar, dependendo se o controle em questão tem o


StandardDoubleClick bit de estilo definido como true . Para obter mais
informações sobre como definir um ControlStyles bit, consulte o SetStyle método .
7. MouseDoubleClick .

8. MouseUp .

Controles individuais
Os seguintes controles não estão em conformidade com o comportamento de evento
de clique do mouse padrão:

Button

CheckBox

ComboBox

RadioButton

7 Observação

Para o ComboBox controle, o comportamento do evento detalhado


posteriormente ocorrerá se o usuário clicar no campo de edição, no botão ou
em um item dentro da lista.

Clique com o botão esquerdo: Click, MouseClick


Clique com o botão direito do mouse: Nenhum evento de clique gerado
Clique duas vezes à esquerda: Click, MouseClick; Click, MouseClick
Clique duas vezes com o botão direito do mouse: Nenhum evento de clique
gerado

TextBoxControles , RichTextBox, ListBox, MaskedTextBoxe CheckedListBox

7 Observação

O comportamento do evento detalhado a seguir ocorre quando o usuário


clica em qualquer lugar desses controles.

Clique com o botão esquerdo: Click, MouseClick


Clique com o botão direito do mouse: Nenhum evento de clique gerado
Clique duas vezes à esquerda: Click, MouseClick, DoubleClick,
MouseDoubleClick
Clique duas vezes com o botão direito do mouse: Nenhum evento de clique
gerado

Controle ListView
7 Observação

O comportamento do evento detalhado posteriormente ocorre somente


quando o usuário clica nos itens no ListView controle. Nenhum evento é
gerado para cliques em qualquer outro lugar no controle. Além dos eventos
descritos posteriormente, há os BeforeLabelEdit eventos e AfterLabelEdit ,
que podem ser de seu interesse se você quiser usar a validação com o
ListView controle .

Clique com o botão esquerdo: Click, MouseClick


Clique com o botão direito do mouse: Click, MouseClick
Clique duas vezes à esquerda: Click, MouseClick; DoubleClick,
MouseDoubleClick
Clique duas vezes com o botão direito do mouse: Click, MouseClick;
DoubleClick, MouseDoubleClick

Controle TreeView

7 Observação

O comportamento do evento detalhado posteriormente ocorre somente


quando o usuário clica nos próprios itens ou à direita dos itens no TreeView
controle. Nenhum evento é gerado para cliques em qualquer outro lugar no
controle. Além dos descritos posteriormente, há os BeforeCheckeventos ,
BeforeSelect, BeforeLabelEdit, AfterSelect, AfterChecke AfterLabelEdit , que
podem ser de seu interesse se você quiser usar a validação com o TreeView
controle .

Clique com o botão esquerdo do mouse: Click, MouseClick


Clique com o botão direito do mouse: Click, MouseClick
Clique duas vezes à esquerda: Click, MouseClick; DoubleClick,
MouseDoubleClick
Clique duas vezes com o botão direito do mouse: Click, MouseClick;
DoubleClick, MouseDoubleClick

Comportamento de pintura de controles de


alternância
Controles de alternância, como os controles derivados da ButtonBase classe , têm o
seguinte comportamento de pintura distinto em combinação com eventos de clique do
mouse:
1. O usuário pressiona o botão do mouse.

2. O controle pinta no estado pressionado.

3. O evento MouseDown será gerado.

4. O usuário libera o botão do mouse.

5. O controle pinta no estado elevado.

6. O evento Click será gerado.

7. O evento MouseClick será gerado.

8. O evento MouseUp será gerado.

7 Observação

Se o usuário mover o ponteiro para fora do controle de alternância enquanto


o botão do mouse estiver para baixo (como mover o mouse para fora do
Button controle enquanto ele é pressionado), o controle de alternância
pintará no estado elevado e apenas o MouseUp evento ocorrerá. Os Click
eventos ou MouseClick não ocorrerão nessa situação.

Confira também
Visão geral do uso do mouse (Windows Forms .NET)
Gerenciar ponteiros do mouse (Windows Forms .NET)
Como simular eventos do mouse (Windows Forms .NET)
System.Windows.Forms.Control
Visão geral do comportamento do
mouse de arrastar e soltar (Windows
Forms .NET)
Artigo • 15/02/2023 • 3 minutos para o fim da leitura

O Windows Forms incluem um conjunto de métodos, eventos e classes que


implementam o comportamento do tipo "arrastar e soltar". Este tópico fornece uma
visão geral do suporte a arrastar e soltar no Windows Forms.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Eventos de arrastar e soltar


Há duas categorias de eventos em uma operação de arrastar e soltar: os eventos que
ocorrem no destino atual da operação do tipo "arrastar e soltar" e eventos que ocorrem
na fonte da operação de arrastar e soltar. Para executar operações de arrastar e soltar,
você deve manipular esses eventos. Trabalhando com as informações disponíveis no
evento argumentos desses eventos, você pode facilmente orientar as operações do tipo
"arrastar e soltar".

Eventos no destino de descarte atual


A tabela a seguir mostra os eventos que ocorrem no destino atual de uma operação do
tipo "arrastar e soltar".

Eventos Descrição
de mouse

DragEnter Esse evento ocorre quando um objeto é arrastado para os limites do controle. O
manipulador para esse evento recebe um argumento do tipo DragEventArgs.

DragOver Esse evento ocorre quando um objeto é arrastado enquanto o ponteiro do mouse
está dentro dos limites do controle. O manipulador para esse evento recebe um
argumento do tipo DragEventArgs.
Eventos Descrição
de mouse

DragDrop Esse evento ocorre quando uma operação do tipo "arrastar e soltar" é concluída. O
manipulador para esse evento recebe um argumento do tipo DragEventArgs.

DragLeave Esse evento ocorre quando um objeto é arrastado para fora dos limites do controle.
O manipulador para esse evento recebe um argumento do tipo EventArgs.

A DragEventArgs classe fornece o local do ponteiro do mouse, o estado atual dos


botões do mouse e as teclas modificadoras do teclado, os dados que estão sendo
arrastados e DragDropEffects os valores que especificam as operações permitidas pela
origem do evento de arrastar e o efeito de soltar de destino para a operação.

Eventos na origem da remoção


A tabela a seguir mostra os eventos que ocorrem na fonte atual de uma operação do
tipo "arrastar e soltar".

Eventos de mouse Descrição

GiveFeedback Esse evento ocorre durante uma operação de arrastar. Ele fornece uma
indicação visual para o usuário que a operação do tipo "arrastar e soltar"
está ocorrendo, como uma alteração no ponteiro do mouse. O
manipulador para esse evento recebe um argumento do tipo
GiveFeedbackEventArgs.

QueryContinueDrag Esse evento é gerado durante uma operação do tipo "arrastar e soltar" e
permite que a fonte de arrastar determine se a operação do tipo "arrastar e
soltar" deve ser cancelada. O manipulador para esse evento recebe um
argumento do tipo QueryContinueDragEventArgs.

A QueryContinueDragEventArgs classe fornece o estado atual dos botões do mouse e


das teclas modificadoras do teclado, um valor que especifica se a tecla ESC foi
pressionada e um DragAction valor que pode ser definido para especificar se a
operação de arrastar e soltar deve continuar.

Executando arrastar e soltar


As operações de arrastar e soltar sempre envolvem dois componentes, a origem do
arrasto e o destino de soltar. Para iniciar uma operação de arrastar e soltar, designe um
controle como a origem e manipule o MouseDown evento. No manipulador de eventos,
chame o DoDragDrop método que fornece os dados associados à queda e ao valor
.DragDropEffects
Defina a propriedade do AllowDrop controle de destino definida como true para
permitir que esse controle aceite uma operação de arrastar e soltar. O destino manipula
dois eventos, primeiro um evento em resposta ao arrastão que está sobre o controle,
como DragOver. E um segundo evento que é a própria ação de soltar, DragDrop.

O exemplo a seguir demonstra um arraste de um Label controle para um TextBox.


Quando o arrastar é concluído, o TextBox responde atribuindo o texto do rótulo a si
mesmo.

C#

// Initiate the drag


private void label1_MouseDown(object sender, MouseEventArgs e) =>
DoDragDrop(((Label)sender).Text, DragDropEffects.All);

// Set the effect filter and allow the drop on this control
private void textBox1_DragOver(object sender, DragEventArgs e) =>
e.Effect = DragDropEffects.All;

// React to the drop on this control


private void textBox1_DragDrop(object sender, DragEventArgs e) =>
textBox1.Text = (string)e.Data.GetData(typeof(string));

Para obter mais informações sobre os efeitos de arrastar, consulte Data e AllowedEffect.

Confira também
Visão geral do uso do mouse (Windows Forms .NET)
Control.DragDrop
Control.DragEnter
Control.DragLeave
Control.DragOver
Como distinguir entre cliques e cliques
duplos (Windows Forms .NET)
Artigo • 15/02/2023 • 4 minutos para o fim da leitura

Normalmente, um único clique inicia uma ação de interface do usuário e um clique


duplo estende a ação. Por exemplo, um clique normalmente seleciona um item e um
clique duplo edita o item selecionado. No entanto, os eventos de clique Windows Forms
não acomodam facilmente um cenário em que um clique e um clique duplo executam
ações incompatíveis, pois uma ação vinculada ao Click evento ou MouseClick é
executada antes da ação vinculada ao DoubleClick evento ou MouseDoubleClick . Este
tópico demonstra duas soluções para esse problema.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Uma solução é manipular o evento de clique duplo e reverter as ações no tratamento de


evento de clique. Em situações raras, talvez seja necessário simular o comportamento de
clique e clique duas vezes manipulando o MouseDown evento e usando as
DoubleClickTime propriedades e DoubleClickSize da SystemInformation classe . Você
mede o tempo entre cliques e se um segundo clique ocorrer antes que o valor de
DoubleClickTime seja atingido e o clique estiver dentro de um retângulo definido por
DoubleClickSize, execute a ação de clique duplo; caso contrário, execute a ação de
clique.

Reverter uma ação de clique


Verifique se o controle em que você está trabalhando tem um comportamento de clique
duplo padrão. Caso contrário, habilite o controle com o SetStyle método . Trate o
evento de clique duplo e reverta a ação de clique, bem como a ação de clique duplo. O
exemplo de código a seguir demonstra um como criar um botão personalizado com
clique duplo habilitado, bem como reverter a ação de clique no código de tratamento
de eventos de clique duplo.

Este exemplo de código usa um novo controle de botão que permite cliques duplos:

C#
public partial class DoubleClickButton : Button
{
public DoubleClickButton()
{
// Set the style so a double click event occurs.
SetStyle(ControlStyles.StandardClick |
ControlStyles.StandardDoubleClick, true);
}
}

O código a seguir demonstra como um formulário altera o estilo da borda com base em
um clique ou clique duas vezes no novo controle de botão:

C#

public partial class Form1 : Form


{
private FormBorderStyle _initialStyle;
private bool _isDoubleClicking;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)


{
_initialStyle = this.FormBorderStyle;

var button1 = new DoubleClickButton();


button1.Location = new Point(50, 50);
button1.Size = new Size(200, 23);
button1.Text = "Click or Double Click";
button1.Click += Button1_Click;
button1.DoubleClick += Button1_DoubleClick;

Controls.Add(button1);
}

private void Button1_DoubleClick(object sender, EventArgs e)


{
// This flag prevents the click handler logic from running
// A double click raises the click event twice.
_isDoubleClicking = true;
FormBorderStyle = _initialStyle;
}

private void Button1_Click(object sender, EventArgs e)


{
if (_isDoubleClicking)
_isDoubleClicking = false;
else
FormBorderStyle = FormBorderStyle.FixedToolWindow;
}
}

Para distinguir entre cliques


Manipule o MouseDown evento e determine o local e o intervalo de tempo entre os
cliques usando a SystemInformation propriedade e um Timer componente. Execute a
ação apropriada dependendo se ocorreu um clique ou um clique duplo. O exemplo de
código a seguir demonstra como fazer isso.

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace project
{
public partial class Form2 : Form
{
private DateTime _lastClick;
private bool _inDoubleClick;
private Rectangle _doubleClickArea;
private TimeSpan _doubleClickMaxTime;
private Action _doubleClickAction;
private Action _singleClickAction;
private Timer _clickTimer;

public Form2()
{
InitializeComponent();
_doubleClickMaxTime =
TimeSpan.FromMilliseconds(SystemInformation.DoubleClickTime);

_clickTimer = new Timer();


_clickTimer.Interval = SystemInformation.DoubleClickTime;
_clickTimer.Tick += ClickTimer_Tick;

_singleClickAction = () => MessageBox.Show("Single clicked");


_doubleClickAction = () => MessageBox.Show("Double clicked");
}

private void Form2_MouseDown(object sender, MouseEventArgs e)


{
if (_inDoubleClick)
{
_inDoubleClick = false;
TimeSpan length = DateTime.Now - _lastClick;

// If double click is valid, respond


if (_doubleClickArea.Contains(e.Location) && length <
_doubleClickMaxTime)
{
_clickTimer.Stop();
_doubleClickAction();
}

return;
}

// Double click was invalid, restart


_clickTimer.Stop();
_clickTimer.Start();
_lastClick = DateTime.Now;
_inDoubleClick = true;
_doubleClickArea = new Rectangle(e.Location -
(SystemInformation.DoubleClickSize / 2),

SystemInformation.DoubleClickSize);
}

private void ClickTimer_Tick(object sender, EventArgs e)


{
// Clear double click watcher and timer
_inDoubleClick = false;
_clickTimer.Stop();

_singleClickAction();
}
}
}

Confira também
Visão geral do uso do mouse (Windows Forms .NET)
Usando eventos do mouse (Windows Forms .NET)
Gerenciar ponteiros do mouse (Windows Forms .NET)
Como simular eventos do mouse (Windows Forms .NET)
Control.Click
Control.MouseDown
Control.SetStyle
Gerenciar ponteiros do mouse
(Windows Forms .NET)
Artigo • 10/02/2023 • 2 minutos para o fim da leitura

O ponteiro do mouse, que às vezes é conhecido como o cursor, é um bitmap que


especifica um ponto de foco na tela para entrada do usuário com o mouse. Este tópico
fornece uma visão geral do ponteiro do mouse no Windows Forms e descreve algumas
maneiras de modificar e controlar o ponteiro do mouse.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Acessando o ponteiro do mouse


O ponteiro do Cursor mouse é representado pela classe e cada Control um tem uma
Control.Cursor propriedade que especifica o ponteiro para esse controle. A Cursor
classe contém propriedades que descrevem o ponteiro, como as Position propriedades
e HotSpot e métodos que podem modificar a aparência do ponteiro, como os
Showmétodos , Hidee DrawStretched .

O exemplo a seguir oculta o cursor quando o cursor está sobre um botão:

C#

private void button1_MouseEnter(object sender, EventArgs e) =>


Cursor.Hide();

private void button1_MouseLeave(object sender, EventArgs e) =>


Cursor.Show();

Controlando o ponteiro do mouse


Às vezes, pode ser recomendável limitar a área na qual o ponteiro do mouse pode ser
usado ou alterar a posição do mouse. Você pode obter ou definir o local atual do mouse
usando a Position propriedade do Cursor. Além disso, você pode limitar a área em que o
ponteiro do mouse pode ser usado para definir a Clip propriedade. A área de recorte,
por padrão, é a tela inteira.
O exemplo a seguir posiciona o ponteiro do mouse entre dois botões quando eles são
clicados:

C#

private void button1_Click(object sender, EventArgs e) =>


Cursor.Position = PointToScreen(button2.Location);

private void button2_Click(object sender, EventArgs e) =>


Cursor.Position = PointToScreen(button1.Location);

Alterando o ponteiro do mouse


Alterar o ponteiro do mouse é uma maneira importante de fornecer comentários para o
usuário. Por exemplo, o ponteiro do mouse pode ser modificado nos manipuladores dos
MouseEnter eventos e MouseLeave para informar ao usuário que as computações estão
ocorrendo e para limitar a interação do usuário no controle. Às vezes, o ponteiro do
mouse será alterado devido a eventos de sistema, como quando seu aplicativo está
envolvido em uma operação do tipo "arrastar e soltar".

A principal maneira de alterar o ponteiro do mouse é definindo a Control.Cursor


propriedade ou DefaultCursor de um controle como um novo Cursor. Para obter
exemplos de alteração do ponteiro do mouse, consulte o exemplo de código na Cursor
classe . Além disso, a Cursors classe expõe um conjunto de Cursor objetos para muitos
tipos diferentes de ponteiros, como um ponteiro semelhante a uma mão.

O exemplo a seguir altera o cursor do ponteiro do mouse para um botão para uma
mão:

C#

button2.Cursor = System.Windows.Forms.Cursors.Hand;

Para exibir o ponteiro de espera, que se assemelha a uma ampulheta, sempre que o
ponteiro do mouse estiver no controle, use a UseWaitCursor propriedade da Control
classe .

Confira também
Visão geral do uso do mouse (Windows Forms .NET)
Usando eventos do mouse (Windows Forms .NET)
Como distinguir entre cliques e cliques duplos (Windows Forms .NET)
Como simular eventos do mouse (Windows Forms .NET)
System.Windows.Forms.Cursor
Cursor.Position
Como simular eventos do mouse
(Windows Forms .NET)
Artigo • 09/02/2023 • 2 minutos para o fim da leitura

Simular eventos do mouse em Windows Forms não é tão simples quanto simular
eventos de teclado. Windows Forms não fornece uma classe auxiliar para mover o
mouse e invocar ações de clique do mouse. A única opção para controlar o mouse é
usar métodos nativos do Windows. Se você estiver trabalhando com um controle
personalizado ou um formulário, poderá simular um evento do mouse, mas não poderá
controlar diretamente o mouse.

) Importante

A documentação do Guia da Área de Trabalho para .NET 7 e .NET 6 está em


construção.

Eventos
A maioria dos eventos tem um método correspondente que os invoca, nomeado no
padrão de On seguido por EventName , como OnMouseMove . Essa opção só é possível em
formulários ou controles personalizados, pois esses métodos são protegidos e não
podem ser acessados de fora do contexto do controle ou formulário. A desvantagem de
usar um método como OnMouseMove é que ele realmente não controla o mouse ou
interage com o controle, ele simplesmente gera o evento associado. Por exemplo, se
você quiser simular passar o mouse sobre um item em um ListBoxe OnMouseMove o
ListBox não reagir visualmente com um item realçado sob o cursor.

Esses métodos protegidos estão disponíveis para simular eventos do mouse.

OnMouseDown

OnMouseEnter
OnMouseHover

OnMouseLeave
OnMouseMove

OnMouseUp

OnMouseWheel
OnMouseClick

OnMouseDoubleClick
Para obter mais informações sobre esses eventos, consulte Usando eventos do mouse
(Windows Forms .NET)

Invocar um clique
Considerando que a maioria dos controles faz algo quando clicado, como um botão que
chama o código do usuário ou a caixa de seleção altera seu estado marcado, Windows
Forms fornece uma maneira fácil de disparar o clique. Alguns controles, como uma caixa
de combinação, não fazem nada especial quando clicado e simular um clique não tem
efeito sobre o controle.

Performclick
A System.Windows.Forms.IButtonControl interface fornece o PerformClick método que
simula um clique no controle . System.Windows.Forms.Button Os controles e
System.Windows.Forms.LinkLabel implementam essa interface.

C#

button1.PerformClick();

InvokeClick
Com um formulário de um controle personalizado, use o InvokeOnClick método para
simular um clique do mouse. Esse é um método protegido que só pode ser chamado de
dentro do formulário ou de um controle personalizado derivado.

Por exemplo, o código a seguir clica em uma caixa de seleção de button1 .

C#

private void button1_Click(object sender, EventArgs e)


{
InvokeOnClick(checkBox1, EventArgs.Empty);
}

Usar métodos nativos do Windows


O Windows fornece métodos que você pode chamar para simular movimentos do
mouse e cliques como User32.dll SendInput e User32.dll SetCursorPos. O exemplo a
seguir move o cursor do mouse para o centro de um controle:
C#

[DllImport("user32.dll", EntryPoint = "SetCursorPos")]


[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetCursorPos(int x, int y);

private void button1_Click(object sender, EventArgs e)


{
Point position = PointToScreen(checkBox1.Location) + new
Size(checkBox1.Width / 2, checkBox1.Height / 2);
SetCursorPos(position.X, position.Y);
}

Confira também
Visão geral do uso do mouse (Windows Forms .NET)
Usando eventos do mouse (Windows Forms .NET)
Como distinguir entre cliques e cliques duplos (Windows Forms .NET)
Gerenciar ponteiros do mouse (Windows Forms .NET)
Visão geral do componente PrintDialog
(Windows Forms .NET)
Artigo • 08/02/2023 • 4 minutos para o fim da leitura

Imprimir em Windows Forms consiste principalmente em usar o PrintDocument


componente para permitir que o usuário imprima. O PrintPreviewDialog controle
PrintDialog e PageSetupDialog os componentes fornecem uma interface gráfica familiar
para Windows usuários do sistema operacional.

O PrintDialog componente é uma caixa de diálogo pré-configurada usada para


selecionar uma impressora, escolher as páginas a serem impressas e determinar outras
configurações relacionadas à impressão em aplicativos baseados em Windows. É uma
solução simples para configurações relacionadas à impressora e à impressão em vez de
configurar sua própria caixa de diálogo. Você pode habilitar os usuários a imprimir
muitas partes de seus documentos: imprimir tudo, imprimir um intervalo de páginas
selecionadas ou uma seleção. Com base nas caixas de diálogo padrão do Windows, crie
aplicativos cuja funcionalidade básica é imediatamente familiar aos usuários. O
PrintDialog componente herda da CommonDialog classe.

Normalmente, você cria uma nova instância do PrintDocument componente e define as


propriedades que descrevem o que imprimir usando e PrinterSettingsPageSettings
classes. A chamada para o Print método realmente imprime o documento.

Trabalhando com o componente


Use o método PrintDialog.ShowDialog para exibir a caixa de diálogo em tempo de
execução. Esse componente tem propriedades relacionadas a um único trabalho de
impressão (PrintDocument classe) ou às configurações de uma impressora individual
(PrinterSettings classe). Um dos dois, por sua vez, pode ser compartilhado por várias
impressoras.

O método da caixa de diálogo mostrar ajuda você a adicionar a caixa de diálogo de


impressão ao formulário. O PrintDialog componente aparece na bandeja na parte
inferior do Designer de Windows Forms no Visual Studio.

Como capturar a entrada do usuário de um


PrintDialog em tempo de execução
Você pode definir opções relacionadas à impressão em tempo de design. Às vezes,
talvez você queira alterar essas opções em tempo de execução, provavelmente devido
às escolhas feitas pelo usuário. Você pode capturar a entrada do usuário para imprimir
um documento usando os componentes e os PrintDialogPrintDocument componentes.
As etapas a seguir demonstram a exibição da caixa de diálogo de impressão de um
documento:

1. Adicione um PrintDialog e um PrintDocument componente ao formulário.

2. Defina a Document propriedade da PrintDialog adição PrintDocument ao


formulário.

C#

printDialog1.Document = printDocument1;

3. Exiba o PrintDialog componente usando o ShowDialog método.

C#

// display show dialog and if user selects "Ok" document is printed


if (printDialog1.ShowDialog() == DialogResult.OK)
printDocument1.Print();

4. As opções de impressão do usuário da caixa de diálogo serão copiadas para a


PrinterSettings propriedade do PrintDocument componente.

Como criar trabalhos de impressão


A base da impressão em Windows Forms é o PrintDocument componente , mais
especificamente, o PrintPage evento. Ao escrever código para manipular o PrintPage
evento, você pode especificar o que imprimir e como imprimi-lo. As seguintes etapas
demonstram a criação do trabalho de impressão:

1. Adicione um PrintDocument componente ao formulário.

2. Escreva código para manipular o PrintPage evento.

Você terá que codificar sua própria lógica de impressão. Além disso, você precisará
especificar o material a ser impresso.

Como um material a ser impresso, no exemplo de código a seguir, um gráfico de


exemplo na forma de um retângulo vermelho é criado no manipulador de
PrintPage eventos.
C#

private void PrintDocument1_PrintPage(object sender,


System.Drawing.Printing.PrintPageEventArgs e) =>
e.Graphics.FillRectangle(Brushes.Red, new Rectangle(100, 100, 100,
100));

Talvez você também queira escrever código para eventos e eventos BeginPrintEndPrint .
Ele ajudará a incluir um inteiro que representa o número total de páginas a serem
impressas que são deccrementados conforme cada página é impressa.

7 Observação

Você pode adicionar um PrintDialog componente ao formulário para fornecer uma


interface do usuário (interface do usuário) limpa e eficiente aos usuários. Definir a
Document propriedade do PrintDialog componente permite definir propriedades
relacionadas ao documento de impressão com o qual você está trabalhando em
seu formulário.

Para obter mais informações sobre as especificidades de Windows Forms trabalhos de


impressão, incluindo como criar um trabalho de impressão programaticamente,
consulte PrintPageEventArgs.

Como concluir trabalhos de impressão


Frequentemente, processadores de texto e outros aplicativos que envolvem impressão
fornecerão a opção para exibir uma mensagem aos usuários de que um trabalho de
impressão foi concluído. Você pode fornecer essa funcionalidade em sua Windows
Forms manipulando o EndPrint evento do PrintDocument componente.

O procedimento a seguir exige que você tenha criado um aplicativo baseado em


Windows com um PrintDocument componente. O procedimento abaixo é a maneira
padrão de habilitar a impressão de um aplicativo baseado em Windows. Para obter mais
informações sobre impressão de Windows Forms usando o PrintDocument
componente, consulte Como criar trabalhos de impressão.

1. Defina a DocumentName propriedade do PrintDocument componente.

C#

printDocument1.DocumentName = "SamplePrintApp";
2. Escreva código para manipular o EndPrint evento.

No exemplo de código a seguir, uma caixa de mensagem é exibida, indicando que


o documento terminou a impressão.

C#

private void PrintDocument1_EndPrint(object sender,


System.Drawing.Printing.PrintEventArgs e) =>
MessageBox.Show(printDocument1.DocumentName + " has finished
printing.");
Imprimir um arquivo de texto de várias
páginas (Windows Forms .NET)
Artigo • 08/02/2023 • 3 minutos para o fim da leitura

É comum que aplicativos baseados em Windows imprimam texto. A Graphics classe


fornece métodos para desenhar objetos (elementos gráficos ou texto) para um
dispositivo, como uma tela ou impressora. A seção a seguir descreve detalhadamente o
processo para imprimir o arquivo de texto. Esse método não dá suporte à impressão de
arquivos de texto não simples, como um documento do Office Word ou um arquivo
PDF.

7 Observação

Não DrawText há suporte para os métodos TextRenderer de impressão. Você


sempre deve usar os DrawString métodos de Graphics, conforme mostrado no
exemplo de código a seguir, para desenhar texto para fins de impressão.

Imprimir texto
1. Em Visual Studio, clique duas vezes no formulário do qual você deseja imprimir, no
painel Gerenciador de Soluções. Isso abre o Visual Designer.

2. Na Caixa de Ferramentas, clique duas vezes no PrintDocument componente para


adicioná-lo ao formulário. Isso deve criar um PrintDocument componente com o
nome printDocument1 .

3. Adicione um Button ao formulário ou use um botão que já esteja no formulário.

4. No Designer Visual do formulário, selecione o botão. No painel Propriedades ,


selecione o botão Filtro de Evento e clique duas vezes no Click evento para gerar
um manipulador de eventos.

5. O Click código do evento deve estar visível. Fora do escopo do manipulador de


eventos, adicione uma variável de cadeia de caracteres privada à classe chamada
stringToPrint .

C#

private string stringToPrint="";


6. De volta ao código do Click manipulador de eventos, defina a DocumentName
propriedade como o nome do documento. Essas informações são enviadas para a
impressora. Em seguida, leia o conteúdo do texto do documento e armazene-o
stringToPrint na cadeia de caracteres. Por fim, chame o Print método para gerar
o PrintPage evento. O Print método está realçado abaixo.

C#

private void button1_Click(object sender, EventArgs e)


{
string docName = "testPage.txt";
string docPath = @"C:\";
string fullPath = System.IO.Path.Combine(docPath, docName);

printDocument1.DocumentName = docName;

stringToPrint = System.IO.File.ReadAllText(fullPath);

printDocument1.Print();
}

7. Voltar ao Designer Visual do formulário e selecione o PrintDocument componente.


No painel Propriedades , selecione o filtro Evento e clique duas vezes no
PrintPage evento para gerar um manipulador de eventos.

8. PrintPage No manipulador de eventos, use a Graphics propriedade da


PrintPageEventArgs classe e o conteúdo do documento para calcular o
comprimento da linha e as linhas por página. Depois que cada página for
desenhada, verifique se ela é a última página e defina a HasMorePages
propriedade do PrintPageEventArgs correspondente. O PrintPage evento é
acionado até HasMorePages que seja false .

No exemplo de código a seguir, o manipulador de eventos é usado para imprimir


o conteúdo do arquivo "testPage.txt" na mesma fonte usada no formulário.

C#

private void PrintDocument1_PrintPage(object sender,


System.Drawing.Printing.PrintPageEventArgs e)
{
int charactersOnPage = 0;
int linesPerPage = 0;

// Sets the value of charactersOnPage to the number of characters


// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);

// Draws the string within the bounds of the page


e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);

// Remove the portion of the string that has been printed.


stringToPrint = stringToPrint.Substring(charactersOnPage);

// Check to see if more pages are to be printed.


e.HasMorePages = (stringToPrint.Length > 0);
}

Confira também
Graphics
Brush
Visão geral do componente PrintDialog
Como imprimir um formulário
(Windows Forms .NET)
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

Como parte do processo de desenvolvimento, você normalmente deseja imprimir uma


cópia do formulário Windows. O exemplo de código a seguir mostra como imprimir
uma cópia do formulário atual usando o CopyFromScreen método.

No exemplo a seguir, um botão chamado Button1 é adicionado ao formulário. Quando


o botão Button1 é clicado, ele salva o formulário em uma imagem na memória e o envia
para o objeto de impressão.

Exemplo
C#

namespace Sample_print_win_form1
{
public partial class Form1 : Form
{
Bitmap memoryImage;
public Form1()
{
InitializeComponent();
}

private void Button1_Click(object sender, EventArgs e)


{
Graphics myGraphics = this.CreateGraphics();
Size s = this.Size;
memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(this.Location.X, this.Location.Y,
0, 0, s);

printDocument1.Print();

}
private void PrintDocument1_PrintPage(System.Object sender,
System.Drawing.Printing.PrintPageEventArgs e) =>
e.Graphics.DrawImage(memoryImage, 0, 0);

}
}
Programação robusta
As seguintes condições podem causar uma exceção:

Você não tem permissão para acessar a impressora.

Não há nenhuma impressora instalada.

Segurança do .NET
Para executar este exemplo de código, você deve ter permissão para acessar a
impressora que usa com seu computador.

Confira também
PrintDocument
Como: renderizar imagens com o GDI+
Como: imprimir elementos gráficos no Windows Forms
Imprimir usando visualização de
impressão (Windows Forms .NET)
Artigo • 08/02/2023 • 4 minutos para o fim da leitura

É comum em Windows Forms programação oferecer visualização de impressão além de


serviços de impressão. Uma maneira fácil de adicionar serviços de visualização de
impressão ao seu aplicativo é usar um PrintPreviewDialog controle em combinação com
a PrintPage lógica de tratamento de eventos para imprimir um arquivo.

Visualizar um documento de texto com um


controle PrintPreviewDialog
1. Em Visual Studio, use o painel Gerenciador de Soluções e clique duas vezes no
formulário do qual você deseja imprimir. Isso abre o Visual Designer.

2. No painel Caixa de Ferramentas , clique duas vezes no PrintDocument


componente e no PrintPreviewDialog componente para adicioná-los ao formulário.

3. Adicione um Button ao formulário ou use um botão que já esteja no formulário.

4. No Designer Visual do formulário, selecione o botão. No painel Propriedades ,


selecione o botão Filtro de Evento e clique duas vezes no Click evento para gerar
um manipulador de eventos.

5. O Click código do evento deve estar visível. Fora do escopo do manipulador de


eventos, adicione duas variáveis de cadeia de caracteres privadas à classe
nomeada documentContents e stringToPrint :

C#

// Declare a string to hold the entire document contents.


private string documentContents="";

// Declare a variable to hold the portion of the document that


// is not printed.
private string stringToPrint="";

6. De volta ao código do Click manipulador de eventos, defina a DocumentName


propriedade como o documento que você deseja imprimir e abra e leia o
conteúdo do documento para a cadeia de caracteres que você adicionou
anteriormente.
C#

string docName = "testPage.txt";


string docPath = @"C:\";
string fullPath = System.IO.Path.Combine(docPath, docName);
printDocument1.DocumentName = docName;
stringToPrint = System.IO.File.ReadAllText(fullPath);

7. Como faria para imprimir o documento, no PrintPage manipulador de eventos, use


a Graphics propriedade da classe e o conteúdo do PrintPageEventArgs arquivo
para calcular linhas por página e renderizar o conteúdo do documento. Depois
que cada página for desenhada, verifique se ela é a última página e defina a
HasMorePages propriedade de PrintPageEventArgs acordo. O PrintPage evento é
gerado até HasMorePages que seja false . Após a renderização do documento ser
concluída, redefina a cadeia de caracteres a ser renderizada. Além disso, verifique
se o PrintPage evento está associado ao método de manipulação de eventos.

7 Observação

Se você implementou a impressão em seu aplicativo, talvez já tenha concluído


as etapas 5 e 6.

No exemplo de código a seguir, o manipulador de eventos é usado para imprimir


o arquivo “testPage.txt” na mesma fonte usada no formulário.

C#

void PrintDocument1_PrintPage(object sender, PrintPageEventArgs e)


{
int charactersOnPage = 0;
int linesPerPage = 0;

// Sets the value of charactersOnPage to the number of characters


// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);

// Draws the string within the bounds of the page.


e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);

// Remove the portion of the string that has been printed.


stringToPrint = stringToPrint.Substring(charactersOnPage);

// Check to see if more pages are to be printed.


e.HasMorePages = (stringToPrint.Length > 0);
// If there are no more pages, reset the string to be printed.
if (!e.HasMorePages)
stringToPrint = documentContents;
}

8. Defina a Document propriedade do PrintPreviewDialog controle como o


PrintDocument componente no formulário.

C#

printPreviewDialog1.Document = printDocument1;

9. Chame o ShowDialog método no PrintPreviewDialog controle. Observe o código


realçado especificado abaixo, que normalmente você chamaria ShowDialog do
Click método de tratamento de eventos de um botão. A chamada ShowDialog
gera o PrintPage evento e renderiza a saída para o PrintPreviewDialog controle.
Quando o usuário seleciona o ícone de impressão na caixa de diálogo, o
PrintPage evento é gerado novamente, enviando a saída para a impressora em

vez da caixa de diálogo de visualização. Portanto, a cadeia de caracteres é


redefinida no final do processo de renderização na etapa 4.

O exemplo de código a seguir mostra o Click método de tratamento de eventos


para um botão no formulário. O método de tratamento de eventos chama os
métodos para ler o documento e mostrar a caixa de diálogo de visualização de
impressão.

C#

private void Button1_Click(object sender, EventArgs e)


{
string docName = "testPage.txt";
string docPath = @"C:\";
string fullPath = System.IO.Path.Combine(docPath, docName);
printDocument1.DocumentName = docName;
stringToPrint = System.IO.File.ReadAllText(fullPath);

printPreviewDialog1.Document = printDocument1;

printPreviewDialog1.ShowDialog();
}

Confira também
Visão geral do componente PrintDialog
Imprimir um arquivo de texto de várias páginas
Impressão mais segura no Windows Forms
Visão geral da associação de dados
(Windows Forms .NET)
Artigo • 08/02/2023 • 16 minutos para o fim da leitura

No Windows Forms, você pode vincular não apenas a fontes de dados tradicionais, mas
também a praticamente qualquer estrutura que contenha dados. Você pode vincular 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 vincular qualquer propriedade de qualquer controle à fonte de
dados. Na vinculação de dados tradicional, você geralmente vincula 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. É possível usar a vinculação para realizar as seguintes tarefas:

Definir o grafo de um controle de imagem.

Definir a cor do plano de fundo de um ou mais controles.

Definir o tamanho dos controles.

Basicamente, a vinculação de dados é uma maneira automática de configurar qualquer


propriedade acessível do tempo de execução de qualquer controle em um formulário.

Interfaces relacionadas à associação de dados


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 forneçam ou consumam
dados em 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 de fonte de dados, como os controles Windows Forms ou componentes,
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 Windows Forms. Você pode
implementar essas interfaces em classes associadas ao formulário para habilitar a
associação de dados. Cada caso apresenta uma classe que implementa uma interface
que permite a interação com os dados. Visual Studio ferramentas de experiência de
design de dados RAD (desenvolvimento rápido de aplicativos) já aproveitam essa
funcionalidade.

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


Os controles Windows Forms implementam as seguintes interfaces:

Interface IList

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

7 Observação

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

Interface IBindingList

Uma classe que implementa a IBindingList interface 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 da 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.

7 Observação

A notificação de alteração está habilitada para a IBindingList interface por


meio da SupportsChangeNotification propriedade que, quando true , gera
um ListChanged evento, indicando a lista alterada ou um item na lista foi
alterado.

O tipo de alteração é descrito pela ListChangedType propriedade do


ListChangedEventArgs parâmetro. 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 ListChanged evento.

7 Observação

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


interface.

Interface IBindingListView

Uma classe que implementa a IBindingListView interface 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 cadeia de caracteres e classificação de várias colunas
com pares de direção de descritor de propriedade.

Interface IEditableObject

Uma classe que implementa a IEditableObject interface permite que um objeto


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

O BeginEdit método sinaliza o início de uma edição em um objeto. Um objeto


que implementa essa interface precisará armazenar quaisquer atualizações após
a chamada do BeginEdit método de forma que as atualizações possam ser
descartadas se o CancelEdit método for chamado. No Windows Forms de
associação de dados, você pode chamar BeginEdit várias vezes no escopo de
uma única transação de edição (por exemplo, BeginEdit , , BeginEdit , EndEdit).
As implementações devem IEditableObject acompanhar se BeginEdit já foram
chamadas e ignorar chamadas subsequentes para BeginEdit . Como esse
método pode ser chamado várias vezes, é importante que as chamadas
subsequentes sejam não estruturativas. Chamadas subsequentes BeginEdit não
podem destruir as atualizações que foram feitas ou alterar os dados que foram
salvos na primeira BeginEdit chamada.

O EndEdit método envia por push todas as alterações desde BeginEdit que foi
chamado para o objeto subjacente, se o objeto estiver atualmente no modo de
edição.

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

Para obter mais informações sobre como os BeginEditmétodos e CancelEdit os


métodos EndEditfuncionam, consulte Salvar dados de volta no banco de dados.

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


controle.

Interface ICancelAddNew

Uma classe que implementa a ICancelAddNew interface geralmente implementa a


IBindingList interface e permite reverter uma adição feita à fonte de dados com o
AddNew método. Se a fonte de dados implementar a IBindingList interface, você
também deverá implementá-la ICancelAddNew .

Interface IDataErrorInfo

Uma classe que implementa a IDataErrorInfo interface permite que objetos


ofereçam informações de erro personalizadas a controles associados:

A Error propriedade retorna texto de mensagem de erro geral (por exemplo,


"Ocorreu um erro").

A Item[] propriedade retorna uma cadeia de caracteres com a mensagem de


erro específica da coluna (por exemplo, "O valor na State coluna é inválido").

Interface IEnumerable

Uma classe que implementa a IEnumerable interface normalmente é consumida


por ASP.NET. Windows Forms suporte para essa interface só está disponível por
meio do BindingSource componente.

7 Observação

O BindingSource componente copia todos os IEnumerable itens em uma lista


separada para fins de associação.
Interface ITypedList

Uma classe de coleções que implementa a ITypedList interface fornece o recurso


para controlar a ordem e o conjunto de propriedades expostas ao controle
associado.

7 Observação

Quando você implementa o GetItemProperties método e a


PropertyDescriptor matriz 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 ICustomTypeDescriptor interface fornece


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

7 Observação

Para dar suporte à associação de tempo de design aos 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 permite a IListSource associação baseada


em lista em objetos não listados. O GetList método de IListSource é usado para
retornar uma lista associável de um objeto que não herda de IList. IListSource é
usado pela DataSet classe.

Interface IRaiseItemChangedEvents

Uma classe que implementa a IRaiseItemChangedEvents interface é uma lista


associável que também implementa a IBindingList interface. Essa interface é usada
para indicar se seu tipo gera ListChanged eventos de tipo ItemChanged por meio
de sua RaisesItemChangedEvents propriedade.
7 Observação

Você deve implementar se a IRaiseItemChangedEvents fonte de dados


fornecer a propriedade para listar a conversão de eventos descrita
anteriormente e estiver interagindo com o BindingSource componente. Caso
contrário, a BindingSource propriedade também executará para listar a
conversão de eventos, resultando em um desempenho mais lento.

Interface ISupportInitialize

Um componente que implementa a ISupportInitialize interface aproveita as


otimizações em lote para definir propriedades e inicializar propriedades
codependadas. O ISupportInitialize contém dois métodos:

BeginInit sinaliza que a inicialização do objeto está iniciando.

EndInit sinaliza que a inicialização do objeto está terminando.

Interface ISupportInitializeNotification

Um componente que implementa a ISupportInitializeNotification interface também


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

IsInitialized retorna um boolean valor que indica se o componente é


inicializado.

Initialized ocorre quando EndInit é chamado.

Interface INotifyPropertyChanged

Uma classe que implementa essa interface é um tipo que aciona um evento
quando qualquer um dos seus valores de propriedade são alterados. 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 INotifyPropertyChanged interface e o BindingList'1
converterá PropertyChanged eventos em ListChanged eventos do tipo
ItemChanged.

7 Observação
Para que a notificação de alteração ocorra em uma associação entre um
cliente associado e uma fonte de dados, seu tipo de fonte de dados associada
deve implementar a INotifyPropertyChanged interface (preferencial) ou você
pode fornecer eventos propertyName Changed para o tipo associado, mas você
não deve fazer ambos.

Interfaces para implementação por autores de componentes


As seguintes interfaces são projetadas para consumo pelo mecanismo de associação de
dados dos Windows Forms:

Interface IBindableComponent

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

7 Observação

Se o componente herdar, Controlvocê não precisará implementar a


IBindableComponent interface.

Interface ICurrencyManagerProvider

Uma classe que implementa a ICurrencyManagerProvider interface é um


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

7 Observação

Uma classe que herda de Control gerencia associações automaticamente por


meio de sua BindingContext propriedade, portanto, os casos em que você
precisa implementar são ICurrencyManagerProvider bastante raros.

Fontes de dados compatíveis com Windows


Forms
Tradicionalmente, a associação de dados era usada nos aplicativos para tirar proveito
dos dados armazenados em bancos de dados. Com Windows Forms associação de
dados, 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 para associar a


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

A lista a seguir mostra as estruturas a que você pode associar no Windows Forms.

BindingSource

A BindingSource é a fonte de dados de Windows Forms mais comum e atua em


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

Objetos simples

Windows Forms dar suporte a propriedades de controle de associação de dados a


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

Matriz ou Coleção

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

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

IEnumerable

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

objetos de dados ADO.NET

ADO.NET fornece muitas estruturas de dados adequadas para associação. Cada


uma delas varia em termos de sofisticação e complexidade.

DataColumn

A DataColumn é o bloco de construção essencial de um DataTable, em que


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

DataTable

A 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 DataGridView controle a uma tabela de
dados). No entanto, quando você associa a um DataTable , você é uma
associação ao modo de exibição padrão da tabela.

DataView

A 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 forma complexa. Você pode associar
ou associar de forma simples ou complexa aos dados dentro de 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

Uma DataSet é uma coleção de tabelas, relações e restrições dos dados em um


banco de dados. Você pode associar simples ou associar complexos aos dados
dentro de um conjunto de dados, mas observe que você está associando ao
padrão DataViewManager para o DataSet (consulte o próximo ponto
marcador).

DataViewManager

A DataViewManager é uma exibição personalizada de todo DataSeto , análogo


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

Tipos de associação de dados


O Windows Forms pode tirar proveito de dois tipos de vinculação de dados: vinculação
simples e vinculação complexa. Cada uma oferece vantagens diferentes.

Tipo de Descrição
vinculação
de dados

Vinculação A capacidade de um controle em vincular a um elemento de dados único, tal como


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

Para obter mais informações, consulte Navegar dados e criar um controle de


associação simples (Windows Forms .NET).
Tipo de Descrição
vinculação
de dados

Vinculação A capacidade de um controle para vincular a mais de um elemento de dados,


de dados geralmente mais de um registro em um banco de dados. A vinculação complexa
complexos também é chamada de vinculação baseada em lista. Exemplos de controles que
suportam vinculação complexa são os controles DataGridView, ListBox e ComboBox.
Para obter um exemplo de associação de dados complexa, consulte Como associar
um Windows Forms ComboBox ou controle ListBox aos dados.

Componente de origem de associação


Para simplificar a vinculação de dados, o Windows Forms permite que você vincule uma
fonte de dados ao componente BindingSource e, em seguida, vincule controles à
BindingSource . Você pode usar a BindingSource em cenários de vinculaçã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


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

Cenário Descrição

Relatórios Os relatórios fornecem uma maneira flexível para exibir e resumir 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 que melhor se adequa aos dados.

Entrada de É uma forma comum de inserir grandes quantidades de dados relacionados ou


dados de 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. As
informações são então enviadas e armazenadas em um banco de dados, cuja
estrutura se baseia nas informações inseridas.
Cenário Descrição

Relação Um aplicativo mestre/detalhes é um formato para pesquisa em dados


mestre/detalhes relacionados. Especificamente, há duas tabelas de dados com uma relação que
se conecta 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 Windows FormsDataGridView,
consulte Como criar um formulário mestre/detalhado usando dois controles
DataGridView Windows Forms

Tabela de Outro cenário comum de apresentação/manipulação de dados é a pesquisa de


pesquisa tabela. Geralmente, como parte de uma exibição de dados maior, um controle
ComboBox é usado para exibir e manipular os dados. A chave é que os dados
exibidos no controle ComboBox sejam diferentes dos dados gravados no banco
de dados. Por exemplo, se você tiver um controle ComboBox exibindo os itens
disponíveis em uma mercearia, provavelmente gostaria de ver os nomes dos
produtos (pão, leite, ovos). No entanto, para facilitar a recuperação de
informações do banco de dados e para a normalização do banco de dados,
você provavelmente armazenará as informações dos itens específicos em 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 em ComboBox seu formulário e o número de item
relacionado que está presente em uma ordem. É a essência de uma pesquisa
de tabela. Para obter mais informações, consulte Como criar uma tabela de
pesquisa com o componente Windows Forms BindingSource.

Confira também
Binding
Visão geral da vinculação de dados
Criar ótimas fontes de dados com notificação de alteração
Criar um controle de associação simples (Windows Forms .NET)
Componente BindingSource
Como: Associar o controle DataGrid do Windows Forms a uma fonte de dados
Criar ótimas fontes de dados com
notificação de alteração (Windows
Forms .NET)
Artigo • 08/02/2023 • 10 minutos para o fim da leitura

Um dos conceitos mais importantes da associação de dados Windows Forms é a


notificação de alteração. Para garantir que a fonte de dados e os controles associados
sempre tenham os dados mais recentes, você deve adicionar a notificação de alteração
para associação de dados. Especificamente, você deseja garantir que os controles
associados sejam notificados sobre as alterações feitas na fonte de dados. A fonte de
dados é notificada sobre as alterações feitas nas propriedades associadas de um
controle.

Há diferentes tipos de notificações de alteração, dependendo do tipo de associação de


dados:

Associação simples, na qual uma única propriedade de controle está associada a


uma única instância de um objeto.

Associação baseada em lista, que pode incluir uma única propriedade de controle
associada à propriedade de um item em uma lista ou uma propriedade de controle
associada a uma lista de objetos.

Além disso, se você estiver criando Windows Forms controles que deseja usar para
associação de dados, deverá aplicar o padrão PropertyNameChanged aos controles. A
aplicação de padrão aos controles resulta em alterações na propriedade associada de
um controle são propagadas para a fonte de dados.

Alterar notificação para associação simples


Para associação simples, os objetos de negócios devem fornecer notificação de
alteração quando o valor de uma propriedade associada for alterado. Você pode
fornecer uma notificação de alteração expondo um evento PropertyNameChanged para
cada propriedade do objeto de negócios. Ele também requer a associação do objeto de
negócios aos controles com o BindingSource método preferencial no qual o objeto
empresarial implementa a INotifyPropertyChanged interface e gera um
PropertyChanged evento quando o valor de uma propriedade é alterado. Quando você
usa objetos que implementam a INotifyPropertyChanged interface, não é necessário
usar o BindingSource para associar o objeto a um controle. Mas usar o BindingSource é
recomendado.

Alterar notificação para associação baseada em


lista
Windows Forms depende de uma lista associada para fornecer informações de alteração
de propriedade e alteração de lista para controles associados. A alteração da propriedade
é uma alteração do valor da propriedade do item de lista e a alteração da lista é um
item excluído ou adicionado à lista. Portanto, as listas usadas para associação de dados
devem implementar o IBindingList, que fornece os dois tipos de notificação de
alteração. A BindingList<T> implementação IBindingList é genérica e foi projetada
para uso com Windows Forms associação de dados. Você pode criar um BindingList
tipo de objeto comercial que implementa INotifyPropertyChanged e a lista converterá
automaticamente os PropertyChanged eventos em ListChanged eventos. Se a lista
associada não for uma IBindingList , você deverá associar a lista de objetos aos
controles Windows Forms usando o BindingSource componente. O BindingSource
componente fornecerá conversão de propriedade para lista semelhante à do
BindingList . Para obter mais informações, consulte Como gerar notificações de

alteração usando um BindingSource e a interface INotifyPropertyChanged.

Alterar notificação para controles


personalizados
Por fim, do lado do controle, você deve expor um evento PropertyNameChanged para
cada propriedade projetada para estar associada a dados. As alterações na propriedade
de controle são propagadas para a fonte de dados associada. Para obter mais
informações, consulte Aplicar o padrão PropertyNameChanged.

Aplicar o padrão PropertyNameChanged


O exemplo de código a seguir demonstra como aplicar o padrão
PropertyNameChanged a um controle personalizado. Aplique o padrão ao implementar
controles personalizados usados com o mecanismo de associação de dados Windows
Forms.

C#
// This class implements a simple user control
// that demonstrates how to apply the propertyNameChanged pattern.
[ComplexBindingProperties("DataSource", "DataMember")]
public class CustomerControl : UserControl
{
private DataGridView dataGridView1;
private Label label1;
private DateTime lastUpdate = DateTime.Now;

public EventHandler DataSourceChanged;

public object DataSource


{
get
{
return this.dataGridView1.DataSource;
}
set
{
if (DataSource != value)
{
this.dataGridView1.DataSource = value;
OnDataSourceChanged();
}
}
}

public string DataMember


{
get { return this.dataGridView1.DataMember; }

set { this.dataGridView1.DataMember = value; }


}

private void OnDataSourceChanged()


{
if (DataSourceChanged != null)
{
DataSourceChanged(this, new EventArgs());
}
}

public CustomerControl()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
this.label1 = new System.Windows.Forms.Label();
this.dataGridView1.ColumnHeadersHeightSizeMode =

System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.ImeMode = System.Windows.Forms.ImeMode.Disable;
this.dataGridView1.Location = new System.Drawing.Point(100, 100);
this.dataGridView1.Size = new System.Drawing.Size(500,500);

this.dataGridView1.TabIndex = 1;
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(50, 50);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(76, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Customer List:";
this.Controls.Add(this.label1);
this.Controls.Add(this.dataGridView1);
this.Size = new System.Drawing.Size(450, 250);
}
}

Implementar a interface
INotifyPropertyChanged
O exemplo de código a seguir demonstra como implementar a INotifyPropertyChanged
interface. Implemente a interface em objetos de negócios que são usados em Windows
Forms associação de dados. Quando implementada, a interface se comunica com um
controle associado que a propriedade muda em um objeto de negócios.

C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

// Change the namespace to the project name.


namespace binding_control_example
{
// This form demonstrates using a BindingSource to bind
// a list to a DataGridView control. The list does not
// raise change notifications. However the DemoCustomer1 type
// in the list does.
public partial class Form3 : Form
{
// This button causes the value of a list element to be changed.
private Button changeItemBtn = new Button();

// This DataGridView control displays the contents of the list.


private DataGridView customersDataGridView = new DataGridView();

// This BindingSource binds the list to the DataGridView control.


private BindingSource customersBindingSource = new BindingSource();

public Form3()
{
InitializeComponent();
// Set up the "Change Item" button.
this.changeItemBtn.Text = "Change Item";
this.changeItemBtn.Dock = DockStyle.Bottom;
this.changeItemBtn.Height = 100;
//this.changeItemBtn.Click +=
// new EventHandler(changeItemBtn_Click);
this.Controls.Add(this.changeItemBtn);

// Set up the DataGridView.


customersDataGridView.Dock = DockStyle.Top;
this.Controls.Add(customersDataGridView);

this.Size = new Size(400, 200);


}

private void Form3_Load(object sender, EventArgs e)


{
this.Top = 100;
this.Left = 100;
this.Height = 600;
this.Width = 1000;

// Create and populate the list of DemoCustomer objects


// which will supply data to the DataGridView.
BindingList<DemoCustomer1> customerList = new ();
customerList.Add(DemoCustomer1.CreateNewCustomer());
customerList.Add(DemoCustomer1.CreateNewCustomer());
customerList.Add(DemoCustomer1.CreateNewCustomer());

// Bind the list to the BindingSource.


this.customersBindingSource.DataSource = customerList;

// Attach the BindingSource to the DataGridView.


this.customersDataGridView.DataSource =
this.customersBindingSource;
}

// Change the value of the CompanyName property for the first


// item in the list when the "Change Item" button is clicked.
void changeItemBtn_Click(object sender, EventArgs e)
{
// Get a reference to the list from the BindingSource.
BindingList<DemoCustomer1>? customerList =
this.customersBindingSource.DataSource as
BindingList<DemoCustomer1>;

// Change the value of the CompanyName property for the


// first item in the list.
customerList[0].CustomerName = "Tailspin Toys";
customerList[0].PhoneNumber = "(708)555-0150";
}

}
// This is a simple customer class that
// implements the IPropertyChange interface.
public class DemoCustomer1 : INotifyPropertyChanged
{
// These fields hold the values for the public properties.
private Guid idValue = Guid.NewGuid();
private string customerNameValue = String.Empty;
private string phoneNumberValue = String.Empty;

public event PropertyChangedEventHandler PropertyChanged;

// This method is called by the Set accessor of each property.


// The CallerMemberName attribute that is applied to the optional
propertyName
// parameter causes the property name of the caller to be
substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String
propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new
PropertyChangedEventArgs(propertyName));
}
}

// The constructor is private to enforce the factory pattern.


private DemoCustomer1()
{
customerNameValue = "Customer";
phoneNumberValue = "(312)555-0100";
}

// This is the public factory method.


public static DemoCustomer1 CreateNewCustomer()
{
return new DemoCustomer1();
}

// This property represents an ID, suitable


// for use as a primary key in a database.
public Guid ID
{
get
{
return this.idValue;
}
}

public string CustomerName


{
get
{
return this.customerNameValue;
}
set
{
if (value != this.customerNameValue)
{
this.customerNameValue = value;
NotifyPropertyChanged();
}
}
}

public string PhoneNumber


{
get
{
return this.phoneNumberValue;
}

set
{
if (value != this.phoneNumberValue)
{
this.phoneNumberValue = value;
NotifyPropertyChanged();
}
}
}
}
}

Sincronizar associações
Durante a implementação da associação de dados em Windows Forms, vários controles
são associados à mesma fonte de dados. Em alguns casos, pode ser necessário executar
etapas adicionais para garantir que as propriedades associadas dos controles
permaneçam sincronizadas entre si e à fonte de dados. Essas etapas são necessárias em
duas situações:

Se a fonte de dados não implementar IBindingListe, portanto, gerar ListChanged


eventos do tipo ItemChanged.

Se a fonte de dados for implementada IEditableObject.

No primeiro caso, você pode usar um BindingSource para associar a fonte de dados aos
controles. No último caso, você usa um BindingSource evento e manipula o
BindingComplete evento e chama EndCurrentEdit o associado BindingManagerBase.
Para obter mais informações sobre como implementar esse conceito, consulte a página
de referência da API BindingComplete.

Confira também
Associação de dados
BindingSource
INotifyPropertyChanged
BindingList<T>
Navegar pelos dados (Windows Forms
.NET)
Artigo • 08/02/2023 • 6 minutos para o fim da leitura

A maneira mais fácil de navegar pelos registros em uma fonte de dados é associar um
BindingSource componente à fonte de dados e associar controles ao BindingSource . Em
seguida, você pode usar o método de navegação interno do BindingSource , como
MoveNext, e MoveLastMovePreviousMoveFirst. O uso desses métodos ajustará as
propriedades e Current as Position BindingSource propriedades do apropriadamente.
Você também pode encontrar um registro e defini-lo como o registro atual definindo a
Position propriedade.

Para incrementar a posição do registro em uma


fonte de dados
Defina a Position propriedade dos BindingSource dados associados à posição do
registro para ir para a posição de registro necessária. O exemplo a seguir ilustra o
MoveNext uso do método para BindingSource incrementar a Position propriedade
quando você seleciona o nextButton . Ele BindingSource está associado à Customers
tabela de um conjunto Northwind de dados.

C#

private void nextButton_Click(object sender, System.EventArgs e)


{
this.customersBindingSource.MoveNext();
}

7 Observação

Definir a Position propriedade como um valor além do primeiro ou último registro


não resulta em um erro, pois Windows Forms não definirá a posição como um valor
fora dos limites da lista. Se for importante saber se você passou do primeiro ou
último registro, inclua a lógica para testar se você excederá a contagem de
elementos de dados.
Para verificar se você excedeu o primeiro ou o
último registro
Crie um manipulador de eventos para o evento PositionChanged. No manipulador, é
possível testar se o valor da posição proposta excedeu a contagem de elementos de
dados real.

O exemplo a seguir ilustra como você pode testar se você atingiu o último elemento de
dados. No exemplo, se você estiver no último elemento, o botão Próximo do formulário
estará desabilitado.

C#

void customersBindingSource_PositionChanged(object sender, EventArgs e)


{
if (customersBindingSource.Position == customersBindingSource.Count - 1)
nextButton.Enabled = false;
else
nextButton.Enabled = true;
}

7 Observação

Lembre-se de que, se você alterar a lista que está navegando no código, deverá
habilitar novamente o botão Avançar para que os usuários possam navegar por
todo o comprimento da nova lista. Além disso, lembre-se de que o evento acima
PositionChanged para o específico BindingSource com o qual você está
trabalhando precisa ser associado ao método de tratamento de eventos.

Para localizar um registro e defini-lo como o


item atual
Localize o registro que deseja definir como o item atual. Use o Find método do
BindingSource exemplo, conforme mostrado no exemplo, se a fonte de dados
implementar IBindingList. Alguns exemplos de fontes de dados que implementam
IBindingList são BindingList<T> e DataView.

C#

void findButton_Click(object sender, EventArgs e)


{
int foundIndex = customersBindingSource.Find("CustomerID", "ANTON");
customersBindingSource.Position = foundIndex;
}

Para garantir que a linha selecionada em uma


tabela filho permaneça na posição correta
Ao trabalhar com a associação de dados em Windows Forms, você exibirá dados em
uma exibição pai/filho ou mestre/detalhe. É um cenário de associação de dados em que
os dados da mesma fonte são exibidos em dois controles. Alterar a seleção em um
controle faz com que os dados exibidos no segundo controle mudem. Por exemplo, o
primeiro controle pode conter uma lista de clientes e o segundo, uma lista de pedidos
relacionada ao cliente selecionado no primeiro controle.

Ao exibir dados em um modo de exibição pai/filho, talvez seja necessário executar


etapas extras para garantir que a linha atualmente selecionada na tabela filho não seja
redefinida para a primeira linha da tabela. Para fazer isso, você precisará armazenar em
cache a posição da tabela filho e redefini-la depois que a tabela pai for alterada.
Normalmente, a redefinição da tabela filho ocorre na primeira vez em que um campo
em uma linha da tabela pai é alterado.

Para armazenar em cache a posição atual da tabela filho


1. Declare uma variável inteiro para armazenar a posição da tabela filho e uma
variável booliana para armazenar em cache a posição da tabela filho.

C#

private int cachedPosition = -1;


private bool cacheChildPosition = true;

2. Manipule o ListChanged evento para a associação CurrencyManager e verifique se


há um ListChangedType de Reset.

3. Verifique a posição atual do CurrencyManager. Se for maior que a primeira entrada


na lista (normalmente 0), salve-a em uma variável.

C#

void relatedCM_ListChanged(object sender, ListChangedEventArgs e)


{
// Check to see if this is a caching situation.
if (cacheChildPosition && cachePositionCheckBox.Checked)
{
// If so, check to see if it is a reset situation, and the
current
// position is greater than zero.
CurrencyManager relatedCM = sender as CurrencyManager;
if (e.ListChangedType == ListChangedType.Reset &&
relatedCM.Position > 0)

// If so, cache the position of the child table.


cachedPosition = relatedCM.Position;
}
}

4. Manipule o evento da CurrentChanged lista pai para o gerenciador de moedas pai.


No manipulador, defina o valor booliano para indicar que não é um cenário de
cache. Se ocorrer CurrentChanged , a alteração para o pai será uma alteração de
posição de lista e não uma alteração de valor de item.

C#

void bindingSource1_CurrentChanged(object sender, EventArgs e)


{
// If the CurrentChanged event occurs, this is not a caching
// situation.
cacheChildPosition = false;
}

Para redefinir a posição da tabela filho


1. Manipule o PositionChanged evento para a associação da CurrencyManagertabela
filho.

2. Redefina a posição da tabela filho para a posição em cache salva no procedimento


anterior.

C#

void relatedCM_PositionChanged(object sender, EventArgs e)


{
// Check to see if this is a caching situation.
if (cacheChildPosition && cachePositionCheckBox.Checked)
{
CurrencyManager relatedCM = sender as CurrencyManager;

// If so, check to see if the current position is


// not equal to the cached position and the cached
// position is not out of bounds.
if (relatedCM.Position != cachedPosition && cachedPosition
> 0 && cachedPosition < relatedCM.Count)
{
relatedCM.Position = cachedPosition;
cachedPosition = -1;
}
}
}

Para testar o exemplo de código, execute as etapas a seguir:

1. Execute o exemplo.

2. Verifique se a caixa de seleção Cache e redefinição de posição está selecionada.

3. Selecione o botão Limpar campo pai para causar uma alteração em um campo da
tabela pai. Observe que a linha selecionada na tabela filho não é alterada.

4. Feche e execute novamente o exemplo. Você precisa executá-lo novamente


porque o comportamento de redefinição ocorre apenas na primeira alteração na
linha pai.

5. Desmarque a caixa de seleção Cache e redefinir posição .

6. Selecione o botão Limpar campo pai . Observe que a linha selecionada na tabela
filho muda para a primeira linha.

Confira também
Visão geral da vinculação de dados
Fontes de dados compatíveis com Windows Forms
Notificação de alteração na associação de dados do Windows Forms
Como sincronizar vários controles com a mesma fonte de dados
Componente BindingSource
Criar um controle de associação simples
(Windows Forms .NET)
Artigo • 08/02/2023 • 3 minutos para o fim da leitura

Com a associação de dados simples, você pode exibir um único elemento de dados,
como um valor de coluna de uma tabela de conjunto de dados para um controle em um
formulário. Você pode associar de maneira simples qualquer propriedade de um
controle a um valor de dados.

Para associar de maneira simples um controle


1. Conexão a uma fonte de dados.

2. Em Visual Studio, selecione o controle no formulário e exiba a janela Propriedades.

3. Expanda a propriedade DataBindings .

As propriedades associadas são exibidas na propriedade DataBindings . Por


exemplo, na maioria dos controles, a propriedade Text é associada com frequência.

4. Se a propriedade que você deseja associar não for uma das propriedades
comumente associadas, selecione o botão Reticências ( ) na caixa Avançado
para exibir a caixa de diálogo Formatação e Associação Avançada com uma lista
completa de propriedades para esse controle.

5. Selecione a propriedade que você deseja associar e selecione a seta suspensa em


Associação. Uma lista de fontes de dados disponíveis é exibida.

6. Expanda a fonte de dados a que deseja associar até encontrar o elemento de


dados individual desejado. Por exemplo, se você estiver associando a um valor de
coluna em uma tabela de conjunto de dados, expanda o nome do conjunto de
dados e expanda o nome da tabela para exibir nomes de coluna.

7. Selecione o nome de um elemento ao qual associar.

8. Se você estiver trabalhando na caixa de diálogo Formatação e Associação


Avançada , selecione OK para retornar à janela Propriedades .

9. Se você quiser associar mais propriedades do controle, repita as etapas de 3 a 7.

7 Observação
Como os controles de associação simples mostram apenas um único
elemento de dados, é comum incluir a lógica de navegação em um
Formulário Windows com controles de associação simples.

Para criar um controle associado e formatar os


dados exibidos
Com Windows Forms associação de dados, você pode formatar os dados exibidos em
um controle associado a dados usando a caixa de diálogo Formatação e Associação
Avançada.

1. Conexão a uma fonte de dados.

2. Em Visual Studio, selecione o controle no formulário e abra a janela Propriedades.

3. Expanda a propriedade DataBindings e, em seguida, na caixa Avançado , selecione


o botão de reticências ( ) para exibir a caixa de diálogo Formatação e
Associação Avançada , que tem uma lista completa de propriedades para esse
controle.

4. Selecione a propriedade que você deseja associar e selecione a seta de associação


.

Uma lista de fontes de dados disponíveis é exibida.

5. Expanda a fonte de dados à qual você deseja associar a propriedade até encontrar
o único elemento de dados desejado.

Por exemplo, se você estiver associando a um valor de coluna na tabela de um


conjunto de dados, expanda o nome do conjunto de dados e expanda o nome da
tabela para exibir nomes de coluna.

6. Selecione o nome de um elemento ao qual associar.

7. Na caixa Formatar tipo , selecione o formato que você deseja aplicar aos dados
exibidos no controle.

Em todos os casos, você pode especificar o valor exibido no controle se a fonte de


dados contiver DBNull. Caso contrário, as opções variam ligeiramente,
dependendo do tipo de formato selecionado. A tabela a seguir mostra os tipos e
opções de formato.
Tipo de Opção de formatação
formato

Sem Não há opções.


Formatação

Numérico Especifique o número de casas decimais usando o controle


superior/inferior Casas decimais.

Moeda Especifique o número de casas decimais usando o controle de casas


decimais .

Data/Hora Escolha como a data e a hora devem ser exibidas selecionando um dos
itens na caixa de seleção Tipo .

Científico Especifique o número de casas decimais usando o controle de casas


decimais .

Personalizado Especifique uma cadeia de caracteres de formato personalizado.

Para obter mais informações, consulte Tipos de formatação. Nota: As


cadeias de caracteres de formato personalizado não têm a garantia de
fazer uma viagem de ida e volta com êxito entre a fonte de dados e o
controle associado. Em vez disso, manipule o Parse evento ou Format a
associação e aplique a formatação personalizada no código de tratamento
de eventos.

8. Selecione OK para fechar a caixa de diálogo Formatação e Associação Avançada e


retornar à janela Propriedades .

Confira também
Binding
Associação de dados
Validação da entrada do usuário no Windows Forms
Sincronizar vários controles com a
mesma fonte de dados (Windows Forms
.NET)
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

Durante a implementação da associação de dados em Windows Forms, vários controles


são associados à mesma fonte de dados. Nas seguintes situações, é necessário garantir
que as propriedades associadas do controle permaneçam sincronizadas entre si e com a
fonte de dados:

Se a fonte de dados não implementar IBindingListe, portanto, gerar ListChanged


eventos do tipo ItemChanged.

Se a fonte de dados for implementada IEditableObject.

No caso anterior, você pode usar uma BindingSource para associar a fonte de dados aos
controles. No último caso, você usa um BindingSource e manipula o BindingComplete
evento e chama EndCurrentEdit o associado BindingManagerBase.

Exemplo de controles de associação usando


BindingSource
O exemplo de código a seguir demonstra como associar três controles, dois controles
de caixa de texto e um DataGridView controle à mesma coluna em um DataSet
componente.BindingSource O exemplo demonstra como lidar com o BindingComplete
evento. Ele garante que, quando o valor de texto de uma caixa de texto for alterado, a
outra caixa de texto e o DataGridView controle sejam atualizados com o valor correto.

O exemplo usa um BindingSource para associar a fonte de dados e os controles. Como


alternativa, você pode associar os controles diretamente à fonte de dados e recuperar o
BindingManagerBase para a associação do BindingContext formulário e, em seguida,
manipular o BindingComplete evento para o BindingManagerBase . Para obter mais
informações sobre como associar a fonte de dados e os controles, consulte a página de
ajuda sobre o BindingComplete evento de BindingManagerBase .

C#

public Form1()
{
InitializeComponent();
set1.Tables.Add("Menu");
set1.Tables[0].Columns.Add("Beverages");

// Add some rows to the table.


set1.Tables[0].Rows.Add("coffee");
set1.Tables[0].Rows.Add("tea");
set1.Tables[0].Rows.Add("hot chocolate");
set1.Tables[0].Rows.Add("milk");
set1.Tables[0].Rows.Add("orange juice");

// Set the data source to the DataSet.


bindingSource1.DataSource = set1;

//Set the DataMember to the Menu table.


bindingSource1.DataMember = "Menu";

// Add the control data bindings.


dataGridView1.DataSource = bindingSource1;
textBox1.DataBindings.Add("Text", bindingSource1,
"Beverages", true, DataSourceUpdateMode.OnPropertyChanged);
textBox2.DataBindings.Add("Text", bindingSource1,
"Beverages", true, DataSourceUpdateMode.OnPropertyChanged);
bindingSource1.BindingComplete +=
new BindingCompleteEventHandler(bindingSource1_BindingComplete);
}

void bindingSource1_BindingComplete(object sender, BindingCompleteEventArgs


e)
{
// Check if the data source has been updated, and that no error has
occurred.
if (e.BindingCompleteContext ==
BindingCompleteContext.DataSourceUpdate && e.Exception == null)

// If not, end the current edit.


e.Binding.BindingManagerBase.EndCurrentEdit();
}

Confira também
Criar ótimas fontes de dados com notificação de alteração
Associação de dados
Como: Compartilhar dados associados entre formulários usando o componente
BindingSource
Recursos de Windows Forms obsoletos
no .NET 7+
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

A partir do .NET 7, algumas APIs Windows Forms são marcadas como obsoletas (ou
produzem um aviso) com IDs de diagnóstico personalizadas do formato WFDEVXXX .

Se você encontrar avisos ou erros de compilação devido ao uso de uma API obsoleta,
siga as orientações específicas fornecidas para o ID de diagnóstico listado na seção
Referência. Avisos ou erros para essas obsoletas não podem ser suprimidos usando o ID
de diagnóstico padrão (CS0618) para tipos ou membros obsoletos; em vez disso, use os
valores de ID de diagnóstico WFDEVXXX personalizados. Para obter mais informações,
consulte Suprimir avisos.

Referência
A tabela a seguir fornece um índice para as WFDEVXXX obsoletões e avisos no .NET 7+.

ID do Aviso ou Descrição
diagnóstico erro

WFDEV001 Aviso A conversão de/para IntPtr não é segura. Use WParamInternal ,


LParamInternal ou ResultInternal em seu lugar.

WFDEV002 Aviso/erro System.Windows.Forms.DomainUpDown.DomainUpDownAccessibleObject


não é mais usado para dar suporte acessível para controles
DomainUpDown. Use AccessibleObject em vez disso.

WFDEV003 Aviso System.Windows.Forms.DomainUpDown.DomainItemAccessibleObject


não é mais usado para dar suporte acessível para itens DomainUpDown.
Use AccessibleObject em vez disso.

Suprimir avisos
É recomendável usar uma solução alternativa disponível sempre que possível. No
entanto, se você não puder alterar seu código, poderá suprimir os avisos por meio de
uma diretiva #pragma ou de uma configuração de projeto <NoWarn> . Se você precisar
usar as APIs obsoletas e o diagnóstico WFDEVXXX não aparecer como um erro, você
poderá suprimir o aviso no código ou no arquivo de projeto.

Para suprimir os avisos no código, faça o seguinte:


C#

// Disable the warning.


#pragma warning disable WFDEV001

// Code that uses obsolete API.


//...

// Re-enable the warning.


#pragma warning restore WFDEV001

Para suprimir os avisos em um arquivo de projeto, faça o seguinte:

XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!-- NoWarn below suppresses WFDEV001 project-wide -->
<NoWarn>$(NoWarn);WFDEV001</NoWarn>
<!-- To suppress multiple warnings, you can use multiple NoWarn elements
-->
<NoWarn>$(NoWarn);WFDEV001</NoWarn>
<NoWarn>$(NoWarn);WFDEV003</NoWarn>
<!-- Alternatively, you can suppress multiple warnings by using a
semicolon-delimited list -->
<NoWarn>$(NoWarn);WFDEV001;WFDEV003</NoWarn>
</PropertyGroup>
</Project>

7 Observação

A supressão de avisos dessa maneira desativa apenas os avisos de obsolescência


que você especificar. Ele não desabilita nenhum outro aviso, incluindo avisos de
obsolescência com diferentes IDs de diagnóstico.

Confira também
Recursos obsoletos do .NET no .NET 5+
WFDEV001: WParam, LParam e
Message.Result estão obsoletos
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

Para reduzir o risco de exceções de conversão e estouro associadas IntPtr em diferentes


plataformas, o SDK Windows Forms não permite o uso direto de Message.WParam,
Message.LParame Message.Result. Projetos que usam o DEBUG build do SDK do
Windows Forms e essa referênciaWParamLParam, ou Result que não serão compilados
devido ao aviso WFDEV001 .

Soluções Alternativas
Atualize seu código para usar as novas propriedades internas
WParamInternal LParamInternal ResultInternal ou dependendo da situação.

Suprimir um aviso
Se for necessário usar as APIs obsoletas, você poderá suprimir o aviso no código ou no
arquivo de projeto.

Para suprimir apenas uma violação única, adicione as diretivas de pré-processador ao


arquivo de origem para desabilitar e, em seguida, reabilite o aviso.

C#

// Disable the warning.


#pragma warning disable WFDEV001

// Code that uses obsolete API.


// ...

// Re-enable the warning.


#pragma warning restore WFDEV001

Para suprimir todos os avisos WFDEV001 no projeto, adicione uma propriedade <NoWarn>
ao arquivo de projeto.

XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);WFDEV001</NoWarn>
</PropertyGroup>
</Project>

Para obter mais informações, confira Suprimir avisos.


WFDEV002:
DomainUpDownAccessibleObject não
deve ser usado
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

Qualquer referência a
System.Windows.Forms.DomainUpDown.DomainUpDownAccessibleObject resultará em
aviso WFDEV002 . Esse aviso indica que DomainUpDown.DomainUpDownAccessibleObject
não é mais usado para fornecer suporte acessível para DomainUpDown controles. O
DomainUpDown.DomainUpDownAccessibleObject tipo nunca foi destinado ao uso
público.

7 Observação

Esse aviso foi promovido a um erro a partir do .NET 8 e você não pode mais
suprimir o erro. Para obter mais informações, consulte A obsoletão WFDEV002
agora é um erro.

Soluções Alternativas
Atualize seu código para usar AccessibleObject em vez de
DomainUpDown.DomainUpDownAccessibleObject.
Se você estiver usando o .NET 7, poderá suprimir o aviso e seu código continuará a
ser compilado e executado.

Suprimir um aviso (somente .NET 7)


Se você precisar usar a API obsoleta, poderá suprimir o aviso no código ou no arquivo
de projeto.

Para suprimir apenas uma violação única, adicione as diretivas de pré-processador ao


arquivo de origem para desabilitar e, em seguida, reabilite o aviso.

C#

// Disable the warning.


#pragma warning disable WFDEV002

// Code that uses obsolete API.


// ...

// Re-enable the warning.


#pragma warning restore WFDEV002

Para suprimir todos os avisos WFDEV002 no projeto, adicione uma propriedade <NoWarn>
ao arquivo de projeto.

XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);WFDEV002</NoWarn>
</PropertyGroup>
</Project>

Para obter mais informações, confira Suprimir avisos.


WFDEV003:
DomainItemAccessibleObject não deve
ser usado
Artigo • 08/02/2023 • 2 minutos para o fim da leitura

Qualquer referência resultará


System.Windows.Forms.DomainUpDown.DomainItemAccessibleObject em aviso
WFDEV003 . Esse aviso indica que DomainUpDown.DomainItemAccessibleObject não é

mais usado para fornecer suporte acessível para itens em DomainUpDown controles.
Esse tipo nunca foi destinado a uso público.

Anteriormente, objetos desse tipo eram servidos a ferramentas de acessibilidade que


navegavam na hierarquia de um DomainUpDown controle. No .NET 7 e versões
posteriores, instâncias do tipo AccessibleObject são usadas para representar itens em
um DomainUpDown controle para ferramentas de acessibilidade.

Soluções Alternativas
Remova invocações do construtor público para o
DomainUpDown.DomainItemAccessibleObject tipo. Use
System.Windows.Forms.AccessibleObject em vez disso.

Suprimir um aviso
Se for necessário usar as APIs obsoletas, você poderá suprimir o aviso no código ou no
arquivo de projeto.

Para suprimir apenas uma violação única, adicione as diretivas de pré-processador ao


arquivo de origem para desabilitar e, em seguida, reabilite o aviso.

C#

// Disable the warning.


#pragma warning disable WFDEV003

// Code that uses obsolete API.


// ...

// Re-enable the warning.


#pragma warning restore WFDEV003
Para suprimir todos os avisos WFDEV003 no projeto, adicione uma propriedade <NoWarn>
ao arquivo de projeto.

XML

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
...
<NoWarn>$(NoWarn);WFDEV003</NoWarn>
</PropertyGroup>
</Project>

Para obter mais informações, confira Suprimir avisos.

You might also like