Windows Form PDF
Windows Form PDF
Windows Form PDF
Windows Forms
Getting Started with Windows Forms
Windows Forms Overview
Creating a New Windows Form
How to: Create a Windows Forms Application from the Command Line
Windows Forms Coordinates
Creating Event Handlers in Windows Forms
Events Overview
Event Handlers Overview
How to: Create Event Handlers at Run Time for Windows Forms
How to: Connect Multiple Events to a Single Event Handler in Windows Forms
Order of Events in Windows Forms
Adjusting the Size and Scale of Windows Forms
How to: Resize Windows Forms
Automatic Scaling in Windows Forms
How to: Respond to Font Scheme Changes in a Windows Forms Application
Disable DPI Awareness in Visual Studio
High DPI Support In Windows Forms
Changing the Appearance of Windows Forms
How to: Change the Borders of Windows Forms
Windows Forms Controls
User Input in Windows Forms
User Input in a Windows Forms Application
Keyboard Input in a Windows Forms Application
How Keyboard Input Works
Using Keyboard Events
How to: Modify Keyboard Input to a Standard Control
How to: Determine Which Modifier Key Was Pressed
How to: Handle Keyboard Input at the Form Level
Mouse Input in a Windows Forms Application
How Mouse Input Works in Windows Forms
Mouse Events in Windows Forms
How to: Distinguish Between Clicks and Double-Clicks
Mouse Pointers in Windows Forms
Mouse Capture in Windows Forms
Drag-and-Drop Functionality in Windows Forms
How to: Simulate Mouse and Keyboard Events in Code
How to: Handle User Input Events in Windows Forms Controls
User Input Validation in Windows Forms
Dialog Boxes in Windows Forms
How to: Display Dialog Boxes for Windows Forms
Windows Forms Data Binding
Data Binding and Windows Forms
Data Sources Supported by Windows Forms
Interfaces Related to Data Binding
Change Notification in Windows Forms Data Binding
How to: Apply the PropertyNameChanged Pattern
How to: Create a Bound Control and Format the Displayed Data
How to: Create a Simple-Bound Control on a Windows Form
How to: Ensure Multiple Controls Bound to the Same Data Source Remain
Synchronized
How to: Ensure the Selected Row in a Child Table Remains at the Correct Position
How to: Implement the IListSource Interface
How to: Implement the INotifyPropertyChanged Interface
How to: Implement the ITypedList Interface
How to: Navigate Data in Windows Forms
Windows Forms Security
Security in Windows Forms Overview
More Secure File and Data Access in Windows Forms
More Secure Printing in Windows Forms
Additional Security Considerations in Windows Forms
ClickOnce Deployment for Windows Forms
How to: Access Keyed Collections in Windows Forms
Enhancing Windows Forms Applications
Windows Forms
3/9/2019 • 2 minutes to read • Edit Online
As forms are the base unit of your application, it is essential that you give some thought to their function and
design. A form is ultimately a blank slate that you, as a developer, enhance with controls to create a user interface
and with code to manipulate data. To that end, Visual Studio provides you with an integrated development
environment (IDE ) to aid in writing code, as well as a rich control set written with the .NET Framework. By
complementing the functionality of these controls with your code, you can easily and quickly develop the solutions
you need.
In This Section
Getting Started with Windows Forms
Provides links to topics about how to harness the power of Windows Forms to display data, handle user input, and
deploy your applications easily and with more robust security.
Enhancing Windows Forms Applications
Provides links to topics about how to enhance your Windows Forms with a variety of features.
Related Sections
Windows Forms Controls
Contains links to topics that describe Windows Forms controls and show how to implement them.
Windows Forms Data Binding
Contains links to topics that describe the Windows Forms data-binding architecture.
Graphics Overview
Discusses how to create graphics, draw text, and manipulate graphical images as objects using the advanced
implementation of the Windows graphics design interface.
ClickOnce Security and Deployment
Discusses the principles of ClickOnce deployment.
Windows Forms/MFC Programming Differences
Discusses the differences between MFC applications and Windows Forms.
Accessing data in Visual Studio
Discusses incorporating data access functionality into your applications.
Windows Forms Applications
Discusses the process of debugging applications created with the Windows Application project template, as well as
how to change the Debug and Release configurations.
First look at deployment in Visual Studio
Describes the process by which you distribute a finished application or component to be installed on other
computers.
Building Console Applications
Describes the basics of creating a console application using the Console class.
Getting Started with Windows Forms
3/9/2019 • 2 minutes to read • Edit Online
With Windows Forms, you can create powerful Windows-based applications. The following topics describe in-
depth how to harness the power of Windows Forms to display data, handle user input, and deploy your
applications easily and with enhanced security.
In This Section
Windows Forms Overview
Contains an overview of Windows Forms and smart client applications.
Creating a New Windows Form
Contains links to topics that describe basic concepts for creating Windows Forms applications.
Creating Event Handlers in Windows Forms
Contains links to topics that describe how to create Windows Forms event handlers.
Adjusting the Size and Scale of Windows Forms
Contains links to topics that show how to adjust the size and scale of Windows Forms.
Changing the Appearance of Windows Forms
Contains links to topics that show how to change the appearance of Windows Forms applications.
Windows Forms Controls
Contains links to topics that describe and show how to use Windows Forms controls and components.
User Input in Windows Forms
Contains links to topics that describe and show how to handle input from the user in Windows Forms applications.
Dialog Boxes in Windows Forms
Contains links to topics that describe the different dialog boxes for use in Windows Forms.
Windows Forms Data Binding
Contains links to topics that describe the Windows Forms data binding architecture and how to use it in Windows
Forms applications.
Windows Forms Security
Contains links to topics that describe how to build Windows Forms applications that have enhanced security.
ClickOnce Deployment for Windows Forms
Contains links to topics that describe how to easily deploy Windows Forms applications.
How to: Access Keyed Collections in Windows Forms
Demonstrates how to access collections with keys rather than indexes.
Related Sections
Enhancing Windows Forms Applications
Contains links to topics that describe more advanced concepts for creating Windows Forms applications.
Windows Forms overview
5/7/2019 • 7 minutes to read • Edit Online
The following overview discusses the advantages of smart client applications, the main features of Windows
Forms programming, and how you can use Windows Forms to build smart clients that meet the needs of today's
enterprises and end users.
Using the ToolStrip Control How to: Create a Basic ToolStrip with Standard Items Using
the Designer
Creating custom controls How to: Inherit from the UserControl Class
Using the BindingSource component How to: Bind Windows Forms Controls with the BindingSource
Component Using the Designer
DESCRIPTION HELP TOPIC
Working with ADO.NET data sources How to: Sort and Filter ADO.NET Data with the Windows
Forms BindingSource Component
Using the Data Sources window Bind Windows Forms controls to data in Visual Studio
Deploying an application by using ClickOnce How to: Publish a ClickOnce Application using the Publish
Wizard
Updating a ClickOnce deployment How to: Manage Updates for a ClickOnce Application
Managing security with ClickOnce How to: Enable ClickOnce Security Settings
Printing the contents of a form How to: Print Graphics in Windows Forms
Learn more about Windows Forms security Security in Windows Forms Overview
See also
Getting Started with Windows Forms
Creating a New Windows Form
ToolStrip Control Overview
DataGridView Control Overview
BindingSource Component Overview
Application Settings Overview
ClickOnce Security and Deployment
Creating a New Windows Form
3/9/2019 • 2 minutes to read • Edit Online
This topic contains links to topics that describe how to create your first Windows Forms application. Also, the
topics in this section introduce some of the basic vocabulary and guidelines that you should understand when you
start to create a Windows Forms application. To learn more about Windows Forms applications, the controls you
can use on them, events and handling events, and how to handle input from the user, see the related topic list.
In This Section
Windows Forms Coordinates.
Describes client and screen coordinates.
How to: Create a Windows Forms Application from the Command Line
Describes how to create a basic Windows Form and compile it from the command line.
Reference
Form
Describes this class and contains links to all its members.
Control
Describes this class and contains links to all its members.
Related Sections
Handling User Input
Contains links to topics that discuss user input and how to handle it in Windows Forms applications.
Creating Event Handlers in Windows Forms
Contains links to topics that describe how to handle events in Windows Forms applications.
Changing the Appearance of Windows Forms
Contains links to topics that show how to change the appearance of Windows Forms applications.
Windows Forms Controls by Function
Contains links to topics that describe the controls you can use in Windows Forms applications.
How to: Create a Windows Forms application from
the command line
4/28/2019 • 3 minutes to read • Edit Online
The following procedures describe the basic steps that you must complete to create and run a Windows Forms
application from the command line. There is extensive support for these procedures in Visual Studio. Also see
Walkthrough: Hosting a Windows Forms Control in WPF.
Procedure
To create the form
1. In an empty code file, type the following import or using statements:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
2. Declare a class named Form1 that inherits from the Form class.
public Form1() {}
End Sub
End Class
-or-
End Sub
Example
Following code example is the complete example from the previous procedures.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace FormWithButton
{
public class Form1 : Form
{
public Button button1;
public Form1()
{
button1 = new Button();
button1.Size = new Size(40, 40);
button1.Location = new Point(30, 30);
button1.Text = "Click me";
this.Controls.Add(button1);
button1.Click += new EventHandler(button1_Click);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello World");
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
}
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
End Sub
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
End Class
Compiling the Code
To compile the code, follow the instructions in the proceeding procedure that describe how to compile and run
the application.
See also
Form
Control
Changing the Appearance of Windows Forms
Enhancing Windows Forms Applications
Getting Started with Windows Forms
Windows Forms Coordinates
4/8/2019 • 2 minutes to read • Edit Online
The coordinate system for a Windows Form is based on device coordinates, and the basic unit of measure when
drawing in Windows Forms is the device unit (typically, the pixel). Points on the screen are described by x- and y-
coordinate pairs, with the x-coordinates increasing to the right and the y-coordinates increasing from top to
bottom. The location of the origin, relative to the screen, will vary depending on whether you are specifying screen
or client coordinates.
Screen Coordinates
A Windows Forms application specifies the position of a window on the screen in screen coordinates. For screen
coordinates, the origin is the upper-left corner of the screen. The full position of a window is often described by a
Rectangle structure containing the screen coordinates of two points that define the upper-left and lower-right
corners of the window.
Client Coordinates
A Windows Forms application specifies the position of points in a form or control using client coordinates. The
origin for client coordinates is the upper-left corner of the client area of the control or form. Client coordinates
ensure that an application can use consistent coordinate values while drawing in a form or control, regardless of
the position of the form or control on the screen.
The dimensions of the client area are also described by a Rectangle structure that contains client coordinates for
the area. In all cases, the upper-left coordinate of the rectangle is included in the client area, while the lower-right
coordinate is excluded. Graphics operations do not include the right and lower edges of a client area. For example
the FillRectangle method will fill up to the right and lower edge of the specified rectangle, but will not include these
edges.
See also
PointToClient
PointToScreen
Creating Event Handlers in Windows Forms
5/7/2019 • 2 minutes to read • Edit Online
An event handler is a procedure in your code that determines what actions are performed when an event occurs,
such as when the user clicks a button or a message queue receives a message. When an event is raised, the event
handler or handlers that receive the event are executed. Events can be assigned to multiple handlers, and the
methods that handle particular events can be changed dynamically. You can also use the Windows Forms
Designer in Visual Studio to create event handlers.
In This Section
Events Overview
Explains the event model and the role of delegates.
Event Handlers Overview
Describes how to handle events.
How to: Create Event Handlers at Run Time for Windows Forms
Gives directions for responding to system or user events dynamically.
How to: Connect Multiple Events to a Single Event Handler in Windows Forms
Gives directions for assigning the same functionality to multiple controls through events.
Order of Events in Windows Forms
Describes the order in which events are raised in Windows Forms controls.
How to: Create Event Handlers Using the Designer Describes how to use the Windows Forms Designer to create
event handlers.
Related Sections
Events
Provides links to topics on handling and raising events using the .NET Framework].
Troubleshooting Inherited Event Handlers in Visual Basic
Lists common issues that occur with event handlers in inherited components.
Events Overview (Windows Forms)
5/7/2019 • 2 minutes to read • Edit Online
An event is an action which you can respond to, or "handle," in code. Events can be generated by a user action,
such as clicking the mouse or pressing a key; by program code; or by the system.
Event-driven applications execute code in response to an event. Each form and control exposes a predefined set of
events that you can program against. If one of these events occurs and there is code in the associated event
handler, that code is invoked.
The types of events raised by an object vary, but many types are common to most controls. For example, most
objects will handle a Click event. If a user clicks a form, code in the form's Click event handler is executed.
NOTE
Many events occur in conjunction with other events. For example, in the course of the DoubleClick event occurring, the
MouseDown, MouseUp, and Click events occur.
For information about how to raise and consume an event, see Events.
See also
Creating Event Handlers in Windows Forms
Event Handlers Overview
Event Handlers Overview (Windows Forms)
4/8/2019 • 2 minutes to read • Edit Online
An event handler is a method that is bound to an event. When the event is raised, the code within the event
handler is executed. Each event handler provides two parameters that allow you to handle the event properly. The
following example shows an event handler for a Button control's Click event.
End Sub
private:
void button1_Click(System::Object ^ sender,
System::EventArgs ^ e)
{
The first parameter, sender , provides a reference to the object that raised the event. The second parameter, e , in
the example above, passes an object specific to the event that is being handled. By referencing the object's
properties (and, sometimes, its methods), you can obtain information such as the location of the mouse for mouse
events or data being transferred in drag-and-drop events.
Typically each event produces an event handler with a different event-object type for the second parameter. Some
event handlers, such as those for the MouseDown and MouseUp events, have the same object type for their
second parameter. For these types of events, you can use the same event handler to handle both events.
You can also use the same event handler to handle the same event for different controls. For example, if you have
a group of RadioButton controls on a form, you could create a single event handler for the Click event and have
each control's Click event bound to the single event handler. For more information, see How to: Connect Multiple
Events to a Single Event Handler in Windows Forms.
See also
Creating Event Handlers in Windows Forms
Events Overview
How to: Create Event Handlers at Run Time for
Windows Forms
5/7/2019 • 2 minutes to read • Edit Online
In addition to creating events using the Windows Forms Designer in Visual Studio, you can also create an event
handler at run time. This action allows you to connect event handlers based on conditions in code at run time as
opposed to having them connected when the program initially starts.
private:
void button1_Click(System::Object ^ sender,
System::EventArgs ^ e)
{
// Add event handler code here.
}
The AddHandler method demonstrated in the Visual Basic code above establishes a click event handler for
the button.
See also
Creating Event Handlers in Windows Forms
Event Handlers Overview
Troubleshooting Inherited Event Handlers in Visual Basic
How to: Connect Multiple Events to a Single Event
Handler in Windows Forms
4/9/2019 • 2 minutes to read • Edit Online
In your application design, you may find it necessary to use a single event handler for multiple events or have
multiple events perform the same procedure. For example, it is often a powerful time-saver to have a menu
command raise the same event as a button on your form does if they expose the same functionality. You can do
this by using the Events view of the Properties window in C# or using the Handles keyword and the Class Name
and Method Name drop-down boxes in the Visual Basic Code Editor.
To connect multiple events to a single event handler in Visual Basic
1. Right-click the form and choose View Code.
2. From the Class Name drop-down box, select one of the controls that you want to have the event handler
handle.
3. From the Method Name drop-down box, select one of the events that you want the event handler to
handle.
4. The Code Editor inserts the appropriate event handler and positions the insertion point within the method.
In the example below, it is the Click event for the Button control.
5. Append the other events you would like handled to the Handles clause.
See also
Creating Event Handlers in Windows Forms
Event Handlers Overview
Order of Events in Windows Forms
4/28/2019 • 2 minutes to read • Edit Online
The order in which events are raised in Windows Forms applications is of particular interest to developers
concerned with handling each of these events in turn. When a situation calls for meticulous handling of events,
such as when you are redrawing parts of the form, an awareness of the precise order in which events are raised at
run time is necessary. This topic provides some details on the order of events during several important stages in
the lifetime of applications and controls. For specific details about the order of mouse input events, see Mouse
Events in Windows Forms. For an overview of events in Windows Forms, see Events Overview. For details about
the makeup of event handlers, see Event Handlers Overview.
NOTE
Visual Basic 2005 includes additional application events, such as WindowsFormsApplicationBase.Startup and
WindowsFormsApplicationBase.Shutdown.
See also
Creating Event Handlers in Windows Forms
Adjusting the size and scale of Windows Forms
3/9/2019 • 2 minutes to read • Edit Online
In This Section
How to: Resize Windows Forms
Provides instructions for specifying the size of Windows Forms.
Automatic Scaling in Windows Forms
Discusses how automatic scaling enables a form and its controls to be displayed appropriately between machines.
High DPI Support in Windows Forms
Discusses Windows Forms' support for High DPI and dynamic scaling.
Reference
Size
Describes this class and has links to all of its members.
TableLayoutPanel
Describes this class and has links to all of its members.
FlowLayoutPanel
Describes this class and has links to all of its members.
Related sections
Changing the appearance of Windows Forms
Provides links to topics describing other ways to change the appearance of Windows Forms.
How to: Resize Windows Forms
5/7/2019 • 2 minutes to read • Edit Online
You can specify the size of your Windows Form in several ways. You can change both the height and the width of
the form programmatically by setting a new value for the Size property, or adjust the Height or Width properties
individually. If you're using Visual Studio, you can change the size using the Windows Forms Designer. Also see
How to: Resize Windows Forms Using the Designer.
Form1.Width = 300
Form1.Width = 300;
Form1->Width = 300;
-or-
Change Width or Height by setting the Size property.
However, as the following code example shows, this approach is more cumbersome than just setting Width or
Height properties.
Form1.Width += 200
Form1.Width += 200;
Form1->Width += 200;
Cau t i on
Always use the Height or Width property to change a dimension of a form, unless you are setting both height and
width dimensions at the same time by setting the Size property to a new Size structure. The Size property returns
a Size structure, which is a value type. You cannot assign a new value to the property of a value type. Therefore, the
following code example will not compile.
See also
Getting Started with Windows Forms
Enhancing Windows Forms Applications
Automatic scaling in Windows Forms
8/14/2018 • 6 minutes to read • Edit Online
Automatic scaling enables a form and its controls, designed on one machine with a certain display resolution or
system font, to be displayed appropriately on another machine with a different display resolution or system font. It
assures that the form and its controls will intelligently resize to be consistent with native windows and other
applications on both the users' and other developers' machines. The support of the .NET Framework for automatic
scaling and visual styles enables .NET Framework applications to maintain a consistent look and feel when
compared to native Windows applications on each user's machine.
For the most part, automatic scaling works as expected in .NET Framework version 2.0 and later. However, font
scheme changes can be problematic. For an example of how to resolve this, see How to: Respond to Font Scheme
Changes in a Windows Forms Application.
NOTE
You can safely delete references to these members when you upgrade your legacy code to the .NET Framework version 2.0.
Arbitrary mixtures of DPI and font scaling modes are not supported. Although you may scale a user control using
one mode (for example, DPI) and place it on a form using another mode (Font) with no issues, but mixing a base
form in one mode and a derived form in another can lead to unexpected results.
Automatic scaling in action
Windows Forms now uses the following logic to automatically scale forms and their contents:
1. At design time, each ContainerControl records the scaling mode and it current resolution in the
AutoScaleMode and AutoScaleDimensions, respectively.
2. At run time, the actual resolution is stored in the CurrentAutoScaleDimensions property. The
AutoScaleFactor property dynamically calculates the ratio between the run-time and design-time scaling
resolution.
3. When the form loads, if the values of CurrentAutoScaleDimensions and AutoScaleDimensions are
different, then the PerformAutoScale method is called to scale the control and its children. This method
suspends layout and calls the Scale method to perform the actual scaling. Afterwards, the value of
AutoScaleDimensions is updated to avoid progressive scaling.
4. PerformAutoScale is also automatically invoked in the following situations:
In response to the OnFontChanged event if the scaling mode is Font.
When the layout of the container control resumes and a change is detected in the
AutoScaleDimensions or AutoScaleMode properties.
As implied above, when a parent ContainerControl is being scaled. Each container control is
responsible for scaling its children using its own scaling factors and not the one from its parent
container.
5. Child controls can modify their scaling behavior through several means:
The ScaleChildren property can be overridden to determine if their child controls should be scaled or
not.
The GetScaledBounds method can be overridden to adjust the bounds that the control is scaled to,
but not the scaling logic.
The ScaleControl method can be overridden to change the scaling logic for the current control.
See also
AutoScaleMode
Scale
PerformAutoScale
AutoScaleDimensions
Rendering Controls with Visual Styles
How to: Improve Performance by Avoiding Automatic Scaling
How to: Respond to Font Scheme Changes in a
Windows Forms Application
4/9/2019 • 3 minutes to read • Edit Online
In the Windows operating systems, a user can change the system-wide font settings to make the default font
appear larger or smaller. Changing these font settings is critical for users who are visually impaired and require
larger type to read the text on their screens. You can adjust your Windows Forms application to react to these
changes by increasing or decreasing the size of the form and all contained text whenever the font scheme changes.
If you want your form to accommodate changes in font sizes dynamically, you can add code to your form.
Typically, the default font used by Windows Forms is the font returned by the Microsoft.Win32 namespace call to
GetStockObject(DEFAULT_GUI_FONT) . The font returned by this call only changes when the screen resolution changes.
As shown in the following procedure, your code must change the default font to IconTitleFont to respond to
changes in font size.
To use the desktop font and respond to font scheme changes
1. Create your form, and add the controls you want to it. For more information, see How to: Create a Windows
Forms Application from the Command Line and Controls to Use on Windows Forms.
2. Add a reference to the Microsoft.Win32 namespace to your code.
using Microsoft.Win32;
Imports Microsoft.Win32
3. Add the following code to the constructor of your form to hook up required event handlers, and to change
the default font in use for the form.
this.Font = SystemFonts.IconTitleFont;
SystemEvents.UserPreferenceChanged += new
UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
4. Implement a handler for the UserPreferenceChanged event that causes the form to scale automatically
when the Window category changes.
void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (e.Category == UserPreferenceCategory.Window)
{
this.Font = SystemFonts.IconTitleFont;
}
}
5. Finally, implement a handler for the FormClosing event that detaches the UserPreferenceChanged event
handler.
IMPORTANT
Failure to include this code will cause your application to leak memory.
Example
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
namespace WinFormsAutoScaling
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Font = SystemFonts.IconTitleFont;
SystemEvents.UserPreferenceChanged += new
UserPreferenceChangedEventHandler(SystemEvents_UserPreferenceChanged);
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
}
Imports Microsoft.Win32
See also
PerformAutoScale
Automatic Scaling in Windows Forms
Disable DPI-awareness in Visual Studio
4/8/2019 • 4 minutes to read • Edit Online
Visual Studio is a dots per inch (DPI) aware application, which means the display scales automatically. If an
application states that it's not DPI-aware, the operating system scales the application as a bitmap. This behavior is
also called DPI virtualization. The application still thinks that it's running at 100% scaling, or 96 dpi.
This article discusses the limitations of Windows Forms Designer on HDPI monitors and how to run Visual Studio
as a DPI-unaware process.
When you open a form in the Windows Forms Designer in Visual Studio on an HDPI monitor, Visual Studio
displays a yellow informational bar at the top of the designer:
The message reads Scaling on your main display is set to 200% (192 dpi). This might cause rendering
problems in the designer window.
NOTE
This informational bar was introduced in Visual Studio 2017 version 15.8.
If you aren't working in the designer and don't need to adjust the layout of your form, you can ignore the
informational bar and continue working in the code editor or in other types of designers. (You can also disable
notifications so that the informational bar doesn't continue to appear.) Only the Windows Forms Designer is
affected. If you do need to work in the Windows Forms Designer, the next section helps you resolve the problem.
NOTE
If you had undocked tool windows in Visual Studio when you selected the option to restart as a DPI-unaware process, the
position of those tool windows may change.
If you use the default Visual Basic profile, or if you have the Save new projects when created option deselected in Tools
> Options > Projects and Solutions, Visual Studio cannot reopen your project when it restarts as a DPI-unaware
process. However, you can open the project by selecting it under File > Recent Projects and Solutions.
It's important to restart Visual Studio as a DPI-aware process when you're finished working in the Windows
Forms Designer. When it's running as a DPI-unaware process, fonts can look blurry and you may see issues in
other designers such as the XAML Designer. If you close and reopen Visual Studio when it's running in DPI-
unaware mode, it becomes DPI-aware again. You can also click the Restart Visual Studio as a DPI -aware
process option in the informational bar.
Add a registry entry
You can mark Visual Studio as DPI-unaware by modifying the registry. Open Registry Editor and add an entry to
the HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\AppCompatFlags\Layers subkey:
Entry: Depending on whether you're using Visual Studio 2017 or 2019, use one of these values:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exe
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe
NOTE
If you're using the Professional or Enterprise edition of Visual Studio, replace Community with Professional or Enterprise in
the entry. Also replace the drive letter as necessary.
Type: REG_SZ
Value: DPIUNAWARE
NOTE
Visual Studio remains in DPI-unaware mode until you remove the registry entry.
Disable notifications
You can choose not to be notified of DPI scaling issues in Visual Studio. You might want to disable notifications if
you aren't working in the designer, for example.
To disable notifications, choose Tools > Options to open the Options dialog. Then, choose Windows Forms
Designer > General, and set DPI Scaling Notifications to False.
If you want to later reenable scaling notifications, set the property to True.
Troubleshoot
If the DPI-awareness transition isn't working as expected in Visual Studio, check to see if you have the
dpiAwareness value in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Image File Execution Options\devenv.exe subkey in Registry Editor. Delete the value if
it's present.
See also
Automatic scaling in Windows Forms
High DPI support in Windows Forms
3/14/2019 • 3 minutes to read • Edit Online
Starting with the .NET Framework 4.7, Windows Forms includes enhancements for common high DPI and
dynamic DPI scenarios. These include:
Improvements in the scaling and layout of a number of Windows Forms controls, such as the
MonthCalendar control and the CheckedListBox control.
Single-pass scaling. In the .NET Framework 4.6 and earlier versions, scaling was performed through
multiple passes, which caused some controls to be scaled more than was necessary.
Support for dynamic DPI scenarios in which the user changes the DPI or scale factor after a Windows
Forms application has been launched.
In versions of the .NET Framework starting with the .NET Framework 4.7, enhanced high DPI support is an opt-in
feature. You must configure your application to take advantage of it.
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 compatibility -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
IMPORTANT
In previous versions of the .NET Framework, you used the manifest to add high DPI support. This approach is no
longer recommended, since it overrides settings defined on the app.config file.
Call the static EnableVisualStyles method.
This should be the first method call in your application entry point. For example:
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
<add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
</System.Windows.Forms.ApplicationConfigurationSection>
For a list of individual keys and their values, see Windows Forms Add Configuration Element.
Versioning considerations
In addition to running on .NET Framework 4.7 and Windows 10 Creators Update, your application may also run in
an environment in which it isn't compatible with high DPI improvements. In this case, you'll need to develop a
fallback for your application. You can do this to perform custom drawing to handle scaling.
To do this, you also need to determine the operating system on which your app is running. You can do that with
code like the following:
Note that your application won't successfully detect Windows 10 if it wasn't listed as a supported operating system
in the application manifest.
You can also check the version of the .NET Framework that the application was built against:
Console.WriteLine(AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName);
See also
Windows Forms Add Configuration Element
Adjusting the Size and Scale of Windows Forms
Changing the Appearance of Windows Forms
3/9/2019 • 2 minutes to read • Edit Online
You can customize the look of your Windows Forms applications in many different ways, such as changing the
border, opacity, shape, style, or setting a background image for your Windows Forms application.
In This Section
How to: Change the Borders of Windows Forms
Shows how to change the border style of a form.
Reference
Form
Describes this class and has links to all of its members.
FormBorderStyle
Describes this enumeration and contains descriptions of all of its members.
VisualStyleRenderer
Describes this class and has links to all of its members.
Image
Describes this class and has links to all of its members.
Region
Describes this class and has links to all of its members.
Color
Describes this class and has links to all of its members.
Related Sections
Adjusting the Size and Scale of Windows Forms
Contains links to topics that show how to change the size and scale of a form.
Graphics and Drawing in Windows Forms
Contains links to topics that describe how to perform custom drawing on Windows Forms.
Controls with Built-In Owner-Drawing Support
List owner-draw support in Windows Forms controls.
How to: Change the Borders of Windows Forms
4/28/2019 • 2 minutes to read • Edit Online
You have several border styles to choose from when you are determining the appearance and behavior of your
Windows Forms. By changing the FormBorderStyle property, you can control the resizing behavior of the form. In
addition, setting the FormBorderStyle affects how the caption bar is displayed as well as what buttons might
appear on it. For more information, see FormBorderStyle.
There is extensive support for this task in Visual Studio.
See also How to: Change the Borders of Windows Forms Using the Designer.
To set the border style of Windows Forms programmatically
Set the FormBorderStyle property to the style you want. The following code example sets the border style
of form DlgBx1 to FixedDialog.
DlgBx1.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog
DlgBx1.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
DlgBx1->FormBorderStyle =
System::Windows::Forms::FormBorderStyle::FixedDialog;
See also
FormBorderStyle
FixedDialog
Getting Started with Windows Forms
Windows Forms Controls
4/8/2019 • 2 minutes to read • Edit Online
As you design and modify the user interface of your Windows Forms applications, you will need to add, align, and
position controls. Controls are objects that are contained within form objects. Each type of control has its own set
of properties, methods, and events that make it suitable for a particular purpose. You can manipulate controls in
the designer and write code to add controls dynamically at run time.
In This Section
Putting Controls on Windows Forms
Provides links related to putting controls on forms.
Arranging Controls on Windows Forms
Provides links related to arranging controls on forms.
Labeling Individual Windows Forms Controls and Providing Shortcuts to Them
Describes the uses of keyboard shortcuts, text labels on controls, and modifier keys.
Controls to Use on Windows Forms
Lists the controls that work with Windows Forms, and basic things you can accomplish with each control.
Developing Custom Windows Forms Controls with the .NET Framework
Provides background information and samples to help users develop custom Windows Forms controls.
Developing Windows Forms Controls at Design Time
Describes techniques for creating custom controls through design and inheritance.
Related Sections
Client Applications
Provides an overview of developing Windows-based applications.
User Input in Windows Forms
3/9/2019 • 2 minutes to read • Edit Online
Windows Forms includes a user input model based on events that are raised while processing related Windows
messages. The topics in this section provide information on mouse and keyboard user input, including code
examples that demonstrate how to perform specific tasks.
In This Section
User Input in a Windows Forms Application
Provides an overview of user input events and the methods that process Windows messages.
Keyboard Input in a Windows Forms Application
Provides information on keyboard message handling, the different types of keys, and the keyboard events.
Mouse Input in a Windows Forms Application
Provides information on the mouse events and other mouse-related features, including mouse cursors and mouse
capture.
How to: Simulate Mouse and Keyboard Events in Code
Demonstrates several different ways to programmatically simulate mouse and keyboard input.
How to: Handle User Input Events in Windows Forms Controls
Presents a code example that handles most user input events and reports information about each event.
User Input Validation in Windows Forms
Describes the methods to validate user input in Windows Forms applications.
Related Sections
Also see Creating Event Handlers in Windows Forms.
User Input in a Windows Forms Application
4/8/2019 • 2 minutes to read • Edit Online
In Windows Forms, user input is sent to applications in the form of Windows messages. A series of overridable
methods process these messages at the application, form, and control level. When these methods receive mouse
and keyboard messages, they raise events that can be handled to get information about the mouse or keyboard
input. In many cases, Windows Forms applications will be able to process all user input simply by handling these
events. In other cases, an application may need to override one of the methods that process messages in order to
intercept a particular message before it is received by the application, form, or control.
METHOD NOTES
Keyboard and mouse messages are also processed by an additional set of overridable methods that are specific to
those types of messages. For more information, see How Keyboard Input Works and How Mouse Input Works in
Windows Forms.
See also
User Input in Windows Forms
Keyboard Input in a Windows Forms Application
Mouse Input in a Windows Forms Application
Keyboard Input in a Windows Forms Application
3/9/2019 • 2 minutes to read • Edit Online
Windows Forms includes standard keyboard events that allow you to respond to specific key presses, and also
provides ways for you to intercept, modify, and consume key presses at the application, form, and control level.
In This Section
How Keyboard Input Works
Describes how keyboard messages are processed and transformed into keyboard events.
Using Keyboard Events
Provides information on the types of keyboard events and the information that is received by the keyboard event
handlers.
How to: Modify Keyboard Input to a Standard Control
Presents a code example that shows how to modify key values before they reach a control.
How to: Determine Which Modifier Key Was Pressed
Demonstrates how to find out whether SHIFT, ALT, or CTRL was pressed in addition to another key.
How to: Handle Keyboard Input at the Form Level
Presents a code example that shows how to intercept keys before they reach a control.
How Keyboard Input Works
4/9/2019 • 5 minutes to read • Edit Online
Windows Forms processes keyboard input by raising keyboard events in response to Windows messages. Most
Windows Forms applications process keyboard input exclusively by handling the keyboard events. However, you
need to understand how keyboard messages work so you can implement more advanced keyboard-input
scenarios, such as intercepting keys before they reach a control. This topic describes the types of key data that
Windows Forms recognizes and provides an overview of how keyboard messages are routed. For information
about keyboard events, see Using Keyboard Events.
Types of Keys
Windows Forms identifies keyboard input as virtual-key codes that are represented by the bitwise Keys
enumeration. With the Keys enumeration, you can combine a series of pressed keys to result in a single value.
These values correspond to the values that accompany the WM_KEYDOWN and WM_SYSKEYDOWN Windows
messages. You can detect most physical key presses by handling the KeyDown or KeyUp events. Character keys
are a subset of the Keys enumeration and correspond to the values that accompany the WM_CHAR and
WM_SYSCHAR Windows messages. If the combination of pressed keys results in a character, you can detect the
character by handling the KeyPress event. Alternatively, you can use Keyboard, exposed by Visual Basic
programming interface, to discover which keys were pressed and send keys. For more information, see Accessing
the Keyboard.
Preprocessing Keys
Like other messages, keyboard messages are processed in the WndProc method of a form or control. However,
before keyboard messages are processed, the PreProcessMessage method calls one or more methods that can be
overridden to handle special character keys and physical keys. You can override these methods to detect and filter
certain keys before the messages are processed by the control. The following table shows the action that is being
performed and the related method that occurs, in the order that the method occurs.
Preprocessing for a KeyDown event
ACTION RELATED METHOD NOTES
ACTION RELATED METHOD NOTES
Check for a command key such as an ProcessCmdKey This method processes a command key,
accelerator or menu shortcut. which takes precedence over regular
keys. If this method returns true , the
key message is not dispatched and a
key event does not occur. If it returns
false , IsInputKey is called .
Check for a special key that requires IsInputKey If the method returns true , it means
preprocessing or a normal character the control is a regular character and a
key that should raise a KeyDown event KeyDown event is raised. If false ,
and be dispatched to a control. ProcessDialogKey is called. Note: To
ensure a control gets a key or
combination of keys, you can handle
the PreviewKeyDown event and set
IsInputKey of the
PreviewKeyDownEventArgs to true
for the key or keys you want.
Check for a navigation key (ESC, TAB, ProcessDialogKey This method processes a physical key
Return, or arrow keys). that employs special functionality within
the control, such as switching focus
between the control and its parent. If
the immediate control does not handle
the key, the ProcessDialogKey is called
on the parent control and so on to the
topmost control in the hierarchy. If this
method returns true , preprocessing
is complete and a key event is not
generated. If it returns false , a
KeyDown event occurs.
Check to see the key is a normal IsInputChar If the character is a normal character,
character that should be processed by this method returns true , the
the control KeyPress event is raised and no further
preprocessing occurs. Otherwise
ProcessDialogChar will be called.
METHOD NOTES
TASK METHOD
Intercept a navigation key and raise a KeyDown event. For Override IsInputKey. Note: Alternatively, you can handle the
example you want TAB and Return to be handled in a text PreviewKeyDown event and set IsInputKey of the
box. PreviewKeyDownEventArgs to true for the key or keys you
want.
Intercept a navigation key and raise a KeyPress event. For Override IsInputChar.
example in a spin-box control you want multiple arrow key
presses to accelerate progression through the items.
Perform custom mnemonic handling; for example, you want Override ProcessMnemonic.
to handle mnemonics on owner-drawn buttons contained in
a toolbar.
See also
Keys
WndProc
PreProcessMessage
My.Computer.Keyboard Object
Accessing the Keyboard
Using Keyboard Events
Using Keyboard Events
4/28/2019 • 2 minutes to read • Edit Online
Most Windows Forms programs process keyboard input by handling the keyboard events. This topic provides an
overview of the keyboard events, including details on when to use each event and the data that is supplied for
each event. Also see Event Handlers Overview (Windows Forms) and Events Overview (Windows Forms).
Keyboard Events
Windows Forms provides two events that occur when a user presses a keyboard key and one event when a user
releases a keyboard key:
The KeyDown event occurs once
The KeyPress event, which can occur multiple times when a user holds down the same key.
The KeyUp event occurs once when a user releases a key.
When a user presses a key, Windows Forms determines which event to raise based on whether the keyboard
message specifies a character key or a physical key. For more information about character and physical keys, see
How Keyboard Input Works.
The following table describes the three keyboard events.
KeyDown This event is raised when a user presses The handler for KeyDown receives:
a physical key.
A KeyEventArgs parameter,
which provides the KeyCode
property (which specifies a
physical keyboard button).
The Modifiers property (SHIFT,
CTRL, or ALT).
The KeyData property (which
combines the key code and
modifier). The KeyEventArgs
parameter also provides:
KeyPress This event is raised when the key or KeyPress is raised after KeyDown.
keys pressed result in a character. For
example, a user presses SHIFT and the The handler for KeyPress
lowercase "a" keys, which result in a receives:
capital letter "A" character. A KeyPressEventArgs parameter,
which contains the character
code of the key that was
pressed. This character code is
unique for every combination of
a character key and a modifier
key.
KeyUp This event is raised when a user The handler for KeyUp receives:
releases a physical key.
A KeyEventArgs parameter:
See also
Keyboard Input in a Windows Forms Application
How Keyboard Input Works
Mouse Input in a Windows Forms Application
How to: Modify Keyboard Input to a Standard
Control
4/28/2019 • 7 minutes to read • Edit Online
Windows Forms provides the ability to consume and modify keyboard input. Consuming a key refers to handling a
key within a method or event handler so that other methods and events further down the message queue do not
receive the key value. Modifying a key refers to modifying the value of a key so that methods and event handlers
further down the message queue receive a different key value. This topic shows how to accomplish these tasks.
To consume a key
In a KeyPress event handler, set the Handled property of the KeyPressEventArgs class to true .
-or-
In a KeyDown event handler, set the Handled property of the KeyEventArgs class to true .
NOTE
Setting the Handled property in the KeyDown event handler does not prevent the KeyPress and KeyUp events from
being raised for the current keystroke. Use the SuppressKeyPress property for this purpose.
The following example is an excerpt from a switch statement that examines the KeyChar property of the
KeyPressEventArgs received by a KeyPress event handler. This code consumes the 'A' and 'a' character keys.
MessageBox.Show("Control.PreProcessMessage: '" +
keyCode.ToString() + "' pressed.");
MessageBox.Show(("Control.PreProcessMessage: '" + _
keyCode.ToString() + "' pressed."))
Example
The following code example is the complete application for the code examples in the previous sections. The
application uses a custom control derived from the TextBox class to consume and modify keyboard input.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace KeyboardInput
{
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand,
Name="FullTrust")]
class Form1 : Form
{
// The following Windows message value is defined in Winuser.h.
private int WM_KEYDOWN = 0x100;
CustomTextBox CustomTextBox1 = new CustomTextBox();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
this.AutoSize = true;
this.Controls.Add(CustomTextBox1);
CustomTextBox1.KeyPress +=
new KeyPressEventHandler(CustomTextBox1_KeyPress);
}
public CustomTextBox()
{
this.Size = new Size(100, 100);
this.AutoSize = false;
}
MessageBox.Show("Control.PreProcessMessage: '" +
keyCode.ToString() + "' pressed.");
MessageBox.Show("Control.ProcessKeyMessage: '" +
keyCode.ToString() + "' pressed.");
break;
}
}
Imports System
Imports System.Drawing
Imports System.Security
Imports System.Security.Permissions
Imports System.Windows.Forms
Namespace KeyboardInput
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand,
Name:="FullTrust")> _
Class Form1
Inherits Form
<STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
Public Sub New()
Me.AutoSize = True
Me.Controls.Add(CustomTextBox1)
End Sub
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand,
Name:="FullTrust")> _
Public Class CustomTextBox
Inherits TextBox
MessageBox.Show(("Control.PreProcessMessage: '" + _
keyCode.ToString() + "' pressed."))
MessageBox.Show(("Control.ProcessKeyMessage: '" + _
keyCode.ToString() + "' pressed."))
End Select
End If
End Class
End Namespace
See also
Keyboard Input in a Windows Forms Application
User Input in a Windows Forms Application
How Keyboard Input Works
How to: Determine Which Modifier Key Was Pressed
4/28/2019 • 2 minutes to read • Edit Online
When you create an application that accepts the user's keystrokes, you may also want to monitor for modifier keys
such as the SHIFT, ALT, and CTRL keys. When a modifier key is pressed in combination with other keys, or with
mouse clicks, your application can respond appropriately. For example, if the letter S is pressed, this may simply
cause an "s" to appear on the screen, but if the keys CTRL+S are pressed, the current document may be saved. If
you handle the KeyDown event, the Modifiers property of the KeyEventArgs received by the event handler
specifies which modifier keys are pressed. Alternatively, the KeyData property of KeyEventArgs specifies the
character that was pressed as well as any modifier keys combined with a bitwise OR. However, if you are handling
the KeyPress event or a mouse event, the event handler does not receive this information. In this case, you must
use the ModifierKeys property of the Control class. In either case, you must perform a bitwise AND of the
appropriate Keys value and the value you are testing. The Keys enumeration offers variations of each modifier key,
so it is important that you perform the bitwise AND with the correct value. For example, the SHIFT key is
represented by Shift, ShiftKey, RShiftKey and LShiftKey The correct value to test SHIFT as a modifier key is Shift.
Similarly, to test for CTRL and ALT as modifiers you should use the Control and Alt values, respectively.
NOTE
Visual Basic programmers can also access key information through the Keyboard property
private:
void textBox1_KeyPress(Object^ sender, KeyPressEventArgs^ e)
{
if ((Control::ModifierKeys & Keys::Shift) == Keys::Shift)
{
MessageBox::Show("Pressed " + Keys::Shift.ToString());
}
}
Windows Forms provides the ability to handle keyboard messages at the form level, before the messages reach a
control. This topic shows how to accomplish this task.
To handle a keyboard message at the form level
Handle the KeyPress or KeyDown event of the startup form, and set the KeyPreview property of the form to
true so that keyboard messages are received by the form before they reach any controls on the form. The
following code example handles the KeyPress event by detecting all of the number keys and consuming '1',
'4', and '7'.
switch (e->KeyChar)
{
case '1':
case '4':
case '7':
MessageBox::Show("Form.KeyPress: '" +
e->KeyChar.ToString() + "' consumed.");
e->Handled = true;
break;
}
}
}
// Detect all numeric characters at the form level and consume 1,
// 4, and 7. Note that 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.ToString() + "' pressed.");
switch (e.KeyChar)
{
case (char)49:
case (char)52:
case (char)55:
MessageBox.Show("Form.KeyPress: '" +
e.KeyChar.ToString() + "' consumed.");
e.Handled = true;
break;
}
}
}
' Detect all numeric characters at the form level and consume 1,
' 4, and 7. Note that Form.KeyPreview must be set to true for this
' event handler to be called.
Sub Form1_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles Me.KeyPress
Example
The following code example is the entire application for the above example. The application includes a TextBox
along with several other controls that allow you to move focus from the TextBox. The KeyPress event of the main
Form consumes '1', '4', and '7', and the KeyPress event of the TextBox consumes '2', '5', and '8' while displaying the
remaining keys. Compare the MessageBox output when you press a number key while the TextBox has focus with
the MessageBox output when you press a number key while focus is on one of the other controls.
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
namespace KeyboardInputForm
{
public ref class Form1 sealed: public Form, public IMessageFilter
{
// The following Windows message value is defined in Winuser.h.
private:
static const int WM_KEYDOWN = 0x100;
private:
TextBox^ inputTextBox;
public:
Form1()
{
inputTextBox = gcnew TextBox();
this->AutoSize = true;
Application::AddMessageFilter(this);
FlowLayoutPanel^ panel = gcnew FlowLayoutPanel();
panel->AutoSize = true;
panel->FlowDirection = FlowDirection::TopDown;
panel->Controls->Add(gcnew Button());
panel->Controls->Add(gcnew RadioButton());
panel->Controls->Add(inputTextBox);
this->Controls->Add(panel);
this->KeyPreview = true;
this->KeyPress +=
gcnew KeyPressEventHandler(this, &Form1::Form1_KeyPress);
inputTextBox->KeyPress +=
gcnew KeyPressEventHandler(this,
&Form1::inputTextBox_KeyPress);
}
switch (e->KeyChar)
{
case '1':
case '4':
case '7':
MessageBox::Show("Form.KeyPress: '" +
e->KeyChar.ToString() + "' consumed.");
e->Handled = true;
break;
}
}
}
switch (e->KeyChar)
{
case '2':
case '5':
case '8':
MessageBox::Show("Control.KeyPress: '" +
e->KeyChar.ToString() + "' consumed.");
e->Handled = true;
break;
}
}
}
};
}
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew KeyboardInputForm::Form1());
}
using System;
using System.Drawing;
using System.Windows.Forms;
namespace KeyboardInputForm
{
class Form1 : Form
{
TextBox TextBox1 = new TextBox();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
this.AutoSize = true;
this.KeyPreview = true;
this.KeyPress +=
new KeyPressEventHandler(Form1_KeyPress);
TextBox1.KeyPress +=
new KeyPressEventHandler(TextBox1_KeyPress);
}
switch (e.KeyChar)
{
case (char)49:
case (char)52:
case (char)55:
MessageBox.Show("Form.KeyPress: '" +
e.KeyChar.ToString() + "' consumed.");
e.Handled = true;
break;
}
}
}
switch (e.KeyChar)
{
case (char)50:
case (char)53:
case (char)56:
MessageBox.Show("Control.KeyPress: '" +
e.KeyChar.ToString() + "' consumed.");
e.Handled = true;
break;
}
}
}
}
}
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Namespace KeyboardInputForm
Class Form1
Inherits Form
<STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
Me.KeyPreview = True
End Sub
' Detect all numeric characters at the form level and consume 1,
' 4, and 7. Note that Form.KeyPreview must be set to true for this
' event handler to be called.
Sub Form1_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles Me.KeyPress
' Detect all numeric characters at the TextBox level and consume
' 2, 5, and 8.
Sub TextBox1_KeyPress(ByVal sender As Object, _
ByVal e As KeyPressEventArgs) Handles TextBox1.KeyPress
End Class
End Namespace
See also
Keyboard Input in a Windows Forms Application
Mouse Input in a Windows Forms Application
3/9/2019 • 2 minutes to read • Edit Online
Windows Forms includes a variety of mouse events and additional support for customized mouse cursors, mouse
capture, and drag-and-drop behavior.
In This Section
How Mouse Input Works in Windows Forms
Provides information about the mouse events and how to get current information and system settings for the
mouse.
Mouse Events in Windows Forms
Provides information about the order in which the mouse events occur and how the mouse events are raised
within specific controls.
How to: Distinguish Between Clicks and Double-Clicks
Demonstrates how to use single and double clicks to initiate incompatible actions.
Mouse Pointers in Windows Forms
Describes how to change the mouse cursor.
Mouse Capture in Windows Forms
Describes how a control can capture the mouse.
Drag-and-Drop Functionality in Windows Forms
Describes how to implement drag-and-drop behavior.
Related Sections
Accessing the Mouse
Lists topics for accessing the mouse using Visual Basic.
How Mouse Input Works in Windows Forms
4/8/2019 • 4 minutes to read • Edit Online
Receiving and handling mouse input is an important part of every Windows application. You can handle mouse
events to perform an action in your application, or use mouse location information to perform hit testing or other
actions. In addition, you can change the way the controls in your application handle mouse input. This topic
describes these mouse events in detail, and how to obtain and change system settings for the mouse. For more
information about the data provided with the mouse events and the order in which the mouse click events are
raised, see Mouse Events in Windows Forms.
Mouse Events
The primary way to respond to mouse input is to handle mouse events. The following table shows the mouse
events and describes when they are raised.
Click This event occurs when the mouse button is released, typically
before the MouseUp event. The handler for this event receives
an argument of type EventArgs. Handle this event when you
only need to determine when a click occurs.
MouseClick This event occurs when the user clicks the control with the
mouse. The handler for this event receives an argument of
type MouseEventArgs. Handle this event when you need to
get information about the mouse when a click occurs.
MouseDoubleClick This event occurs when the user double-clicks the control with
the mouse. The handler for this event receives an argument of
type MouseEventArgs. Handle this event when you need to
get information about the mouse when a double-click occurs.
MOUSE EVENT DESCRIPTION
MouseDown This event occurs when the mouse pointer is over the control
and the user presses a mouse button. The handler for this
event receives an argument of type MouseEventArgs.
MouseEnter This event occurs when the mouse pointer enters the border
or client area of the control, depending on the type of control.
The handler for this event receives an argument of type
EventArgs.
MouseHover This event occurs when the mouse pointer stops and rests
over the control. The handler for this event receives an
argument of type EventArgs.
MouseLeave This event occurs when the mouse pointer leaves the border
or client area of the control, depending on the type of the
control. The handler for this event receives an argument of
type EventArgs.
MouseMove This event occurs when the mouse pointer moves while it is
over a control. The handler for this event receives an
argument of type MouseEventArgs.
MouseUp This event occurs when the mouse pointer is over the control
and the user releases a mouse button. The handler for this
event receives an argument of type MouseEventArgs.
MouseWheel This event occurs when the user rotates the mouse wheel
while the control has focus. The handler for this event receives
an argument of type MouseEventArgs. You can use the Delta
property of MouseEventArgs to determine how far the mouse
has scrolled.
PROPERTY DESCRIPTION
DoubleClickSize Gets the dimensions, in pixels, of the area in which the user
must click twice for the operating system to consider the two
clicks a double-click.
MouseButtonsSwapped Gets a value indicating whether the functions of the left and
right mouse buttons have been swapped.
MouseHoverTime Gets the time, in milliseconds, that the mouse pointer has to
stay in the hover rectangle before a mouse hover message is
generated.
MouseWheelScrollLines Gets the number of lines to scroll when the mouse wheel is
rotated.
See also
Mouse Input in a Windows Forms Application
Mouse Capture in Windows Forms
Mouse Pointers in Windows Forms
Mouse Events in Windows Forms
4/26/2019 • 3 minutes to read • Edit Online
When you handle mouse input, you usually want to know the location of the mouse pointer and the state of the
mouse buttons. This topic provides details on how to get this information from mouse events, and explains the
order in which mouse click events are raised in Windows Forms controls. For a list and description of all of the
mouse events, see How Mouse Input Works in Windows Forms. Also see Event Handlers Overview (Windows
Forms) and Events Overview (Windows Forms).
Mouse Information
A MouseEventArgs is sent to the handlers of mouse events related to clicking a mouse button and tracking mouse
movements. MouseEventArgs provides information about the current state of the mouse, including the location of
the mouse pointer in client coordinates, which mouse buttons are pressed, and whether the mouse wheel has
scrolled. Several mouse events, such as those that simply notify when the mouse pointer has entered or left the
bounds of a control, send an EventArgs to the event handler with no further information.
If you want to know the current state of the mouse buttons or the location of the mouse pointer, and you want to
avoid handling a mouse event, you can also use the MouseButtons and MousePosition properties of the Control
class. MouseButtons returns information about which mouse buttons are currently pressed. The MousePosition
returns the screen coordinates of the mouse pointer and is equivalent to the value returned by Position.
NOTE
For the ComboBox control, the event behavior detailed later occurs if the user clicks on the edit field, the button, or
on an item within the list.
NOTE
The event behavior detailed later occurs when the user clicks anywhere within these controls.
NOTE
The event behavior detailed later occurs only when the user clicks on the items in the ListView control. No events are
raised for clicks anywhere else on the control. In addition to the events described later, there are the BeforeLabelEdit
and AfterLabelEdit events, which may be of interest to you if you want to use validation with the ListView control.
NOTE
The event behavior detailed later occurs only when the user clicks on the items themselves or to the right of the
items in the TreeView control. No events are raised for clicks anywhere else on the control. In addition to those
described later, there are the BeforeCheck, BeforeSelect, BeforeLabelEdit, AfterSelect, AfterCheck, and AfterLabelEdit
events, which may be of interest to you if you want to use validation with the TreeView control.
NOTE
If the user moves the pointer out of the toggle control while the mouse button is down (such as moving the mouse
off the Button control while it is pressed), the toggle control will paint in the raised state and only the MouseUp
event occurs. The Click or MouseClick events will not occur in this situation.
See also
Mouse Input in a Windows Forms Application
How to: Distinguish Between Clicks and Double-
Clicks
4/28/2019 • 9 minutes to read • Edit Online
Typically, a single click initiates a user interface (UI) action and a double-click extends the action. For example, one
click usually selects an item, and a double-click edits the selected item. However, the Windows Forms click events
do not easily accommodate a scenario where a click and a double-click perform incompatible actions, because an
action tied to the Click or MouseClick event is performed before the action tied to the DoubleClick or
MouseDoubleClick event. This topic demonstrates two solutions to this problem. One solution is to handle the
double-click event and roll back the actions in the handling of the click event. In rare situations you may need to
simulate click and double-click behavior by handling the MouseDown event and by using the DoubleClickTime
and DoubleClickSize properties of the SystemInformation class. You measure the time between clicks and if a
second click occurs before the value of DoubleClickTime is reached and the click is within a rectangle defined by
DoubleClickSize, perform the double-click action; otherwise, perform the click action.
To roll back a click action
Ensure that the control you are working with has standard double-click behavior. If not, enable the control
with the SetStyle method. Handle the double-click event and roll back the click action as well as the double-
click action. The following code example demonstrates a how to create a custom button with double-click
enabled, as well as how to roll back the click action in the double-click event handling code.
using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace MouseRollBackSingleClick
{
public class Form1 : Form
{
private DoubleClickButton button1;
private FormBorderStyle initialStyle;
public Form1()
{
initialStyle = this.FormBorderStyle;
this.ClientSize = new System.Drawing.Size(292, 266);
button1 = new DoubleClickButton();
button1.Location = new Point (40,40);
button1.Click += new EventHandler(button1_Click);
button1.AutoSize = true;
this.AllowDrop = true;
button1.Text = "Click or Double Click";
button1.DoubleClick += new EventHandler(button1_DoubleClick);
this.Controls.Add(button1);
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
public class DoubleClickButton : Button
{
public DoubleClickButton() : base()
{
// Set the style so a double click event occurs.
SetStyle(ControlStyles.StandardClick |
ControlStyles.StandardDoubleClick, true);
}
}
}
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
End Sub
Me.FormBorderStyle = FormBorderStyle.FixedToolWindow
End Sub
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
End Class
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
namespace SingleVersusDoubleClick
{
public ref class Form1 : public Form
{
private:
Rectangle hitTestRectangle;
private:
Rectangle doubleClickRectangle;
private:
TextBox^ outputBox;
private:
Timer^ doubleClickTimer;
private:
ProgressBar^ doubleClickBar;
private:
Label^ hitTestLabel;
private:
Label^ timerLabel;
private:
bool isFirstClick;
private:
bool isDoubleClick;
private:
int milliseconds;
public:
Form1()
{
hitTestRectangle = Rectangle();
hitTestRectangle.Location = Point(30, 20);
hitTestRectangle.Size = System::Drawing::Size(100, 40);
doubleClickRectangle = Rectangle();
isFirstClick = true;
private:
void doubleClickTimer_Tick(Object^ sender, EventArgs^ e)
{
milliseconds += 100;
doubleClickBar->Increment(100);
if (isDoubleClick)
{
outputBox->AppendText("Perform double click action");
outputBox->AppendText(Environment::NewLine);
}
else
{
outputBox->AppendText("Perform single click action");
outputBox->AppendText(Environment::NewLine);
}
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew SingleVersusDoubleClick::Form1);
}
using System;
using System.Drawing;
using System.Windows.Forms;
namespace SingleVersusDoubleClick
{
class Form1 : Form
{
private Rectangle hitTestRectangle = new Rectangle();
private Rectangle doubleClickRectangle = new Rectangle();
private TextBox textBox1 = new TextBox();
private Timer doubleClickTimer = new Timer();
private ProgressBar doubleClickBar = new ProgressBar();
private Label label1 = new Label();
private Label label2 = new Label();
private bool isFirstClick = true;
private bool isDoubleClick = false;
private int milliseconds = 0;
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
public Form1()
{
label1.Location = new Point(30, 5);
label1.Size = new Size(100, 15);
label1.Text = "Hit test rectangle:";
doubleClickTimer.Interval = 100;
doubleClickTimer.Tick +=
new EventHandler(doubleClickTimer_Tick);
if (isDoubleClick)
{
textBox1.AppendText("Perform double click action");
textBox1.AppendText(Environment.NewLine);
}
else
{
textBox1.AppendText("Perform single click action");
textBox1.AppendText(Environment.NewLine);
}
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Namespace SingleVersusDoubleClick
Class Form1
Inherits Form
Private hitTestRectangle As New Rectangle()
Private doubleClickRectangle As New Rectangle()
Private textBox1 As New TextBox()
Private WithEvents doubleClickTimer As New Timer()
Private doubleClickBar As New ProgressBar()
Private label1 As New Label()
Private label2 As New Label()
Private isFirstClick As Boolean = True
Private isDoubleClick As Boolean = False
Private milliseconds As Integer = 0
<STAThread()> _
<STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
Me.Controls.Add(doubleClickBar)
Me.Controls.Add(textBox1)
Me.Controls.Add(label1)
Me.Controls.Add(label2)
End Sub
milliseconds += 100
doubleClickBar.Increment(100)
' The timer has reached the double click time limit.
If milliseconds >= SystemInformation.DoubleClickTime Then
doubleClickTimer.Stop()
If isDoubleClick Then
textBox1.AppendText("Perform double click action")
textBox1.AppendText(Environment.NewLine)
Else
textBox1.AppendText("Perform single click action")
textBox1.AppendText(Environment.NewLine)
End If
See also
Mouse Input in a Windows Forms Application
Mouse Pointers in Windows Forms
4/8/2019 • 2 minutes to read • Edit Online
The mouse pointer, which is sometimes referred to as the cursor, is a bitmap that specifies a focus point on the
screen for user input with the mouse. This topic provides an overview of the mouse pointer in Windows Forms
and describes some of the ways to modify and control the mouse pointer.
See also
Cursor
Mouse Input in a Windows Forms Application
Drag-and-Drop Functionality in Windows Forms
Mouse Capture in Windows Forms
4/8/2019 • 2 minutes to read • Edit Online
Mouse capture refers to when a control takes command of all mouse input. When a control has captured the
mouse, it receives mouse input whether or not the pointer is within its borders.
See also
Mouse Input in a Windows Forms Application
Drag-and-Drop Functionality in Windows Forms
4/8/2019 • 2 minutes to read • Edit Online
Windows Forms includes a set of methods, events, and classes that implement drag-and-drop behavior. This topic
provides an overview of the drag-and-drop support in Windows Forms. Also see Drag-and-Drop Operations and
Clipboard Support.
DragEnter This event occurs when an object is dragged into the control's
bounds. The handler for this event receives an argument of
type DragEventArgs.
DragOver This event occurs when an object is dragged while the mouse
pointer is within the control's bounds. The handler for this
event receives an argument of type DragEventArgs.
The DragEventArgs class provides the location of the mouse pointer, the current state of the mouse buttons and
modifier keys of the keyboard, the data being dragged, and DragDropEffects values that specify the operations
allowed by the source of the drag event and the target drop effect for the operation.
Events on the Source
The following table shows the events that occur on the source of the drag-and-drop operation.
The QueryContinueDragEventArgs class provides the current state of the mouse buttons and modifier keys of the
keyboard, a value specifying whether the ESC key was pressed, and a DragAction value that can be set to specify
whether the drag-and-drop operation should continue.
See also
Mouse Input in a Windows Forms Application
How to: Simulate Mouse and Keyboard Events in
Code
4/28/2019 • 9 minutes to read • Edit Online
Windows Forms provides several options for programmatically simulating mouse and keyboard input. This topic
provides an overview of these options.
If your application is intended for international use with a variety of keyboards, the use of SendKeys.Send could
yield unpredictable results and should be avoided.
NOTE
The SendKeys class has been updated for the .NET Framework 3.0 to enable its use in applications that run on Windows
Vista. The enhanced security of Windows Vista (known as User Account Control or UAC) prevents the previous
implementation from working as expected.
The SendKeys class is susceptible to timing issues, which some developers have had to work around. The updated
implementation is still susceptible to timing issues, but is slightly faster and may require changes to the workarounds. The
SendKeys class tries to use the previous implementation first, and if that fails, uses the new implementation. As a result, the
SendKeys class may behave differently on different operating systems. Additionally, when the SendKeys class uses the new
implementation, the SendWait method will not wait for messages to be processed when they are sent to another process.
If your application relies on consistent behavior regardless of the operating system, you can force the SendKeys class to use
the new implementation by adding the following application setting to your app.config file.
<appSettings>
</appSettings>
To force the SendKeys class to use the previous implementation, use the value "JournalHook" instead.
' Send the enter key to the button, which raises the click
' event for the button. This works because the tab stop of
' the button is 0.
SendKeys.Send("{ENTER}")
End Sub
NOTE
The correct parameters of the FindWindow call that locates the Calculator application vary based on your version of
Windows. The following code finds the Calculator application on Windows 7. On Windows Vista, change the first
parameter to "SciCalc". You can use the Spy++ tool, included with Visual Studio, to determine the correct parameters.
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
namespace SimulateKeyPress
{
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew SimulateKeyPress::Form1());
}
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
namespace SimulateKeyPress
{
class Form1 : Form
{
private Button button1 = new Button();
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
button1.Location = new Point(10, 10);
button1.TabIndex = 0;
button1.Text = "Click to automate Calculator";
button1.AutoSize = true;
button1.Click += new EventHandler(button1_Click);
Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Windows.Forms
Namespace SimulateKeyPress
Class Form1
Inherits Form
Private WithEvents button1 As New Button()
<STAThread()> _
Public Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
' Send a key to the button when the user double-clicks anywhere
' on the form.
Private Sub Form1_DoubleClick(ByVal sender As Object, _
ByVal e As EventArgs) Handles Me.DoubleClick
' Send the enter key to the button, which raises the click
' event for the button. This works because the tab stop of
' the button is 0.
SendKeys.Send("{ENTER}")
End Sub
End Class
End Namespace
See also
User Input in Windows Forms
How to: Handle User Input Events in Windows Forms
Controls
4/28/2019 • 26 minutes to read • Edit Online
This example demonstrates how to handle most keyboard, mouse, focus, and validation events that can occur in a
Windows Forms control. The text box named TextBoxInput receives the events when it has focus, and information
about each event is written in the text box named TextBoxOutput in the order in which the events are raised. The
application also includes a set of check boxes that can be used to filter which events to report.
Example
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>
namespace UserInputWalkthrough
{
public ref class Form1 : public Form
{
Label^ lblEvent;
Label^ lblInput;
TextBox^ TextBoxOutput;
TextBox^ TextBoxInput;
GroupBox^ GroupBoxEvents;
Button^ ButtonClear;
LinkLabel^ LinkLabelDrag;
CheckBox^ CheckBoxToggleAll;
CheckBox^ CheckBoxMouse;
CheckBox^ CheckBoxMouseEnter;
CheckBox^ CheckBoxMouseMove;
CheckBox^ CheckBoxMousePoints;
CheckBox^ CheckBoxMouseDrag;
CheckBox^ CheckBoxMouseDragOver;
CheckBox^ CheckBoxKeyboard;
CheckBox^ CheckBoxKeyUpDown;
CheckBox^ CheckBoxFocus;
CheckBox^ CheckBoxValidation;
public:
Form1() : Form()
{
this->Load += gcnew EventHandler(this, &Form1::Form1_Load);
private:
void Form1_Load(Object^ sender, EventArgs^ e)
{
this->GroupBoxEvents->SuspendLayout();
this->SuspendLayout();
LinkLabelDrag->AllowDrop = true;
LinkLabelDrag->AutoSize = true;
LinkLabelDrag->Location = Point(13, 240);
LinkLabelDrag->Size = System::Drawing::Size(175, 14);
LinkLabelDrag->TabIndex = 2;
LinkLabelDrag->TabStop = true;
LinkLabelDrag->Text = "Click here to use as a drag source";
LinkLabelDrag->Links->Add(gcnew LinkLabel::Link(0,
LinkLabelDrag->Text->Length));
CheckBoxToggleAll->AutoSize = true;
CheckBoxToggleAll->Location = Point(7, 20);
CheckBoxToggleAll->Size = System::Drawing::Size(122, 17);
CheckBoxToggleAll->TabIndex = 4;
CheckBoxToggleAll->Text = "Toggle All Events";
CheckBoxToggleAll->Text = "Toggle All Events";
CheckBoxMouse->AutoSize = true;
CheckBoxMouse->Location = Point(7, 45);
CheckBoxMouse->Size = System::Drawing::Size(137, 17);
CheckBoxMouse->TabIndex = 5;
CheckBoxMouse->Text = "Mouse and Click Events";
CheckBoxMouseEnter->AutoSize = true;
CheckBoxMouseEnter->Location = Point(26, 69);
CheckBoxMouseEnter->Margin =
System::Windows::Forms::Padding(3, 3, 3, 1);
CheckBoxMouseEnter->Size = System::Drawing::Size(151, 17);
CheckBoxMouseEnter->TabIndex = 6;
CheckBoxMouseEnter->Text = "Mouse Enter/Hover/Leave";
CheckBoxMouseMove->AutoSize = true;
CheckBoxMouseMove->Location = Point(26, 89);
CheckBoxMouseMove->Margin =
System::Windows::Forms::Padding(3, 2, 3, 3);
CheckBoxMouseMove->Size = System::Drawing::Size(120, 17);
CheckBoxMouseMove->TabIndex = 7;
CheckBoxMouseMove->Text = "Mouse Move Events";
CheckBoxMousePoints->AutoSize = true;
CheckBoxMousePoints->Location = Point(26, 112);
CheckBoxMousePoints->Margin =
System::Windows::Forms::Padding(3, 3, 3, 1);
CheckBoxMousePoints->Size = System::Drawing::Size(141, 17);
CheckBoxMousePoints->TabIndex = 8;
CheckBoxMousePoints->Text = "Draw Mouse Points";
CheckBoxMouseDrag->AutoSize = true;
CheckBoxMouseDrag->Location = Point(26, 135);
CheckBoxMouseDrag->Margin =
System::Windows::Forms::Padding(3, 1, 3, 3);
CheckBoxMouseDrag->Size = System::Drawing::Size(151, 17);
CheckBoxMouseDrag->TabIndex = 9;
CheckBoxMouseDrag->Text = "Mouse Drag && Drop Events";
CheckBoxMouseDragOver->AutoSize = true;
CheckBoxMouseDragOver->Location = Point(44, 159);
CheckBoxMouseDragOver->Size = System::Drawing::Size(142, 17);
CheckBoxMouseDragOver->TabIndex = 10;
CheckBoxMouseDragOver->Text = "Mouse Drag Over Events";
CheckBoxKeyboard->AutoSize = true;
CheckBoxKeyboard->Location = Point(8, 184);
CheckBoxKeyboard->Size = System::Drawing::Size(103, 17);
CheckBoxKeyboard->TabIndex = 11;
CheckBoxKeyboard->Text = "Keyboard Events";
CheckBoxKeyUpDown->AutoSize = true;
CheckBoxKeyUpDown->Location = Point(26, 207);
CheckBoxKeyUpDown->Margin =
System::Windows::Forms::Padding(3, 3, 3, 1);
CheckBoxKeyUpDown->Size = System::Drawing::Size(133, 17);
CheckBoxKeyUpDown->TabIndex = 12;
CheckBoxKeyUpDown->Text = "Key Up && Down Events";
CheckBoxFocus->AutoSize = true;
CheckBoxFocus->Location = Point(8, 233);
CheckBoxFocus->Margin =
System::Windows::Forms::Padding(3, 2, 3, 3);
CheckBoxFocus->Size = System::Drawing::Size(146, 17);
CheckBoxFocus->TabIndex = 13;
CheckBoxFocus->Text = "Focus && Activation Events";
CheckBoxValidation->AutoSize = true;
CheckBoxValidation->Location = Point(8, 257);
CheckBoxValidation->Location = Point(8, 257);
CheckBoxValidation->Size = System::Drawing::Size(104, 17);
CheckBoxValidation->TabIndex = 14;
CheckBoxValidation->Text = "Validation Events";
ButtonClear->Click +=
gcnew EventHandler(this, &Form1::ButtonClear_Click);
TextBoxInput->KeyDown +=
gcnew KeyEventHandler(this, &Form1::TextBoxInput_KeyDown);
TextBoxInput->KeyPress +=
gcnew KeyPressEventHandler(this,
&Form1::TextBoxInput_KeyPress);
TextBoxInput->KeyUp +=
gcnew KeyEventHandler(this, &Form1::TextBoxInput_KeyUp);
TextBoxInput->Click +=
gcnew EventHandler(this, &Form1::TextBoxInput_Click);
TextBoxInput->DoubleClick +=
gcnew EventHandler(this, &Form1::TextBoxInput_DoubleClick);
TextBoxInput->MouseClick +=
gcnew MouseEventHandler(this, &Form1::TextBoxInput_MouseClick);
TextBoxInput->MouseDoubleClick +=
gcnew MouseEventHandler(this,
&Form1::TextBoxInput_MouseDoubleClick);
TextBoxInput->MouseDown +=
gcnew MouseEventHandler(this, &Form1::TextBoxInput_MouseDown);
TextBoxInput->MouseUp +=
gcnew MouseEventHandler(this, &Form1::TextBoxInput_MouseUp);
TextBoxInput->MouseEnter +=
gcnew EventHandler(this, &Form1::TextBoxInput_MouseEnter);
TextBoxInput->MouseHover +=
gcnew EventHandler(this, &Form1::TextBoxInput_MouseHover);
TextBoxInput->MouseLeave +=
gcnew EventHandler(this, &Form1::TextBoxInput_MouseLeave);
TextBoxInput->MouseWheel +=
gcnew MouseEventHandler(this, &Form1::TextBoxInput_MouseWheel);
TextBoxInput->MouseMove +=
gcnew MouseEventHandler(this, &Form1::TextBoxInput_MouseMove);
TextBoxInput->MouseCaptureChanged +=
gcnew EventHandler(this,
&Form1::TextBoxInput_MouseCaptureChanged);
TextBoxInput->DragEnter +=
gcnew DragEventHandler(this, &Form1::TextBoxInput_DragEnter);
TextBoxInput->DragDrop +=
gcnew DragEventHandler(this, &Form1::TextBoxInput_DragDrop);
TextBoxInput->DragOver +=
gcnew DragEventHandler(this, &Form1::TextBoxInput_DragOver);
gcnew DragEventHandler(this, &Form1::TextBoxInput_DragOver);
TextBoxInput->DragLeave +=
gcnew EventHandler(this, &Form1::TextBoxInput_DragLeave);
TextBoxInput->Enter +=
gcnew EventHandler(this, &Form1::TextBoxInput_Enter);
TextBoxInput->Leave +=
gcnew EventHandler(this, &Form1::TextBoxInput_Leave);
TextBoxInput->GotFocus +=
gcnew EventHandler(this, &Form1::TextBoxInput_GotFocus);
TextBoxInput->LostFocus +=
gcnew EventHandler(this, &Form1::TextBoxInput_LostFocus);
TextBoxInput->Validated +=
gcnew EventHandler(this, &Form1::TextBoxInput_Validated);
TextBoxInput->Validating +=
gcnew CancelEventHandler(this,
&Form1::TextBoxInput_Validating);
LinkLabelDrag->MouseDown +=
gcnew MouseEventHandler(this, &Form1::LinkLabelDrag_MouseDown);
LinkLabelDrag->GiveFeedback +=
gcnew GiveFeedbackEventHandler(this,
&Form1::LinkLabelDrag_GiveFeedback);
CheckBoxToggleAll->CheckedChanged +=
gcnew EventHandler(this,
&Form1::CheckBoxToggleAll_CheckedChanged);
CheckBoxMouse->CheckedChanged +=
gcnew EventHandler(this, &Form1::CheckBoxMouse_CheckedChanged);
CheckBoxMouseDrag->CheckedChanged +=
gcnew EventHandler(this,
&Form1::CheckBoxMouseDrag_CheckedChanged);
CheckBoxMouseEnter->CheckedChanged +=
gcnew EventHandler(this,
&Form1::CheckBoxMouseMove_CheckedChanged);
CheckBoxMouseMove->CheckedChanged +=
gcnew EventHandler(this,
&Form1::CheckBoxMouseMove_CheckedChanged);
CheckBoxKeyboard->CheckedChanged +=
gcnew EventHandler(this,
&Form1::CheckBoxKeyboard_CheckedChanged);
this->GroupBoxEvents->ResumeLayout(false);
this->GroupBoxEvents->PerformLayout();
this->ResumeLayout(false);
this->PerformLayout();
CheckAllChildCheckBoxes(this, true);
}
// Click event handler for the button that clears the text box.
private:
void ButtonClear_Click(Object^ sender, EventArgs^ e)
{
TextBoxOutput->Invalidate();
TextBoxOutput->Clear();
}
private:
void TextBoxInput_KeyDown(Object^ sender, KeyEventArgs^ e)
{
if (CheckBoxKeyUpDown->Checked)
{
DisplayLine("KeyDown: " + e->KeyData.ToString());
}
}
private:
void TextBoxInput_KeyUp(Object^ sender, KeyEventArgs^ e)
{
if (CheckBoxKeyUpDown->Checked)
{
DisplayLine("KeyUp: " + e->KeyData.ToString());
}
}
private:
void TextBoxInput_KeyPress(Object^ sender,
KeyPressEventArgs^ e)
{
if (CheckBoxKeyboard->Checked)
{
if (Char::IsWhiteSpace(e->KeyChar))
{
DisplayLine("KeyPress: WS");
}
else
{
DisplayLine("KeyPress: " + e->KeyChar.ToString());
}
}
}
private:
void TextBoxInput_Click(Object^ sender, EventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("Click event");
}
}
private:
void TextBoxInput_DoubleClick(Object^ sender, EventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("DoubleClick event");
}
}
private:
void TextBoxInput_MouseClick(Object^ sender, MouseEventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("MouseClick: " + e->Button.ToString() +
" " + e->Location.ToString());
}
}
private:
void TextBoxInput_MouseDoubleClick(Object^ sender,
MouseEventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("MouseDoubleClick: " + e->Button.ToString() +
" " + e->Location.ToString());
}
}
private:
void TextBoxInput_MouseDown(Object^ sender,
MouseEventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("MouseDown: " + e->Button.ToString() +
" " + e->Location.ToString());
}
}
private:
void TextBoxInput_MouseUp(Object^ sender,
MouseEventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("MouseUp: " + e->Button.ToString() +
" " + e->Location.ToString());
}
private:
void TextBoxInput_MouseEnter(Object^ sender, EventArgs^ e)
{
if (CheckBoxMouseEnter->Checked)
{
DisplayLine("MouseEnter event");
}
}
private:
void TextBoxInput_MouseHover(Object^ sender, EventArgs^ e)
{
if (CheckBoxMouseEnter->Checked)
{
DisplayLine("MouseHover event");
}
}
}
private:
void TextBoxInput_MouseLeave(Object^ sender, EventArgs^ e)
{
if (CheckBoxMouseEnter->Checked)
{
DisplayLine("MouseLeave event");
}
}
private:
void TextBoxInput_MouseWheel(Object^ sender,
MouseEventArgs^ e)
{
if (CheckBoxMouse->Checked)
{
DisplayLine("MouseWheel: " + e->Delta.ToString() +
" detents at " + e->Location.ToString());
}
}
private:
void TextBoxInput_MouseMove(Object^ sender,
MouseEventArgs^ e)
{
if (CheckBoxMouseMove->Checked)
{
DisplayLine("MouseMove: " + e->Button.ToString() + " " +
e->Location.ToString());
}
if (CheckBoxMousePoints->Checked)
{
Graphics^ g = TextBoxInput->CreateGraphics();
g->FillRectangle(Brushes::Black, e->Location.X,
e->Location.Y, 1, 1);
delete g;
}
}
private:
void TextBoxInput_MouseCaptureChanged(Object^ sender,
EventArgs^ e)
{
if (CheckBoxMouseDrag->Checked)
{
DisplayLine("MouseCaptureChanged event");
}
}
private:
void TextBoxInput_DragEnter(Object^ sender, DragEventArgs^ e)
{
if (CheckBoxMouseDrag->Checked)
{
Point^ pt = gcnew Point(e->X, e->Y);
DisplayLine("DragEnter: " +
CovertKeyStateToString(e->KeyState)
+ " at " + pt->ToString());
}
}
private:
void TextBoxInput_DragDrop(Object^ sender, DragEventArgs^ e)
{
if (CheckBoxMouseDrag->Checked)
{
Point^ pt = gcnew Point(e->X, e->Y);
DisplayLine("DragDrop: " +
DisplayLine("DragDrop: " +
CovertKeyStateToString(e->KeyState)
+ " at " + pt->ToString());
}
}
private:
void TextBoxInput_DragOver(Object^ sender, DragEventArgs^ e)
{
if (CheckBoxMouseDragOver->Checked)
{
Point^ pt = gcnew Point(e->X, e->Y);
DisplayLine("DragOver: " +
CovertKeyStateToString(e->KeyState)
+ " at " + pt->ToString());
}
private:
void TextBoxInput_DragLeave(Object^ sender,
EventArgs^ e)
{
if (CheckBoxMouseDrag->Checked)
{
DisplayLine("DragLeave event");
}
}
private:
static String^ CovertKeyStateToString(int keyState)
{
String^ keyString = "None";
if ((keyState & 8) == 8)
{
keyString += "+CTRL";
}
return keyString;
}
private:
void TextBoxInput_Enter(Object^ sender, EventArgs^ e)
{
if (CheckBoxFocus->Checked)
{
DisplayLine("Enter event");
}
}
private:
void TextBoxInput_Leave(Object^ sender, EventArgs^ e)
{
if (CheckBoxFocus->Checked)
{
DisplayLine("Leave event");
}
}
private:
void TextBoxInput_GotFocus(Object^ sender, EventArgs^ e)
{
if (CheckBoxFocus->Checked)
{
DisplayLine("GotFocus event");
}
}
private:
void TextBoxInput_LostFocus(Object^ sender, EventArgs^ e)
{
if (CheckBoxFocus->Checked)
{
DisplayLine("LostFocus event");
}
}
private:
void TextBoxInput_Validated(Object^ sender, EventArgs^ e)
{
if (CheckBoxValidation->Checked)
{
DisplayLine("Validated event");
}
}
private:
void TextBoxInput_Validating(
Object^ sender, CancelEventArgs^ e)
{
if (CheckBoxValidation->Checked)
{
DisplayLine("Validating event");
}
}
private:
void CheckBoxToggleAll_CheckedChanged(
Object^ sender, EventArgs^ e)
{
if (dynamic_cast<CheckBox^>(sender))
{
CheckAllChildCheckBoxes(this, ((CheckBox^)sender)->Checked);
}
}
}
private:
void CheckBoxMouse_CheckedChanged(
Object^ sender, EventArgs^ e)
{
ConfigureCheckBoxSettings();
}
private:
void CheckBoxMouseDrag_CheckedChanged(
Object^ sender, EventArgs^ e)
{
ConfigureCheckBoxSettings();
}
private:
void CheckBoxKeyboard_CheckedChanged(
Object^ sender, EventArgs^ e)
{
ConfigureCheckBoxSettings();
}
private:
void CheckBoxMouseMove_CheckedChanged(
Object^ sender, EventArgs^ e)
{
ConfigureCheckBoxSettings();
}
if (!CheckBoxKeyboard->Checked)
{
CheckBoxKeyUpDown->Enabled = false;
}
else
{
CheckBoxKeyUpDown->Enabled = true;
CheckBoxKeyUpDown->Enabled = true;
}
}
private:
void LinkLabelDrag_MouseDown(Object^ sender, MouseEventArgs^ e)
{
String^ data = "Sample Data";
LinkLabelDrag->DoDragDrop(data, DragDropEffects::All);
}
private:
void LinkLabelDrag_GiveFeedback(Object^ sender,
GiveFeedbackEventArgs^ e)
{
if ((e->Effect & DragDropEffects::Copy) ==
DragDropEffects::Copy)
{
LinkLabelDrag->Cursor = Cursors::HSplit;
}
else
{
LinkLabelDrag->Cursor = Cursors::Default;
}
}
};
}
[STAThread]
int main()
{
Application::EnableVisualStyles();
Application::Run(gcnew UserInputWalkthrough::Form1());
}
using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
namespace UserInputWalkthrough
{
public class Form1 : Form
{
Label Label1 = new Label();
Label Label2 = new Label();
TextBox TextBoxOutput = new TextBox();
TextBox TextBoxInput = new TextBox();
GroupBox GroupBoxEvents = new GroupBox();
Button ButtonClear = new Button();
LinkLabel LinkLabelDrag = new LinkLabel();
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
: base()
{
this.Load += new EventHandler(Form1_Load);
}
LinkLabelDrag.AllowDrop = true;
LinkLabelDrag.AutoSize = true;
LinkLabelDrag.Location = new Point(13, 240);
LinkLabelDrag.Size = new Size(175, 14);
LinkLabelDrag.TabIndex = 2;
LinkLabelDrag.TabStop = true;
LinkLabelDrag.Text = "Click here to use as a drag source";
LinkLabelDrag.Links.Add(new LinkLabel.Link(0,
LinkLabelDrag.Text.Length));
CheckBoxToggleAll.AutoSize = true;
CheckBoxToggleAll.Location = new Point(7, 20);
CheckBoxToggleAll.Size = new Size(122, 17);
CheckBoxToggleAll.TabIndex = 4;
CheckBoxToggleAll.Text = "Toggle All Events";
CheckBoxMouse.AutoSize = true;
CheckBoxMouse.Location = new Point(7, 45);
CheckBoxMouse.Size = new Size(137, 17);
CheckBoxMouse.TabIndex = 5;
CheckBoxMouse.TabIndex = 5;
CheckBoxMouse.Text = "Mouse and Click Events";
CheckBoxMouseEnter.AutoSize = true;
CheckBoxMouseEnter.Location = new Point(26, 69);
CheckBoxMouseEnter.Margin = new Padding(3, 3, 3, 1);
CheckBoxMouseEnter.Size = new System.Drawing.Size(151, 17);
CheckBoxMouseEnter.TabIndex = 6;
CheckBoxMouseEnter.Text = "Mouse Enter/Hover/Leave";
CheckBoxMouseMove.AutoSize = true;
CheckBoxMouseMove.Location = new Point(26, 89);
CheckBoxMouseMove.Margin = new Padding(3, 2, 3, 3);
CheckBoxMouseMove.Size = new Size(120, 17);
CheckBoxMouseMove.TabIndex = 7;
CheckBoxMouseMove.Text = "Mouse Move Events";
CheckBoxMousePoints.AutoSize = true;
CheckBoxMousePoints.Location = new Point(26, 112);
CheckBoxMousePoints.Margin = new Padding(3, 3, 3, 1);
CheckBoxMousePoints.Size = new Size(141, 17);
CheckBoxMousePoints.TabIndex = 8;
CheckBoxMousePoints.Text = "Draw Mouse Points";
CheckBoxMouseDrag.AutoSize = true;
CheckBoxMouseDrag.Location = new Point(26, 135);
CheckBoxMouseDrag.Margin = new Padding(3, 1, 3, 3);
CheckBoxMouseDrag.Size = new Size(151, 17);
CheckBoxMouseDrag.TabIndex = 9;
CheckBoxMouseDrag.Text = "Mouse Drag && Drop Events";
CheckBoxMouseDragOver.AutoSize = true;
CheckBoxMouseDragOver.Location = new Point(44, 159);
CheckBoxMouseDragOver.Size = new Size(142, 17);
CheckBoxMouseDragOver.TabIndex = 10;
CheckBoxMouseDragOver.Text = "Mouse Drag Over Events";
CheckBoxKeyboard.AutoSize = true;
CheckBoxKeyboard.Location = new Point(8, 184);
CheckBoxKeyboard.Size = new Size(103, 17);
CheckBoxKeyboard.TabIndex = 11;
CheckBoxKeyboard.Text = "Keyboard Events";
CheckBoxKeyUpDown.AutoSize = true;
CheckBoxKeyUpDown.Location = new Point(26, 207);
CheckBoxKeyUpDown.Margin = new Padding(3, 3, 3, 1);
CheckBoxKeyUpDown.Size = new Size(133, 17);
CheckBoxKeyUpDown.TabIndex = 12;
CheckBoxKeyUpDown.Text = "Key Up && Down Events";
CheckBoxFocus.AutoSize = true;
CheckBoxFocus.Location = new Point(8, 233);
CheckBoxFocus.Margin = new Padding(3, 2, 3, 3);
CheckBoxFocus.Size = new Size(146, 17);
CheckBoxFocus.TabIndex = 13;
CheckBoxFocus.Text = "Focus && Activation Events";
CheckBoxValidation.AutoSize = true;
CheckBoxValidation.Location = new Point(8, 257);
CheckBoxValidation.Size = new Size(104, 17);
CheckBoxValidation.TabIndex = 14;
CheckBoxValidation.Text = "Validation Events";
ButtonClear.Click +=
new EventHandler(ButtonClear_Click);
TextBoxInput.KeyDown +=
new KeyEventHandler(TextBoxInput_KeyDown);
TextBoxInput.KeyPress +=
new KeyPressEventHandler(TextBoxInput_KeyPress);
TextBoxInput.KeyUp +=
new KeyEventHandler(TextBoxInput_KeyUp);
TextBoxInput.Click +=
new EventHandler(TextBoxInput_Click);
TextBoxInput.DoubleClick +=
new EventHandler(TextBoxInput_DoubleClick);
TextBoxInput.MouseClick +=
new MouseEventHandler(TextBoxInput_MouseClick);
TextBoxInput.MouseDoubleClick +=
new MouseEventHandler(TextBoxInput_MouseDoubleClick);
TextBoxInput.MouseDown +=
new MouseEventHandler(TextBoxInput_MouseDown);
TextBoxInput.MouseUp +=
new MouseEventHandler(TextBoxInput_MouseUp);
TextBoxInput.MouseEnter +=
new EventHandler(TextBoxInput_MouseEnter);
TextBoxInput.MouseHover +=
new EventHandler(TextBoxInput_MouseHover);
TextBoxInput.MouseLeave +=
new EventHandler(TextBoxInput_MouseLeave);
TextBoxInput.MouseWheel +=
new MouseEventHandler(TextBoxInput_MouseWheel);
TextBoxInput.MouseMove +=
new MouseEventHandler(TextBoxInput_MouseMove);
TextBoxInput.MouseCaptureChanged +=
new EventHandler(TextBoxInput_MouseCaptureChanged);
TextBoxInput.DragEnter +=
new DragEventHandler(TextBoxInput_DragEnter);
TextBoxInput.DragDrop +=
new DragEventHandler(TextBoxInput_DragDrop);
TextBoxInput.DragOver +=
new DragEventHandler(TextBoxInput_DragOver);
TextBoxInput.DragLeave +=
new EventHandler(TextBoxInput_DragLeave);
TextBoxInput.Enter +=
new EventHandler(TextBoxInput_Enter);
TextBoxInput.Leave +=
new EventHandler(TextBoxInput_Leave);
TextBoxInput.GotFocus +=
new EventHandler(TextBoxInput_GotFocus);
TextBoxInput.LostFocus +=
new EventHandler(TextBoxInput_LostFocus);
TextBoxInput.Validated +=
new EventHandler(TextBoxInput_Validated);
TextBoxInput.Validating +=
TextBoxInput.Validating +=
new CancelEventHandler(TextBoxInput_Validating);
LinkLabelDrag.MouseDown +=
new MouseEventHandler(LinkLabelDrag_MouseDown);
LinkLabelDrag.GiveFeedback +=
new GiveFeedbackEventHandler(LinkLabelDrag_GiveFeedback);
CheckBoxToggleAll.CheckedChanged +=
new EventHandler(CheckBoxToggleAll_CheckedChanged);
CheckBoxMouse.CheckedChanged +=
new EventHandler(CheckBoxMouse_CheckedChanged);
CheckBoxMouseDrag.CheckedChanged +=
new EventHandler(CheckBoxMouseDrag_CheckedChanged);
CheckBoxMouseEnter.CheckedChanged +=
new EventHandler(CheckBoxMouseMove_CheckedChanged);
CheckBoxMouseMove.CheckedChanged +=
new EventHandler(CheckBoxMouseMove_CheckedChanged);
CheckBoxKeyboard.CheckedChanged +=
new EventHandler(CheckBoxKeyboard_CheckedChanged);
this.GroupBoxEvents.ResumeLayout(false);
this.GroupBoxEvents.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
CheckAllChildCheckBoxes(this, true);
}
// Click event handler for the button that clears the text box.
private void ButtonClear_Click(object sender, EventArgs e)
{
TextBoxOutput.Invalidate();
TextBoxOutput.Clear();
}
if (CheckBoxMousePoints.Checked)
{
Graphics g = TextBoxInput.CreateGraphics();
g.FillRectangle(Brushes.Black, e.Location.X,
e.Location.Y, 1, 1);
g.Dispose();
}
}
}
if ((keyState & 8) == 8)
{
keyString += "+CTRL";
}
return keyString;
}
if (!CheckBoxKeyboard.Checked)
{
CheckBoxKeyUpDown.Enabled = false;
}
else
{
CheckBoxKeyUpDown.Enabled = true;
}
}
Imports System
Imports System.Drawing
Imports System.ComponentModel
Imports System.Windows.Forms
Namespace UserInputWalkthrough
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.Run(New Form1())
End Sub
Me.GroupBoxEvents.SuspendLayout()
Me.SuspendLayout()
LinkLabelDrag.AllowDrop = True
LinkLabelDrag.AutoSize = True
LinkLabelDrag.Location = New Point(13, 240)
LinkLabelDrag.Size = New Size(175, 14)
LinkLabelDrag.TabIndex = 2
LinkLabelDrag.TabStop = True
LinkLabelDrag.Text = "Click here to use as a drag source"
LinkLabelDrag.Links.Add(New LinkLabel.Link(0, _
LinkLabelDrag.Text.Length))
CheckBoxToggleAll.AutoSize = True
CheckBoxToggleAll.Location = New Point(7, 20)
CheckBoxToggleAll.Location = New Point(7, 20)
CheckBoxToggleAll.Size = New Size(122, 17)
CheckBoxToggleAll.TabIndex = 4
CheckBoxToggleAll.Text = "Toggle All Events"
CheckBoxMouse.AutoSize = True
CheckBoxMouse.Location = New Point(7, 45)
CheckBoxMouse.Size = New Size(137, 17)
CheckBoxMouse.TabIndex = 5
CheckBoxMouse.Text = "Mouse and Click Events"
CheckBoxMouseEnter.AutoSize = True
CheckBoxMouseEnter.Location = New Point(26, 69)
CheckBoxMouseEnter.Margin = New Padding(3, 3, 3, 1)
CheckBoxMouseEnter.Size = New System.Drawing.Size(151, 17)
CheckBoxMouseEnter.TabIndex = 6
CheckBoxMouseEnter.Text = "Mouse Enter/Hover/Leave"
CheckBoxMouseMove.AutoSize = True
CheckBoxMouseMove.Location = New Point(26, 89)
CheckBoxMouseMove.Margin = New Padding(3, 2, 3, 3)
CheckBoxMouseMove.Size = New Size(120, 17)
CheckBoxMouseMove.TabIndex = 7
CheckBoxMouseMove.Text = "Mouse Move Events"
CheckBoxMousePoints.AutoSize = True
CheckBoxMousePoints.Location = New Point(26, 112)
CheckBoxMousePoints.Margin = New Padding(3, 3, 3, 1)
CheckBoxMousePoints.Size = New Size(141, 17)
CheckBoxMousePoints.TabIndex = 8
CheckBoxMousePoints.Text = "Draw Mouse Points"
CheckBoxMouseDrag.AutoSize = True
CheckBoxMouseDrag.Location = New Point(26, 135)
CheckBoxMouseDrag.Margin = New Padding(3, 1, 3, 3)
CheckBoxMouseDrag.Size = New Size(151, 17)
CheckBoxMouseDrag.TabIndex = 9
CheckBoxMouseDrag.Text = "Mouse Drag && Drop Events"
CheckBoxMouseDragOver.AutoSize = True
CheckBoxMouseDragOver.Location = New Point(44, 159)
CheckBoxMouseDragOver.Size = New Size(142, 17)
CheckBoxMouseDragOver.TabIndex = 10
CheckBoxMouseDragOver.Text = "Mouse Drag Over Events"
CheckBoxKeyboard.AutoSize = True
CheckBoxKeyboard.Location = New Point(8, 184)
CheckBoxKeyboard.Size = New Size(103, 17)
CheckBoxKeyboard.TabIndex = 11
CheckBoxKeyboard.Text = "Keyboard Events"
CheckBoxKeyUpDown.AutoSize = True
CheckBoxKeyUpDown.Location = New Point(26, 207)
CheckBoxKeyUpDown.Margin = New Padding(3, 3, 3, 1)
CheckBoxKeyUpDown.Size = New Size(133, 17)
CheckBoxKeyUpDown.TabIndex = 12
CheckBoxKeyUpDown.Text = "Key Up && Down Events"
CheckBoxFocus.AutoSize = True
CheckBoxFocus.Location = New Point(8, 233)
CheckBoxFocus.Margin = New Padding(3, 2, 3, 3)
CheckBoxFocus.Size = New Size(146, 17)
CheckBoxFocus.TabIndex = 13
CheckBoxFocus.Text = "Focus && Activation Events"
CheckBoxValidation.AutoSize = True
CheckBoxValidation.Location = New Point(8, 257)
CheckBoxValidation.Size = New Size(104, 17)
CheckBoxValidation.TabIndex = 14
CheckBoxValidation.Text = "Validation Events"
CheckBoxValidation.Text = "Validation Events"
Me.GroupBoxEvents.ResumeLayout(False)
Me.GroupBoxEvents.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
CheckAllChildCheckBoxes(Me, True)
End Sub
' Recursively search the form for all contained checkboxes and
' initially check them
Private Sub CheckAllChildCheckBoxes(ByRef parent As Control, _
ByVal value As Boolean)
TextBoxOutput.AppendText(line)
TextBoxOutput.AppendText(ControlChars.NewLine)
End Sub
' Click event handler for the button that clears the text box.
Private Sub ButtonClear_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles ButtonClear.Click
TextBoxOutput.Invalidate()
TextBoxOutput.Clear()
End Sub
If Char.IsWhiteSpace(e.KeyChar) Then
Dim keyVal As Integer
keyVal = AscW(e.KeyChar)
DisplayLine("KeyPress: WS-" + keyVal.ToString())
Else
DisplayLine("KeyPress: " + e.KeyChar.ToString())
End If
End If
End Sub
Dim pt As Point
If CheckBoxMouseDrag.Checked = True Then
pt = New Point(e.X, e.Y)
DisplayLine("DragEnter: " + _
CovertKeyStateToString(e.KeyState) _
+ " at " + pt.ToString())
End If
End Sub
DisplayLine("DragDrop: " + _
CovertKeyStateToString(e.KeyState) _
+ " at " + pt.ToString())
End If
End Sub
Return keyString
End Function
Dim cb As CheckBox
cb = TryCast(sender, CheckBox)
If cb IsNot Nothing Then
CheckAllChildCheckBoxes(Me, cb.Checked)
End If
End Sub
ConfigureCheckBoxSettings()
End Sub
ConfigureCheckBoxSettings()
End Sub
ConfigureCheckBoxSettings()
End Sub
ConfigureCheckBoxSettings()
End Sub
End Class
End Namespace
See also
User Input in Windows Forms
User Input Validation in Windows Forms
4/28/2019 • 6 minutes to read • Edit Online
When users enter data into your application, you may want to verify that the data is valid before your application
uses it. You may require that certain text fields not be zero-length, that a field be formatted as a telephone number
or other type of well-formed data, or that a string not contain any unsafe characters that could be used to
compromise the security of a database. Windows Forms provides several ways for you to validate input in your
application.
Event-Driven Validation
If you want full programmatic control over validation, or need to perform complex validation checks, you should
use the validation events built into most Windows Forms controls. Each control that accepts free-form user input
has a Validating event that will occur whenever the control requires data validation. In the Validating event-
handling method, you can validate user input in several ways. For example, if you have a text box that must contain
a postal code, you can perform the validation in the following ways:
If the postal code must belong to a specific group of zip codes, you can perform a string comparison on the
input to validate the data entered by the user. For example, if the postal code must be in the set {10001,
10002, 10003}, then you can use a string comparison to validate the data.
If the postal code must be in a specific form you can use regular expressions to validate the data entered by
the user. For example, to validate the form ##### or #####-#### , you can use the regular expression
^(\d{5})(-\d{4})?$ . To validate the form A#A #A# , you can use the regular expression
[A-Z]\d[A-Z] \d[A-Z]\d . For more information about regular expressions, see .NET Framework Regular
Expressions and Regular Expression Examples.
If the postal code must be a valid United States Zip code, you could call a Zip code Web service to validate
the data entered by the user.
The Validating event is supplied an object of type CancelEventArgs. If you determine that the control's data is not
valid, you can cancel the Validating event by setting this object's Cancel property to true . If you do not set the
Cancel property, Windows Forms will assume that validation succeeded for that control, and raise the Validated
event.
For a code example that validates an email address in a TextBox, see Validating.
Data Binding and Event-Driven Validation
Validation is very useful when you have bound your controls to a data source, such as a database table. By using
validation, you can make sure that your control's data satisfies the format required by the data source, and that it
does not contain any special characters such as quotation marks and back slashes that might be unsafe.
When you use data binding, the data in your control is synchronized with the data source during execution of the
Validating event. If you cancel the Validating event, the data will not be synchronized with the data source.
IMPORTANT
If you have custom validation that takes place after the Validating event, it will not affect the data binding. For example, if
you have code in a Validated event that attempts to cancel the data binding, the data binding will still occur. In this case, to
perform validation in the Validated event, change the control's Data Source Update Mode property ( under
(Databindings)\(Advanced)) from OnValidation to Never, and add Control .DataBindings[" <YOURFIELD>
"].WriteValue() to your validation code.
ContainerControl Inherit
Form EnableAllowFocusChange
CONTROL DEFAULT VALIDATION BEHAVIOR
SplitContainer Inherit
UserControl EnableAllowFocusChange
NOTE
If you force the form to close in this manner, any data in the form's controls that has not already been saved is lost. In
addition, modal forms do not validate the contents of controls when they are closed. You can still use control validation to
lock focus to a control, but you do not have to be concerned about the behavior associated with closing the form.
See also
Control.Validating
Form.Closing
System.ComponentModel.CancelEventArgs
MaskedTextBox Control
Regular Expression Examples
Dialog Boxes in Windows Forms
3/9/2019 • 2 minutes to read • Edit Online
Dialog boxes are used to interact with the user and retrieve information. In simple terms, a dialog box is a form
with its FormBorderStyle enumeration property set to FixedDialog . You can construct your own custom dialog
boxes by using the Windows Forms Designer in Visual Studio. Add controls such as Label , Textbox , and Button
to customize dialog boxes to your specific needs. The .NET Framework also includes predefined dialog boxes, such
as File Open and message boxes, which you can adapt for your own applications. For more information, see
Dialog-Box Controls and Components.
In This Section
How to: Display Dialog Boxes for Windows Forms
Gives directions for showing dialog boxes.
Related Sections
Dialog-Box Controls and Components
Lists the predefined dialog box controls.
Changing the Appearance of Windows Forms
Contains links to topics that describe how to change the appearance of Windows Forms applications.
TabControl Control Overview
Explains how you incorporate the tab control into a dialog box.
How to: Display Dialog Boxes for Windows Forms
4/9/2019 • 2 minutes to read • Edit Online
You display a dialog box in the same way you display any other form in an application. The startup form loads
automatically when the application is run. To make a second form or dialog box appear in the application, write
code to load and display it. Similarly, to make the form or dialog box disappear, write code to unload or hide it.
To display a dialog box
1. Navigate to the event handler with which you want to open the dialog box. This can happen when a menu
command is selected, when a button is clicked, or when any other event occurs.
2. In the event handler, add code to open the dialog box. In this example, a button-click event is used to show
the dialog box:
private:
void button1_Click(System::Object ^ sender,
System::EventArgs ^ e)
{
Form ^ dlg1 = gcnew Form();
dlg1->ShowDialog();
}
Windows Forms Data Binding
3/9/2019 • 2 minutes to read • Edit Online
Data binding in Windows Forms gives you the means to display and make changes to information from a data
source in controls on the form. You can bind to both traditional data sources as well as almost any structure that
contains data.
In This Section
Data Binding and Windows Forms
Provides an overview of data binding in Windows Forms.
Data Sources Supported by Windows Forms
Describes the data sources that can be used with Windows Forms.
Interfaces Related to Data Binding
Describes several of the interfaces used with Windows Forms data binding.
How to: Navigate Data in Windows Forms
Shows how to navigate through items in a data source.
Change Notification in Windows Forms Data Binding
Describes different types of change notification for Windows Forms data binding.
How to: Implement the INotifyPropertyChanged Interface
Shows how to implement the INotifyPropertyChanged interface. The interface communicates to a bound control
the property changes on a business object
How to: Apply the PropertyNameChanged Pattern
Shows how to apply the PropertyNameChanged pattern to properties of a Windows Forms user control.
How to: Implement the ITypedList Interface
Shows how to enable discovery of the schema for a bindable list by implementing the ITypedList interface.
How to: Implement the IListSource Interface
Shows how to implement the IListSource interface to create a bindable class does not implement IList, but
provides a list from another location.
How to: Ensure Multiple Controls Bound to the Same Data Source Remain Synchronized
Shows how to handle the BindingComplete event to ensure all controls bound to a data source remain
synchronized.
How to: Ensure the Selected Row in a Child Table Remains at the Correct Position
Shows how to ensure the selected row of a child table does not change, when a change is made to a field of the
parent table.
Also see Interfaces Related to Data Binding, How to: Navigate Data in Windows Forms, and How to: Create a
Simple-Bound Control on a Windows Form.
Reference
System.Windows.Forms.Binding
Describes the class that represents the binding between a bindable component and a data source.
System.Windows.Forms.BindingSource
Describes the class that encapsulates a data source for binding to controls.
Related Sections
BindingSource Component
Contains a list of topics that demonstrate how to use the BindingSource component.
DataGridView Control
Provides a list of topics that demonstrate how to use a bindable datagrid control.
Also see Accessing Data in Visual Studio.
Data Binding and Windows Forms
4/28/2019 • 4 minutes to read • Edit Online
In Windows Forms, you can bind to not just traditional data sources, but also to almost any structure that contains
data. You can bind to an array of values that you calculate at run time, read from a file, or derive from the values of
other controls.
In addition, you can bind any property of any control to the data source. In traditional data binding, you typically
bind the display property—for example, the Text property of a TextBox control—to the data source. With the .NET
Framework, you also have the option of setting other properties through binding as well. You might use binding
to perform the following tasks:
Setting the graphic of an image control.
Setting the background color of one or more controls.
Setting the size of controls.
Essentially, data binding is an automatic way of setting any run-time accessible property of any control on a form.
Simple data binding The ability of a control to bind to a single data element, such
as a value in a column in a dataset table. This is the type of
binding typical for controls such as a TextBox control or Label
control, which are controls that typically only displays a single
value. In fact, any property on a control can be bound to a
field in a database. There is extensive support for this feature
in Visual Studio.
Complex data binding The ability of a control to bind to more than one data
element, typically more than one record in a database.
Complex binding is also called list-based binding. Examples of
controls that support complex binding are the DataGridView,
ListBox, and ComboBox controls. For an example of complex
data binding, see How to: Bind a Windows Forms ComboBox
or ListBox Control to Data.
BindingSource Component
To simplify data binding, Windows Forms enables you to bind a data source to the BindingSource component and
then bind controls to the BindingSource. You can use the BindingSource in simple or complex binding scenarios.
In either case, the BindingSource acts as an intermediary between the data source and bound controls providing
change notification currency management and other services.
SCENARIO DESCRIPTION
See also
Binding
Windows Forms Data Binding
How to: Bind the Windows Forms DataGrid Control to a Data Source
BindingSource Component
Data Sources Supported by Windows Forms
4/28/2019 • 3 minutes to read • Edit Online
Traditionally, data binding has been used within applications to take advantage of data stored in databases. With
Windows Forms data binding, you can access data from databases as well as data in other structures, such as
arrays and collections, so long as certain minimum requirements have been met.
Structures to Bind To
In Windows Forms, you can bind to a wide variety of structures, from simple objects (simple binding) to complex
lists such as ADO.NET data tables (complex binding). For simple binding, Windows Forms supports binding to the
public properties on the simple object. Windows Forms list-based binding generally requires that the object
support the IList interface or the IListSource interface. Additionally, if you are binding with through a
BindingSource component, you can bind to an object that supports the IEnumerable interface. For more
information about interfaces related to data binding, see Interfaces Related to Data Binding.
The following list shows the structures you can bind to in Windows Forms.
BindingSource
A BindingSource is the most common Windows Forms data source and acts a proxy between a data source and
Windows Forms controls. The general BindingSource usage pattern is to bind your controls to the BindingSource
and bind the BindingSource to the data source (for example, an ADO.NET data table or a business object). The
BindingSource provides services that enable and improve the level of data binding support. For example,
Windows Forms list based controls such as the DataGridView and ComboBox do not directly support binding to
IEnumerable data sources however, you can enable this scenario by binding through a BindingSource. In this case,
the BindingSource will convert the data source to an IList.
Simple objects
Windows Forms supports data binding control properties to public properties on the instance of an object using
the Binding type. Windows Forms also supports binding list based controls, such as a ListControl to an object
instance when a BindingSource is used.
array or collection
To act as a data source, a list must implement the IList interface; one example would be an array that is an instance
of the Array class. For more information on arrays, see How to: Create an Array of Objects (Visual Basic).
In general, you should use BindingList<T> when you create lists of objects for data binding. BindingList<T> is a
generic version of the IBindingList interface. The IBindingList interface extends the IList interface by adding
properties, methods and events necessary for two-way data binding.
IEnumerable
Windows Forms controls can be bound to data sources that only support the IEnumerable interface if they are
bound through a BindingSource component.
ADO.NET data objects
ADO.NET provides a number of data structures suitable for binding to. Each varies in its sophistication and
complexity.
DataColumn. A DataColumn is the essential building block of a DataTable, in that a number of columns
comprise a table. Each DataColumn has a DataType property that determines the kind of data the column
holds (for example, the make of an automobile in a table describing cars). You can simple-bind a control
(such as a TextBox control's Text property) to a column within a data table.
DataTable. A DataTable is the representation of a table, with rows and columns, in ADO.NET. A data table
contains two collections: DataColumn, representing the columns of data in a given table (which ultimately
determine the kinds of data that can be entered into that table), and DataRow, representing the rows of data
in a given table. You can complex-bind a control to the information contained in a data table (such as
binding the DataGridView control to a data table). However, when you bind to a DataTable, you are a really
binding to the table's default view.
DataView. A DataView is a customized view of a single data table that may be filtered or sorted. A data view
is the data "snapshot" used by complex-bound controls. You can simple-bind or complex-bind to the data
within a data view, but be aware that you are binding to a fixed "picture" of the data rather than a clean,
updating data source.
DataSet. A DataSet is a collection of tables, relationships, and constraints of the data in a database. You can
simple-bind or complex-bind to the data within a dataset, but be aware that you are binding to the default
DataViewManager for the DataSet (see the next bullet point).
DataViewManager. A DataViewManager is a customized view of the entire DataSet, analogous to a
DataView, but with relations included. With a DataViewSettings collection, you can set default filters and
sort options for any views that the DataViewManager has for a given table.
See also
Change Notification in Windows Forms Data Binding
Data Binding and Windows Forms
Windows Forms Data Binding
Interfaces Related to Data Binding
4/26/2019 • 7 minutes to read • Edit Online
With ADO.NET, you can create many different data structures to suit the binding needs of your application and
the data you are working with. You may want to create your own classes that provide or consume data in
Windows Forms. These objects can offer varying levels of functionality and complexity, from basic data binding, to
providing design-time support, error checking, change notification, or even support for a structured rollback of
the changes made to the data itself.
NOTE
If you want to create a list of business objects for binding with Windows Forms, you should consider using the
BindingList<T>. The BindingList<T> is an extensible class that implements the primary interfaces required for two-
way Windows Forms data binding.
IBindingList interface
A class that implements the IBindingList interface provides a much higher level of data-binding
functionality. This implementation offers you basic sorting capabilities and change notification, both for
when the list items change (for example, the third item in a list of customers has a change to the Address
field), as well as when the list itself changes (for example, the number of items in the list increases or
decreases). Change notification is important if you plan to have multiple controls bound to the same data,
and you want data changes made in one of the controls to propagate to the other bound controls.
NOTE
Change notification is enabled for the IBindingList interface through the SupportsChangeNotification property
which, when true , raises a ListChanged event, indicating the list changed or an item in the list changed.
The type of change is described by the ListChangedType property of the ListChangedEventArgs parameter.
Hence, whenever the data model is updated, any dependent views, such as other controls bound to the
same data source, will also be updated. However, objects contained within the list will have to notify the list
when they change so that the list can raise the ListChanged event.
NOTE
The BindingList<T> provides a generic implementation of the IBindingList interface.
IBindingListView interface
A class that implements the IBindingListView interface provides all the functionality of an implementation
of IBindingList, as well as filtering and advanced sorting functionality. This implementation offers string-
based filtering, and multicolumn sorting with property descriptor-direction pairs.
IEditableObject interface
A class that implements the IEditableObject interface allows an object to control when changes to that
object are made permanent. This implementation affords you the BeginEdit, EndEdit, and CancelEdit
methods, which enable you to roll back changes made to the object. Following is a brief explanation of the
functioning of the BeginEdit, EndEdit, and CancelEdit methods and how they work in conjunction with one
another to enable a possible rollback of changes made to the data:
The BeginEdit method signals the start of an edit on an object. An object that implements this
interface will need to store any updates after the BeginEdit method call in such a way that the
updates can be discarded if the CancelEdit method is called. In data binding Windows Forms, you
can call BeginEdit multiple times within the scope of a single edit transaction (for example,
BeginEdit, BeginEdit, EndEdit). Implementations of IEditableObject should keep track of whether
BeginEdit has already been called and ignore subsequent calls to BeginEdit. Because this method
can be called multiple times, it is important that subsequent calls to it are nondestructive; that is,
subsequent BeginEdit calls cannot destroy the updates that have been made or change the data that
was saved on the first BeginEdit call.
The EndEdit method pushes any changes since BeginEdit was called into the underlying object, if the
object is currently in edit mode.
The CancelEdit method discards any changes made to the object.
For more information about how the BeginEdit, EndEdit, and CancelEdit methods work, see Save data back
to the database.
This transactional notion of data functionality is used by the DataGridView control.
ICancelAddNew interface
A class that implements the ICancelAddNew interface usually implements the IBindingList interface and
allows you to roll back an addition made to the data source with the AddNew method. If your data source
implements the IBindingList interface, you should also have it implement the ICancelAddNew interface.
IDataErrorInfo interface
A class that implements the IDataErrorInfo interface allows objects to offer custom error information to
bound controls:
The Error property returns general error message text (for example, "An error has occurred").
The Item[String] property returns a string with the specific error message from the column (for
example, "The value in the State column is invalid").
IEnumerable interface
A class that implements the IEnumerable interface is typically consumed by ASP.NET. Windows Forms
support for this interface is only available through the BindingSource component.
NOTE
The BindingSource component copies all IEnumerable items into a separate list for binding purposes.
ITypedList interface
A collections class that implements the ITypedList interface provides the ability to control the order and the
set of properties exposed to the bound control.
NOTE
When you implement the GetItemProperties method, and the PropertyDescriptor array is not null, the last entry in
the array will be the property descriptor that describes the list property that is another list of items.
ICustomTypeDescriptor interface
A class that implements the ICustomTypeDescriptor interface provides dynamic information about itself.
This interface is similar to ITypedList but is used for objects rather than lists. This interface is used by
DataRowView to project the schema of the underlying rows. A simple implementation of
ICustomTypeDescriptor is provided by the CustomTypeDescriptor class.
NOTE
To support design-time binding to types that implement ICustomTypeDescriptor, the type must also implement
IComponent and exist as an instance on the Form.
IListSource interface
A class that implements the IListSource interface enables list-based binding on non-list objects. The GetList
method of IListSource is used to return a bindable list from an object that does not inherit from IList.
IListSource is used by the DataSet class.
IRaiseItemChangedEvents interface
A class that implements the IRaiseItemChangedEvents interface is a bindable list that also implements the
IBindingList interface. This interface is used to indicate if your type raises ListChanged events of type
ItemChanged through its RaisesItemChangedEvents property.
NOTE
You should implement the IRaiseItemChangedEvents if your data source provides the property to list event
conversion described previously and is interacting with the BindingSource component. Otherwise, the BindingSource
will also perform property to list event conversion resulting in slower performance.
ISupportInitialize interface
A component that implements the ISupportInitialize interface takes advantages of batch optimizations for
setting properties and initializing co-dependent properties. The ISupportInitialize contains two methods:
BeginInit signals that object initialization is starting.
EndInit signals that object initialization is finishing.
ISupportInitializeNotification interface
A component that implements the ISupportInitializeNotification interface also implements the
ISupportInitialize interface. This interface allows you to notify other ISupportInitialize components that
initialization is complete. The ISupportInitializeNotification interface contains two members:
IsInitialized returns a boolean value indicating whether the component is initialized.
Initialized occurs when EndInit is called.
INotifyPropertyChanged interface
A class that implements this interface is a type that raises an event when any of its property values change.
This interface is designed to replace the pattern of having a change event for each property of a control.
When used in a BindingList<T>, a business object should implement the INotifyPropertyChanged
interface and the BindingList`1 will convert PropertyChanged events to ListChanged events of type
ItemChanged.
NOTE
For change notification to occur in a binding between a bound client and a data source your bound data-source
type should either implement the INotifyPropertyChanged interface (preferred) or you can provide propertyName
Changed events for the bound type, but you shouldn't do both.
NOTE
If your component inherits from Control, you do not need to implement the IBindableComponent interface.
ICurrencyManagerProvider interface
A class that implements the ICurrencyManagerProvider interface is a component that provides its own
CurrencyManager to manage the bindings associated with this particular component. Access to the custom
CurrencyManager is provided by the CurrencyManager property.
NOTE
A class that inherits from Control manages bindings automatically through its BindingContext property, so cases in
which you need to implement the ICurrencyManagerProvider are fairly rare.
See also
Data Binding and Windows Forms
How to: Create a Simple-Bound Control on a Windows Form
Windows Forms Data Binding
Change Notification in Windows Forms Data Binding
4/28/2019 • 2 minutes to read • Edit Online
One of the most important concepts of Windows Forms data binding is change notification. To ensure that your
data source and bound controls always have the most recent data, you must add change notification for data
binding. Specifically, you want to ensure that bound controls are notified of changes that were made to their data
source, and the data source is notified of changes that were made to the bound properties of a control.
There are different kinds of change notification, depending on the kind of data binding:
Simple binding, in which a single control property is bound to a single instance of an object.
List-based binding, which can include a single control property bound to the property of an item in a list or
a control property bound to a list of objects.
Additionally, if you are creating Windows Forms controls that you want to use for data binding, you must apply
the PropertyNameChanged pattern to the controls, so that changes to the bound property of a control are
propagated to the data source.
See also
BindingSource
INotifyPropertyChanged
BindingList<T>
Windows Forms Data Binding
Data Sources Supported by Windows Forms
Data Binding and Windows Forms
How to: Apply the PropertyNameChanged Pattern
4/28/2019 • 2 minutes to read • Edit Online
The following code example demonstrates how to apply the PropertyNameChanged pattern to a custom control.
Apply this pattern when you implement custom controls that are used with the Windows Forms data binding
engine.
Example
// 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 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(19, 55);
this.dataGridView1.Size = new System.Drawing.Size(350, 150);
this.dataGridView1.TabIndex = 1;
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(19, 23);
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(350, 216);
}
}
' This class implements a simple user control
' that demonstrates how to apply the propertyNameChanged pattern.
<ComplexBindingProperties("DataSource", "DataMember")> _
Public Class CustomerControl
Inherits UserControl
Private dataGridView1 As DataGridView
Private label1 As Label
Private lastUpdate As DateTime = DateTime.Now
End Sub
See also
How to: Implement the INotifyPropertyChanged Interface
Change Notification in Windows Forms Data Binding
Windows Forms Data Binding
How to: Create a Bound Control and Format the
Displayed Data
4/9/2019 • 2 minutes to read • Edit Online
With Windows Forms data binding, you can format the data displayed in a data-bound control by using the
Formatting and Advanced Binding dialog box.
NOTE
The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings
or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see
Personalize the Visual Studio IDE.
No Formatting No options.
Date Time Select how the date and time should be displayed by
selecting one of the items in the Type selection box.
8. Click OK to close the Formatting and Advanced Binding dialog box and return to the Properties window.
See also
How to: Create a Simple-Bound Control on a Windows Form
User Input Validation in Windows Forms
Windows Forms Data Binding
How to: Create a Simple-Bound Control on a
Windows Form
4/9/2019 • 2 minutes to read • Edit Online
With simple binding, you can display a single data element, such as a column value from a dataset table, in a
control. You can simple-bind any property of a control to a data value.
NOTE
The dialog boxes and menu commands you see might differ from those described in Help depending on your active settings
or edition. To change your settings, choose Import and Export Settings on the Tools menu. For more information, see
Personalize the Visual Studio IDE.
NOTE
Because simple-bound controls show only a single data element, it is very typical to include navigation logic in a
Windows Form with simple-bound controls.
See also
Binding
Windows Forms Data Binding
Data Binding and Windows Forms
How to: Ensure Multiple Controls Bound to the Same
Data Source Remain Synchronized
4/28/2019 • 3 minutes to read • Edit Online
Oftentimes when working with data binding in Windows Forms, multiple controls are bound to the same data
source. In some cases, it may be necessary to take extra steps to ensure that the bound properties of the controls
remain synchronized with each other and the data source. These steps are necessary in two situations:
If the data source does not implement IBindingList, and therefore generate ListChanged events of type
ItemChanged.
If the data source implements IEditableObject.
In the former case, you can use a BindingSource to bind the data source to the controls. In the latter case, you use
a BindingSource and handle the BindingComplete event and call EndCurrentEdit on the associated
BindingManagerBase.
Example
The following code example demonstrates how to bind three controls—two text-box controls and a DataGridView
control—to the same column in a DataSet using a BindingSource component. This example demonstrates how to
handle the BindingComplete event and ensure that when the text value of one text box is changed, the additional
text box and the DataGridView control are updated with the correct value.
The example uses a BindingSource to bind the data source and the controls. Alternatively, you can bind the
controls directly to the data source and retrieve the BindingManagerBase for the binding from the form's
BindingContext and then handle the BindingComplete event for the BindingManagerBase. For an example of how
to do this, see the Help page about the BindingComplete event of BindingManagerBase.
' Check if the data source has been updated, and that no error has occured.
If e.BindingCompleteContext = BindingCompleteContext.DataSourceUpdate _
AndAlso e.Exception Is Nothing Then
End Sub
See also
How to: Share Bound Data Across Forms Using the BindingSource Component
Change Notification in Windows Forms Data Binding
Interfaces Related to Data Binding
Windows Forms Data Binding
How to: Ensure the Selected Row in a Child Table
Remains at the Correct Position
4/28/2019 • 11 minutes to read • Edit Online
Oftentimes when you work with data binding in Windows Forms, you will display data in what is called a
parent/child or master/details view. This refers to a data-binding scenario where data from the same source is
displayed in two controls. Changing the selection in one control causes the data displayed in the second control to
change. For example, the first control might contain a list of customers and the second a list of orders related to the
selected customer in the first control.
Starting with the .NET Framework version 2.0, when you display data in a parent/child view you might have to take
extra steps to make sure that the currently selected row in the child table is not reset to the first row of the table. In
order to do this, you will have to cache the child table position and reset it after the parent table changes. Typically
the child reset occurs the first time a field in a row of the parent table changes.
To Cache the Current Child Position
1. Declare an integer variable to store the child list position and a Boolean variable to store whether to cache
the child position.
2. Handle the ListChanged event for the binding's CurrencyManager and check for a ListChangedType of
Reset.
3. Check the current position of the CurrencyManager. If it is greater than first entry in the list (typically 0),
save it to a variable.
End Sub
4. Handle the parent list's CurrentChanged event for the parent currency manager. In the handler, set the
Boolean value to indicate it is not a caching scenario. If the CurrentChanged occurs, the change to the
parent is a list position change and not an item value change.
' Handle the current changed event. This event occurs when
' the current item is changed, but not when a field of the current
' item is changed.
Private Sub bindingSource1_CurrentChanged(ByVal sender As Object, _
ByVal e As EventArgs) Handles bindingSource1.CurrentChanged
' If the CurrentChanged event occurs, this is not a caching
' situation.
cacheChildPosition = False
End Sub
Example
The following example demonstrates how to save the current position on the CurrencyManager.for a child table
and reset the position after an edit is completed on the parent table. This example contains two DataGridView
controls bound to two tables in a DataSet using a BindingSource component. A relation is established between the
two tables and the relation is added to the DataSet. The position in the child table is initially set to the third row for
demonstration purposes.
using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace BT2
{
public class Form1 : Form
{
public Form1()
{
InitializeControlsAndDataSource();
}
// Set the data source and member for the second DataGridView.
dataGridView2.DataSource = bindingSource1;
dataGridView2.DataMember = "custOrders";
// Handle the two events for caching and resetting the position.
relatedCM.ListChanged += new ListChangedEventHandler(relatedCM_ListChanged);
relatedCM.PositionChanged
+= new EventHandler(relatedCM_PositionChanged);
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Imports System
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
End Sub
Me.dataGridView2.ColumnHeadersHeightSizeMode = _
System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
Me.dataGridView2.Location = New System.Drawing.Point(0, 225)
Me.dataGridView2.Size = New System.Drawing.Size(309, 130)
Me.cachePositionCheckBox.AutoSize = True
Me.cachePositionCheckBox.Checked = True
Me.cachePositionCheckBox.Location = New System.Drawing.Point(150, 175)
Me.cachePositionCheckBox.Name = "radioButton1"
Me.cachePositionCheckBox.Size = New System.Drawing.Size(151, 17)
Me.cachePositionCheckBox.Text = "Cache and restore position"
Me.ClientSize = New System.Drawing.Size(325, 420)
Me.Controls.Add(Me.dataGridView1)
Me.Controls.Add(Me.cachePositionCheckBox)
Me.Controls.Add(Me.dataGridView2)
Me.Controls.Add(Me.button1)
' Set the data source and member for the second DataGridView.
dataGridView2.DataSource = bindingSource1
dataGridView2.DataMember = "custOrders"
' Get the currency manager for the customer orders binding.
Dim relatedCM As CurrencyManager = _
bindingSource1.GetRelatedCurrencyManager("custOrders")
' Handle the two events for caching and resetting the position.
AddHandler relatedCM.ListChanged, AddressOf relatedCM_ListChanged
AddHandler relatedCM.PositionChanged, AddressOf relatedCM_PositionChanged
' Set the position in the child table for demonstration purposes.
relatedCM.Position = 3
' Establish the data set with two tables and a relationship
' between them.
Private Function InitializeDataSet() As DataSet
set1 = New DataSet()
' Declare the DataSet and add a table and column.
set1.Tables.Add("Customers")
set1.Tables(0).Columns.Add("CustomerID")
set1.Tables(0).Columns.Add("Customer Name")
set1.Tables(0).Columns.Add("Contact Name")
End Sub
' Handle the current changed event. This event occurs when
' the current item is changed, but not when a field of the current
' item is changed.
Private Sub bindingSource1_CurrentChanged(ByVal sender As Object, _
ByVal e As EventArgs) Handles bindingSource1.CurrentChanged
' If the CurrentChanged event occurs, this is not a caching
' situation.
cacheChildPosition = False
End Sub
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1())
End Sub
End Class
See also
How to: Ensure Multiple Controls Bound to the Same Data Source Remain Synchronized
BindingSource Component
Data Binding and Windows Forms
How to: Implement the IListSource Interface
4/28/2019 • 7 minutes to read • Edit Online
Implement the IListSource interface to create a bindable class that does not implement IList but instead provides a
list from another location.
Example
The following code example demonstrates how to implement the IListSource interface. A component named
EmployeeListSource exposes an IList for data binding by implementing the GetList method.
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace IListSourceCS
{
public class EmployeeListSource : Component, IListSource
{
public EmployeeListSource() {}
bool IListSource.ContainsListCollection
{
get { return false; }
}
System.Collections.IList IListSource.GetList()
{
BindingList<Employee> ble = new BindingList<Employee>();
if (!this.DesignMode)
{
ble.Add(new Employee("Aaberg, Jesper", 26000000));
ble.Add(new Employee("Cajhen, Janko", 19600000));
ble.Add(new Employee("Furse, Kari", 19000000));
ble.Add(new Employee("Langhorn, Carl", 16000000));
ble.Add(new Employee("Todorov, Teodor", 15700000));
ble.Add(new Employee("Vereb�lyi, �gnes", 15700000));
}
return ble;
}
#endregion
}
}
Imports System.ComponentModel
<System.Diagnostics.DebuggerNonUserCode()> _
Public Sub New(ByVal Container As System.ComponentModel.IContainer)
MyClass.New()
End Sub
<System.Diagnostics.DebuggerNonUserCode()> _
Public Sub New()
MyBase.New()
End Sub
Return ble
End Function
#End Region
End Class
End Class
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace IListSourceCS
{
public class Employee : BusinessObjectBase
{
private string _id;
private string _name;
private Decimal parkingId;
// Set values
this.Name = name;
this.ParkingID = parkingId;
}
public string ID
{
get { return _id; }
}
End Class
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Diagnostics;
namespace IListSourceCS
{
public class BusinessObjectBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
#endregion
}
}
Imports System.ComponentModel
#End Region
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace IListSourceCS
{
public class Form1 : Form
public class Form1 : Form
{
private System.ComponentModel.IContainer components = null;
private FlowLayoutPanel flowLayoutPanel1;
private Label label2;
private DataGridView dataGridView1;
private DataGridViewTextBoxColumn nameDataGridViewTextBoxColumn;
private DataGridViewTextBoxColumn salaryDataGridViewTextBoxColumn;
private DataGridViewTextBoxColumn iDDataGridViewTextBoxColumn;
private EmployeeListSource employeeListSource1;
public Form1()
{
InitializeComponent();
}
#endregion
}
Imports System.ComponentModel
Imports System.Windows.Forms
Me.InitializeComponent()
End Sub
End Sub
See also
IListSource
ITypedList
BindingList<T>
IBindingList
Data Binding and Windows Forms
How to: Implement the INotifyPropertyChanged
Interface
4/8/2019 • 5 minutes to read • Edit Online
The following code example demonstrates how to implement the INotifyPropertyChanged interface. Implement
this interface on business objects that are used in Windows Forms data binding. When implemented, the interface
communicates to a bound control the property changes on a business object.
Example
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
public Form1()
{
InitializeComponent();
set
{
if (value != this.customerNameValue)
{
this.customerNameValue = value;
NotifyPropertyChanged();
}
}
}
set
{
if (value != this.phoneNumberValue)
{
this.phoneNumberValue = value;
NotifyPropertyChanged();
}
}
}
}
}
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
customerList.Add(DemoCustomer.CreateNewCustomer())
customerList.Add(DemoCustomer.CreateNewCustomer())
customerList.Add(DemoCustomer.CreateNewCustomer())
' These fields hold the values for the public properties.
Private idValue As Guid = Guid.NewGuid()
Private customerNameValue As String = String.Empty
Private phoneNumberValue As String = String.Empty
See also
How to: Apply the PropertyNameChanged Pattern
Windows Forms Data Binding
How to: Raise Change Notifications Using a BindingSource and the INotifyPropertyChanged Interface
Change Notification in Windows Forms Data Binding
How to: Implement the ITypedList Interface
4/28/2019 • 9 minutes to read • Edit Online
Implement the ITypedList interface to enable discovery of the schema for a bindable list.
Example
The following code example demonstrates how to implement the ITypedList interface. A generic type named
SortableBindingList derives from the BindingList<T> class and implements the ITypedList interface. A simple
class named Customer provides data, which is bound to the header of a DataGridView control.
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Collections;
using System.Reflection;
namespace ITypedListCS
{
[Serializable()]
public class SortableBindingList<T> : BindingList<T>, ITypedList
{
[NonSerialized()]
private PropertyDescriptorCollection properties;
return pdc;
}
#endregion
}
}
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Windows.Forms
<Serializable()> _
Public Class SortableBindingList(Of Tkey)
Inherits BindingList(Of Tkey)
Implements ITypedList
<NonSerialized()> _
Private properties As PropertyDescriptorCollection
End Sub
Return pdc
End Function
Return GetType(Tkey).Name
End Function
#End Region
End Class
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace ITypedListCS
{
class Customer : INotifyPropertyChanged
{
public Customer() {}
public Customer(int id, string name, string company, string address, string city, string state, string
zip)
{
this._id = id;
this._name = name;
this._company = company;
this._address = address;
this._city = city;
this._state = state;
this._zip = zip;
}
public int ID
{
get { return _id; }
set
{
if (_id != value)
{
_id = value;
OnPropertyChanged(new PropertyChangedEventArgs("ID"));
}
}
}
#endregion
#endregion
#endregion
}
}
Imports System.ComponentModel
End Sub
Public Sub New(ByVal id As Integer, ByVal name As String, ByVal company As String, ByVal address As
String, ByVal city As String, ByVal state As String, ByVal zip As String)
Me._id = id
Me._name = name
Me._company = company
Me._address = address
Me._city = city
Me._state = state
Me._zip = zip
End Sub
#End Region
#End Region
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ITypedListCS
{
public partial class Form1 : Form
{
private SortableBindingList<Customer> sortableBindingListOfCustomers;
private BindingList<Customer> bindingListOfCustomers;
public Form1()
{
InitializeComponent();
}
this.dataGridView1.DataSource = this.bindingListOfCustomers;
}
#endregion
}
Imports System.ComponentModel
Imports System.Windows.Forms
Me.InitializeComponent()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.dataGridView1.DataSource = bindingListOfCustomers
End Sub
End Class
Compiling the Code
This example requires:
References to the System.Drawing and System.Windows.Forms assemblies.
See also
ITypedList
BindingList<T>
IBindingList
Data Binding and Windows Forms
How to: Navigate Data in Windows Forms
4/9/2019 • 2 minutes to read • Edit Online
In a Windows application, the easiest way to navigate through records in a data source is to bind a BindingSource
component to the data source and then bind controls to the BindingSource. You can then use the built-in
navigation method on the BindingSource such a MoveNext, MoveLast, MovePrevious and MoveFirst. Using these
methods will adjust the Position and Current properties of the BindingSource appropriately. You can also find an
item and set it as the current item by setting the Position property.
To increment the position in a data source
1. Set the Position property of the BindingSource for your bound data to the record position to go to. The
following example illustrates using the MoveNext method of the BindingSource to increment the Position
property when the nextButton is clicked. The BindingSource is associated with the Customers table of a
dataset Northwind .
NOTE
Setting the Position property to a value beyond the first or last record does not result in an error, as the .NET
Framework will not allow you to set the position to a value outside the bounds of the list. If it is important in your
application to know whether you have gone past the first or last record, include logic to test whether you will exceed
the data element count.
NOTE
Be aware that, should you change the list you are navigating in code, you should re-enable the Next button, so that
users may browse the entire length of the new list. Additionally, be aware that the above PositionChanged event for
the specific BindingSource you are working with needs to be associated with its event-handling method. The
following is an example of a method for handling the PositionChanged event:
void customersBindingSource_PositionChanged(object sender, EventArgs e)
{
if (customersBindingSource.Position == customersBindingSource.Count - 1)
nextButton.Enabled = false;
else
nextButton.Enabled = true;
}
If customersBindingSource.Position = _
customersBindingSource.Count - 1 Then
nextButton.Enabled = False
Else
nextButton.Enabled = True
End If
End Sub
See also
Data Sources Supported by Windows Forms
Change Notification in Windows Forms Data Binding
Data Binding and Windows Forms
Windows Forms Data Binding
Windows Forms Security
3/9/2019 • 2 minutes to read • Edit Online
Windows Forms features a security model that is code-based (security levels are set for code, regardless of the
user running the code). This is in addition to any security schemas that may be in place already on your computer
system. These can include those in the browser (such as the zone-based security available in Internet Explorer) or
the operating system (such as the credential-based security of Windows NT).
In This Section
Security in Windows Forms Overview
Briefly explains the .NET Framework security model and the basic steps necessary to ensure the Windows Forms
in your application are secure.
More Secure File and Data Access in Windows Forms
Describes how to access files and data in a semi-trusted environment.
More Secure Printing in Windows Forms
Describes how to access printing features in a semi-trusted environment.
Additional Security Considerations in Windows Forms
Describes performing window manipulation, using the Clipboard, and making calls to unmanaged code in a semi-
trusted environment.
Related Sections
Default Security Policy
Lists the default permissions granted in the Full Trust, Local Intranet, and Internet permission sets.
General Security Policy Administration
Gives information about the administering the .NET Framework security policy and elevating permissions.
Dangerous Permissions and Policy Administration
Discusses some of the.NET Framework permissions that can potentially allow the security system to be
circumvented.
Secure Coding Guidelines
Links to topics that explain the best practices for securely writing code against the .NET Framework.
Requesting Permissions
Discusses the use of attributes to let the runtime know what permissions your code needs to run.
Key Security Concepts
Links to topics that cover the basic aspects of code security.
Code Access Security Basics
Discusses the basics of working with the .NET Framework run time security policy.
Determining When to Modify Security Policy
Explains how to determine when your applications need to diverge from the default security policy.
Deploying Security Policy
Discusses the best manner for deploying security policy changes.
Security in Windows Forms Overview
4/28/2019 • 8 minutes to read • Edit Online
Before the release of the .NET Framework, all code running on a user's computer had the same rights or
permissions to access resources that a user of the computer had. For example, if the user was allowed to access
the file system, the code was allowed to access the file system; if the user was allowed to access a database, the
code was allowed to access that database. Although these rights or permissions may be acceptable for code in
executables that the user has explicitly installed on the local computer, they may not be acceptable for potentially
malicious code coming from the Internet or a local Intranet. This code should not be able to access the user's
computer resources without permission.
The .NET Framework introduces an infrastructure called Code Access Security that lets you differentiate the
permissions, or rights, that code has from the rights that the user has. By default, code coming from the Internet
and the Intranet can only run in what is known as partial trust. Partial trust subjects an application to a series of
restrictions: among other things, an application is restricted from accessing the local hard disk, and cannot run
unmanaged code. The .NET Framework controls the resources that code is allowed to access based on the identity
of that code: where it came from, whether it has a Strong-Named Assemblies, whether it is signed with a
certificate, and so on.
ClickOnce technology, which you use to deploy Windows Forms applications, helps make it easier for you to
develop applications that run in partial trust, in full trust, or in partial trust with elevated permissions. ClickOnce
provides features such as Permission Elevation and Trusted Application Deployment so that your application can
request full trust or elevated permissions from the local user in a responsible manner.
The actual permissions granted to your application can be different from the default values, because the security
policy can be modified; this means that your application can have permission on one computer, but not on another.
TOPIC DESCRIPTION
- More Secure File and Data Access in Windows Forms Describes how to access files and data in a partial trust
environment.
- More Secure Printing in Windows Forms Describes how to access printing features in a partial trust
environment.
- Additional Security Considerations in Windows Forms Describes performing window manipulation, using the
Clipboard, and making calls to unmanaged code in a partial
trust environment.
Permission Elevation Prompts the user with a security dialog box the first time your
application runs. The Permission Elevation dialog box
informs the user about who published the application, so that
the user can make an informed decision about whether to
grant it additional trust
Which technology you choose will depend on your deployment environment. For more information, see Choosing
a ClickOnce Deployment Strategy.
By default, ClickOnce applications deployed using either Visual Studio or the .NET Framework 2.0 SDK tools
(Mage.exe and MageUI.exe) are configured to run on a client computer that has Full Trust. If you are deploying
your application by using partial trust or by using only some additional permissions, you will have to change this
default. You can do this with either Visual Studio or the .NET Framework 2.0 SDK tool MageUI.exe when you
configure your deployment. For more information about how to use MageUI.exe, see Walkthrough: Deploying a
ClickOnce Application from the Command Line. Also see How to: Set Custom Permissions for a ClickOnce
Application or How to: Set Custom Permissions for a ClickOnce Application.
For more information about the security aspects of ClickOnce and Permission Elevation, see Securing ClickOnce
Applications. For more information about Trusted Application Deployment, see Trusted Application Deployment
Overview.
Testing the Application
If you have deployed your Windows Forms application by using Visual Studio, you can enable debugging in
partial trust or a restricted permission set from the development environment. Also see How to: Debug a
ClickOnce Application with Restricted Permissions.
See also
Windows Forms Security
Code Access Security Basics
ClickOnce Security and Deployment
Trusted Application Deployment Overview
Mage.exe (Manifest Generation and Editing Tool)
MageUI.exe (Manifest Generation and Editing Tool, Graphical Client)
More Secure File and Data Access in Windows Forms
4/8/2019 • 9 minutes to read • Edit Online
The .NET Framework uses permissions to help protect resources and data. Where your application can read or
write data depends on the permissions granted to the application. When your application runs in a partial trust
environment, you might not have access to your data or you might have to change the way you access the data.
When you encounter a security restriction, you have two options: assert the permission (assuming it has been
granted to your application), or use a version of the feature written to work in partial trust. The following sections
discuss how to work with file, database, and registry access from applications that are running in a partial trust
environment.
NOTE
By default, tools that generate ClickOnce deployments default these deployments to requesting Full Trust from the
computers on which they run. If you decide you want the added security benefits of running in partial trust, you must
change this default in either Visual Studio or one of the Windows Software Development Kit (SDK) tools (Mage.exe or
MageUI.exe). For more information about Windows Forms security, and on how to determine the appropriate trust level for
your application, see Security in Windows Forms Overview.
File Access
The FileIOPermission class controls file and folder access in the .NET Framework. By default, the security system
does not grant the FileIOPermission to partial trust environments such as the local intranet and Internet zones.
However, an application that requires file access can still function in these environments if you modify the design
of your application or use different methods to access files. By default, the local intranet zone is granted the right
to have same site access and same directory access, to connect back to the site of its origin, and to read from its
installation directory. By default, the Internet zone, is only granted the right to connect back to the site of its origin.
User-Specified Files
One way to deal with not having file access permission is to prompt the user to provide specific file information by
using the OpenFileDialog or SaveFileDialog class. This user interaction helps provide some assurance that the
application cannot maliciously load private files or overwrite important files. The OpenFile and OpenFile methods
provide read and write file access by opening the file stream for the file that the user specified. The methods also
help protect the user's file by obscuring the file's path.
NOTE
These permissions differ depending on whether your application is in the Internet zone or Intranet zone. Internet zone
applications can only use the OpenFileDialog, whereas Intranet applications have unrestricted file dialog permission.
The FileDialogPermission class specifies what type of file dialog box your application can use. The following table
shows the value you must have to use each FileDialog class.
OpenFileDialog Open
SaveFileDialog Save
NOTE
The specific permission is not requested until the OpenFile method is actually called.
Permission to display a file dialog box does not grant your application full access to all members of the FileDialog,
OpenFileDialog, and SaveFileDialog classes. For the exact permissions that are required to call each method, see
the reference topic for that method in the .NET Framework class library documentation.
The following code example uses the OpenFile method to open a user-specified file into a RichTextBox control.
The example requires FileDialogPermission and the associated Open enumeration value. The example
demonstrates how to handle the SecurityException to determine whether the save feature should be disabled. This
example requires that your Form has a Button control named ButtonOpen , and a RichTextBox control named
RtfBoxMain .
NOTE
The programming logic for the save feature is not shown in the example.
NOTE
In Visual C#, ensure that you add code to enable the event handler. By using the code from the previous example, the
following code shows how to enable the event handler.
this.ButtonOpen.Click += newSystem.Windows.Forms.EventHandler(this.ButtonOpen_Click);
Other Files
Sometimes you will need to read or write to files that the user does not specify, such as when you must persist
application settings. In the local intranet and Internet zones, your application will not have permission to store data
in a local file. However, your application will be able to store data in isolated storage. Isolated storage is an
abstract data compartment (not a specific storage location) that contains one or more isolated storage files, called
stores, that contain the actual directory locations where data is stored. File access permissions like
FileIOPermission are not required; instead, the IsolatedStoragePermission class controls the permissions for
isolated storage. By default, applications that are running in the local intranet and Internet zones can store data
using isolated storage; however, settings like disk quota can vary. For more information about isolated storage, see
Isolated Storage.
The following example uses isolated storage to write data to a file located in a store. The example requires
IsolatedStorageFilePermission and the DomainIsolationByUser enumeration value. The example demonstrates
reading and writing certain property values of the Button control to a file in isolated storage. The Read function
would be called after the application starts and the Write function would be called before the application ends.
The example requires that the Read and Write functions exist as members of a Form that contains a Button
control named MainButton .
' Reads the button options from the isolated storage. Uses Default values
' for the button if the options file does not exist.
Public Sub Read()
Dim isoStore As System.IO.IsolatedStorage.IsolatedStorageFile = _
System.IO.IsolatedStorage.IsolatedStorageFile. _
GetUserStoreForDomain()
Me.MainButton.BackColor = _
CType(converter.ConvertFromString _
(reader.ReadLine()), Color)
me.MainButton.ForeColor = _
CType(converter.ConvertFromString _
(reader.ReadLine()), Color)
converter = System.ComponentModel.TypeDescriptor.GetConverter _
(GetType(Font))
me.MainButton.Font = _
CType(converter.ConvertFromString _
(reader.ReadLine()), Font)
Catch ex As Exception
Debug.WriteLine("Cannot read options " + _
ex.ToString())
Finally
reader.Close()
End Try
End If
Catch ex As Exception
Debug.WriteLine("Cannot read options " + ex.ToString())
End Try
End Sub
' Creates the options.txt file and writes the button options to it.
Dim writer as System.IO.StreamWriter
Try
Dim isos As New System.IO.IsolatedStorage.IsolatedStorageFileStream _
(filename, IO.FileMode.CreateNew, isoStore)
converter = System.ComponentModel.TypeDescriptor.GetConverter _
(GetType(Color))
writer.WriteLine(converter.ConvertToString( _
Me.MainButton.BackColor))
writer.WriteLine(converter.ConvertToString( _
Me.MainButton.ForeColor))
Catch ex as Exception
Debug.WriteLine("Cannot write options " + ex.ToString())
Finally
writer.Close()
End Try
End Sub
// Reads the button options from the isolated storage. Uses default values
// for the button if the options file does not exist.
public void Read()
{
System.IO.IsolatedStorage.IsolatedStorageFile isoStore =
System.IO.IsolatedStorage.IsolatedStorageFile.
GetUserStoreForDomain();
this.MainButton.BackColor =
(Color)(converter.ConvertFromString(reader.ReadLine()));
this.MainButton.ForeColor =
(Color)(converter.ConvertFromString(reader.ReadLine()));
converter = TypeDescriptor.GetConverter(typeof(Font));
this.MainButton.Font =
(Font)(converter.ConvertFromString(reader.ReadLine()));
}
catch (Exception ex)
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot read options " + ex.ToString());
}
finally
{
reader.Close();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot read options " + ex.ToString());
}
}
// Creates the options file and writes the button options to it.
System.IO.StreamWriter writer = null;
try
{
System.IO.IsolatedStorage.IsolatedStorageFileStream isos = new
System.IO.IsolatedStorage.IsolatedStorageFileStream(filename,
System.IO.FileMode.CreateNew,isoStore);
converter = TypeDescriptor.GetConverter(typeof(Color));
writer.WriteLine(converter.ConvertToString(
this.MainButton.BackColor));
writer.WriteLine(converter.ConvertToString(
this.MainButton.ForeColor));
converter = TypeDescriptor.GetConverter(typeof(Font));
writer.WriteLine(converter.ConvertToString(
this.MainButton.Font));
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine
("Cannot write options " + ex.ToString());
}
finally
{
writer.Close();
writer.Close();
}
}
Database Access
The permissions required to access a database vary based on the database provider; however, only applications
that are running with the appropriate permissions can access a database through a data connection. For more
information about the permissions that are required to access a database, see Code Access Security and
ADO.NET.
If you cannot directly access a database because you want your application to run in partial trust, you can use a
Web service as an alternative means to access your data. A Web service is a piece of software that can be
programmatically accessed over a network. With Web services, applications can share data across code group
zones. By default, applications in the local intranet and Internet zones are granted the right to access their sites of
origin, which enables them to call a Web service hosted on the same server. For more information see Web
Services in ASP.NET AJAX or Windows Communication Foundation.
Registry Access
The RegistryPermission class controls access to the operating system registry. By default, only applications that
are running locally can access the registry. RegistryPermission only grants an application the right to try registry
access; it does not guarantee access will succeed, because the operating system still enforces security on the
registry.
Because you cannot access the registry under partial trust, you may need to find other methods of storing your
data. When you store application settings, use isolated storage instead of the registry. Isolated storage can also be
used to store other application-specific files. You can also store global application information about the server or
site of origin, because by default an application is granted the right to access the site of its origin.
See also
More Secure Printing in Windows Forms
Additional Security Considerations in Windows Forms
Security in Windows Forms Overview
Windows Forms Security
Mage.exe (Manifest Generation and Editing Tool)
MageUI.exe (Manifest Generation and Editing Tool, Graphical Client)
More Secure Printing in Windows Forms
4/8/2019 • 2 minutes to read • Edit Online
Windows Forms applications frequently include printing abilities. The .NET Framework uses the
PrintingPermission class to control access to printing capabilities and the associated PrintingPermissionLevel
enumeration value to indicate the level of access. By default, printing is enabled by default in the Local Intranet
and Internet zones; however, the level of access is restricted in both zones. Whether your application can print,
requires user interaction, or cannot print depends upon the permission value granted to the application. By
default, the Local Intranet zone receives DefaultPrinting access and the Intranet zone receives SafePrinting access.
The following table shows the functionality available at each printing permission level.
PRINTINGPERMISSIONLEVEL DESCRIPTION
See also
More Secure File and Data Access in Windows Forms
Additional Security Considerations in Windows Forms
Security in Windows Forms Overview
Windows Forms Security
Additional Security Considerations in Windows
Forms
4/8/2019 • 6 minutes to read • Edit Online
.NET Framework security settings might cause your application to run differently in a partial trust environment
than on your local computer. The .NET Framework restricts access to such critical local resources as the file
system, network, and unmanaged APIs, among other things. The security settings affect the ability to call the
Microsoft Windows API or other APIs that cannot be verified by the security system. Security also affects other
aspects of your application, including file and data access, and printing. For more information about file and data
access in a partial trust environment, see More Secure File and Data Access in Windows Forms. For more
information about printing in a partial trust environment, see More Secure Printing in Windows Forms.
The following sections discuss how to work with the Clipboard, perform window manipulation, and call the
Windows API from applications that are running in a partial trust environment.
Clipboard Access
The UIPermission class controls access to the Clipboard, and the associated UIPermissionClipboard enumeration
value indicates the level of access. The following table shows the possible permission levels.
OwnClipboard The Clipboard can be used with some restrictions. The ability
to put data on the Clipboard (Copy or Cut command
operations) is unrestricted. Intrinsic controls that accept paste,
such as a text box, can accept Clipboard data, but user
controls cannot programmatically read from the Clipboard.
By default, the Local Intranet zone receives AllClipboard access and the Internet zone receives OwnClipboard
access. This means that the application can copy data to the Clipboard, but the application cannot
programmatically paste to or read from the Clipboard. These restrictions prevent programs without full trust from
reading content copied to the Clipboard by another application. If your application requires full Clipboard access
but you do not have the permissions, you will have to elevate the permissions for your application. For more
information about elevating permissions, see General Security Policy Administration.
Window Manipulation
The UIPermission class also controls permission to perform window manipulation and other UI-related actions,
and the associated UIPermissionWindow enumeration value indicates the level of access. The following table
shows the possible permission levels.
By default, the Local Intranet zone receives AllWindows access and the Internet zone receives
SafeTopLevelWindows access. This means that in the Internet zone, the application can perform most windowing
and UI actions, but the window's appearance will be modified. The modified window displays a balloon
notification when first run, contains modified title bar text, and requires a close button on the title bar. The balloon
notification and the title bar identify to the user of the application that the application is running under partial
trust.
AllWindows Users can use all windows and user input events without
restriction.
SafeTopLevelWindows Users can use only safer top-level windows and safer
subwindows for drawing, and can use only user input events
for the user interface within those top-level windows and
subwindows. These safer windows are clearly labeled and have
minimum and maximum size restrictions. The restrictions
prevent potentially harmful spoofing attacks, such as imitating
system logon screens or the system desktop, and restricts
programmatic access to parent windows, focus-related APIs,
and use of the ToolTip control,
SafeSubWindows Users can use only safer subwindows for drawing, and can use
only user input events for the user interface within that
subwindow. A control displayed within a browser is an
example of a safer subwindow.
Each permission level identified by the UIPermissionWindow enumeration allows fewer actions than the level
above it. The following tables indicate the actions that are restricted by the SafeTopLevelWindows and
SafeSubWindows values. For exact permissions that are required for each member, see the reference for that
member in the .NET Framework class library documentation.
SafeTopLevelWindows permission restricts the actions listed in the following table.
The SafeSubWindows value restricts the actions listed in the following table, in addition to the restrictions placed
by the SafeTopLevelWindows value.
If your application does not have permission to call unmanaged code, your application must request
UnmanagedCode permission, or you must consider alternative ways of implementing features; in many cases,
Windows Forms provides a managed alternative to Windows API functions. If no alternative means exist and the
application must access unmanaged code, you will have to elevate the permissions for the application.
Permission to call unmanaged code allows an application to perform most anything. Therefore, permission to call
unmanaged code should only be granted for applications that come from a trusted source. Alternatively,
depending on the application, the piece of application functionality that makes the call to unmanaged code could
be optional, or enabled in the full trust environment only. For more information about dangerous permissions, see
Dangerous Permissions and Policy Administration. For more information about elevating permissions, see
General Security Policy Administration.
See also
More Secure File and Data Access in Windows Forms
More Secure Printing in Windows Forms
Security in Windows Forms Overview
Windows Forms Security
Securing ClickOnce Applications
ClickOnce Deployment for Windows Forms
4/8/2019 • 2 minutes to read • Edit Online
The following topics describe ClickOnce, a technology used for easily deploying Windows Forms applications to
client computers.
Related Sections
Choosing a ClickOnce Deployment Strategy
Presents several options for deploying ClickOnce applications.
Choosing a ClickOnce Update Strategy
Presents several options for updating ClickOnce applications.
Securing ClickOnce Applications
Explains the security implications of ClickOnce deployment.
Troubleshooting ClickOnce Deployments
Describes various problems that can occur when deploying ClickOnce applications, and documents the top-level
error messages that ClickOnce might generate.
ClickOnce and Application Settings
Describes how ClickOnce deployment works with application settings, which stores application and user settings
for future retrieval.
Trusted Application Deployment Overview
Describes a ClickOnce feature that allows trusted applications to run with a higher level of permission on client
computers.
ClickOnce and Authenticode
Describes how Authenticode technology is used in trusted application deployment.
Walkthrough: Manually Deploying a ClickOnce Application
Demonstrates using command-line and SDK tools to deploy a ClickOnce application without using Visual Studio.
How to: Add a Trusted Publisher to a Client Computer for ClickOnce Applications
Demonstrates the one-time configuration of client computers required for trusted application deployment.
How to: Specify an Alternate Location for Deployment Updates
Demonstrates configuring a ClickOnce application, using SDK tools, to check a different location for new versions
of an application.
Walkthrough: Downloading Assemblies on Demand with the ClickOnce Deployment API
Demonstrates using API calls to retrieve an assembly the first time your application attempts to load it.
How to: Retrieve Query String Information in an Online ClickOnce Application
Demonstrates retrieving parameters from the URL used to run a ClickOnce application.
ClickOnce Cache Overview
Describes the cache used to store ClickOnce applications on the local computer.
Accessing Local and Remote Data in ClickOnce Applications
Describes how to access local data files and remote data sources from a ClickOnce application.
How to: Include a Data File in a ClickOnce Application
Demonstrates how to mark a file so that it is available in the ClickOnce data directory.
See also
Application Settings Overview
Publishing ClickOnce Applications
Building ClickOnce Applications from the Command Line
Debugging ClickOnce Applications That Use System.Deployment.Application
Deploying COM Components with ClickOnce
How to: Publish a ClickOnce Application using the Publish Wizard
How to: Access Keyed Collections in Windows Forms
4/28/2019 • 2 minutes to read • Edit Online
You can access individual collection items by key. This functionality has been added to many collection
classes that are typically used by Windows Forms applications. The following list shows some of the
collection classes that have accessible keyed collections:
ListView.ListViewItemCollection
ListViewItem.ListViewSubItemCollection
Control.ControlCollection
TabControl.TabPageCollection
TreeNodeCollection
The key associated with an item in a collection is typically the name of the item. The following procedures show
you how to use collection classes to perform common tasks.
To find and give focus to a nested control in a control collection
Use the Find and Focus methods to specify the name of the control to find and give focus to.
this.BackgroundImage = imageList1.Images["logo.gif"];
Me.BackgroundImage = imageList1.Images("logo.gif")
tabControl1.SelectedTab = tabControl1.TabPages["shippingOptions"];
tabControl1.SelectedTab = tabControl1.TabPages("shippingOptions")
See also
Getting Started with Windows Forms
How to: Add or Remove Images with the Windows Forms ImageList Component
Enhancing Windows Forms Applications
3/9/2019 • 2 minutes to read • Edit Online
Windows Forms contains many features that you can use to enhance your Windows-based applications to meet
the specific needs of your users. The following topics describe these features and how to use them.
In This Section
Graphics and Drawing in Windows Forms
Contains links to topics that describe and show how to use the graphics interface in Windows Forms.
Application Settings for Windows Forms.
Contains links to topics that describe and show how to use the Application Settings feature.
Windows Forms Print Support
Contains links to topics that describe and show how to print files from Windows Forms applications.
Drag-and-Drop Operations and Clipboard Support
Contains links to topics that describe and show how to use the drag-and-drop feature and the Clipboard in
Windows Forms.
Networking in Windows Forms Applications
Contains links to topics that describe and show how to use networking in Windows Forms.
Globalizing Windows Forms applications
Contains links to topics that show how to globalize Windows Forms applications.
Windows Forms and Unmanaged Applications
Contains links to topics that describe and show how to access COM components from Windows Form
applications.
System Information and Windows Forms
Describes how to use system information in Windows Forms.
Power Management in Windows Forms
Describes how to manage power use in Windows Forms applications.
Windows Forms Visual Inheritance
Describes how to inherit from a base form.
Multiple-Document Interface (MDI) Applications
Describes how to create multiple-document interface (MDI) applications.
Integrating User Help in Windows Forms
Describes how to integrate user help in your applications.
Windows Forms Accessibility
Describes how to make your applications available to a wide variety of users.
Using WPF Controls
Describes how to use WPF controls in your Windows Forms-based applications.
Related Sections
Help Systems in Windows Forms Applications
Contains links to topics that describe and show how to provide user help in Windows Forms applications.
Getting Started with Windows Forms
Contains links to topics that describe how to use the basic features of Windows Forms.