Using Prebuilt Type Editors
The base UITypeEditor class is found in the System.Drawing.Design namespace. You can inherit from this class to create your custom type editors, or you can use one of the derived classes that are provided with the .NET Framework. Table 13-6 shows a sampling of useful type editors editors that are usable only with specific Web controls have been omitted . Table 13-6. UITypeEditors in the .NETFramework Edits an array by allowing the programmer to enter a list of strings. Used automatically for...
C
improving performance of owner-drawn controls, 839-842 DateTimePicker control, 132 CalendarForeColor property DateTimePicker control, 132 CalendarMonthBackground property DateTimePicker control, 132 CalendarTitleBackColor property DateTimePicker control, 132 CalendarTrailingForeColor property DateTimePicker control, 132 Call Show method AgentController class, 807 CanBeParentedTo method ControlDesigner class, 927 Cancel property DataGridViewCellValidatingEventArgs class, 564...
ToolStrip Basics
The ToolStrip is the basis of the StatusStrip, MenuStrip, and ContextMenuStrip controls you'll consider in this chapter, and a slick stand-alone control of its own. To get off to a quick start with ToolStrip, drag it onto a form, select it, and choose Insert Standard Items from the smart tag. This adds a basic set of buttons including File, Open, Save, and Print, the editing commands Cut, Copy, and Paste, and a Help button. When you run this example, you'll immediately notice that the ToolStrip...
MDI Layout
If you want to add the support for tiling and cascading windows, you'll probably also add these options to this menu. Every MDI container supports a LayoutMdi method that accepts a value from the MdiLayout enumeration, and arranges the windows automatically. For example, here's the code to tile windows horizontally in response to a menu click in the Parent form private void mnuTileH_Click object sender, System.EventArgs e Of course, it's just as easy to create your own custom layout logic....
A Simple Glow Button
The first example you'll see demonstrates how easy it is to extend the AnimatedButtonBase class. The SimpleGlowButton creates a couple of drawing objects in its constructor, and simply overrides the four paint methods to paint a button with a different background color. Here's the complete code public class SimpleGlowButton AnimatedButtonBase private Pen penOutline private StringFormat textFormat In a more sophisticated details, these hard-coded details would be mapped to properties. penOutline...
ListView Visualization
One limitation of the ListView is that, like all Windows controls, it stores all its ListView items in memory. That means if you want to create a ListView that shows tens of thousands of data-heavy records, you're left with an unavoidable footprint in memory. In .NET 2.0, the ListView adds support for virtualization, which allows it to support large sets of data. With virtualization, the ListView loads only the data that's currently being displayed. As the user scrolls to a new place in the...
The ErrorProvider
Interrupting users with a message box is a crude way of pointing out an error. It's not likely to get users on your side, and you won't find it in any modern Windows application. A much better approach is to provide some kind of on-screen indication about the problem, like an explanatory error message next to the incorrect input. The .NET Framework provides an elegant way to accomplish this ErrorProvider control. The ErrorProvider has a simple role in life it can display an error icon which...
Other Domain Controls
Domain controls restrict user input to a finite set of valid values. The standard ListBox is an example of a domain control, because a user can choose only one of the items in the list. Figure 4-5 shows an overview of the other domain controls provided in .NET. DomainUpDown is similar to a list control in that it provides a list of options. The difference is that the user can navigate through this list using only the up down arrow buttons, moving to either the previous item or the following...
Splitting Windows
One of the most recognizable user-interface styles in applications today is the split window arguably popularized by Windows Explorer . In fact, split-window-view applications are beginning to replace the former dominant paradigm of MDI, and Microsoft has led the charge although many developers still favor MDI design for many large-scale applications . In .NET 1.0, split windows were built out of two Panel controls separated by a Splitter control. This worked perfectly well, but it could be a...
Creating a New Binding Context
In the previous example, both controls were synchronized separately and had separate binding contexts because they were bound to two different tables and hence two different DataView objects . In some cases, however, you might want the ability to bind to the same table or any other data source but at two different and independent positions. To accomplish this, you need to manually create an extra binding context. Every control provides the BindingContext property. By default, each control...
TreeView Structure
You can nest nodes in a complex structure with a virtually unlimited number of layers. Adding subnodes is similar to adding submenu items. First you find the parent node, and then you add the child node to the parent's Nodes collection. node treeFood.Nodes.Add Fruits node.Nodes.Add Apple node.Nodes.Add Peach node node.Nodes.Add Tomato The Add method always returns the newly added node object. You can then use this node object to add child nodes. If you wanted to add child nodes to the Apple...
Using Custom Type Editors
You can also develop your own custom type editor classes to allow special settings to be configured. For example, consider the TreeView control. Its Nodes property is a collection, but it doesn't use the standard class. Instead, it uses the more specialized To create a custom type editor, you must first create a class that derives from System.Drawing.Design.UITypeEditor. You can then override the four methods shown in Table 13-7. Table 13-7. UITypeEditor Overridable Methods ClassMethod...
A DropDown Type Editor
Instead of showing a separate dialog box, a drop-down type editor shows a control in a dropdown box underneath the property. The drop-down box is sized to fit the initial size of the control you supply, but it will be resized if it can't fit due to screen size or window positioning. The best way to prepare the content for the drop-down box is to create a user control. The type editor is then responsible for showing that user control in the drop-down box. For example, consider the Progress...
A Modal Type Editor
A modal type editor shows an ellipsis button next to the property value. When this button is clicked, a dialog box appears that allows the developer to change the property value see Figure 13-15 . dir Tree DirectoryTreeControl. DirectoryTree Figure 13-15. The sign of a modal type editor Figure 13-15. The sign of a modal type editor To create a modal type editor, you need to create the dialog box form. To create a basic example, consider the DirectoryTree control first presented in Chapter 11....
The Disposable Pattern
If your class holds on to any unmanaged resources like unmanaged memory or window handles , you need to clean them up properly. The proper approach is to override the Dispose method, and make sure you release your resources there. Similarly, if your class holds references to any IDisposable classes, you need to override Dispose and call Dispose on those objects. This cleanup code makes sure your code runs optimally at runtime and in the design environment. As long as you're deriving your class...
ListView Grouping
The ListView examples you've seen so far gave you a flat look at your data. All the items have had equal precedence. And although the ListView lacks the muscle to represent complex hierarchies of information an area where the TreeView excels , it can subgroup items into separate categories. To use grouping, take these two steps 1. Define the groups you want to use through the ListView.Groups collection. 2. Put each ListViewItem into the appropriate group when you create it by setting the...
Using a Control Renderer
Adding the logic to painstakingly create a VisualStyleObject, check whether it's defined in the current theme, and then render it can become fairly time consuming. If you're planning to use the visual style support to build a unique custom control like the examples in Chapter 12, which use visual styles in a charting control and a collapsible panel , you don't have any other option. However, if you simply want to create a basic ingredient like a button or check box, there is a shortcut. You can...
Custom Cells
Throughout this chapter, you've seen a range of ways to extend the DataGridView by handling various cell-based events. In all of these examples, you place your event handling code in the form. This works perfectly well, but it's not terribly convenient if you want to reuse the same DataGridView in more than one form or, more likely, you want to reuse the same formatting, painting, or validation technique in different columns, forms, and even applications. If you've perfected a piece of custom...
ClickOnce Limitations
ClickOnce is designed to be a lighter setup option than MSI-based setups. As a result, ClickOnce deployment doesn't allow for much configuration. Many aspects of its behavior are completely fixed, either to guarantee a consistent user experience or to encourage enterprise-friendly security policies. The limitations of ClickOnce include the following ClickOnce applications are installed for a single user. You cannot install an application for all users on a workstation. ClickOnce applications...
T
Visual Studio, 59 TabControl control, 134-135 properties, 135-136 TabControl control, 136 TabIndex property controls, 59 Label control, 59 table of contents, creating, 795 Table property ToolStripLayoutStyle enumeration, 479 TableCellFormattingEventArgs class, 550 TableLayout class System.Windows.Forms.Layout namespace, 749 TableLayoutPanel class, 749 Anchor property, 763, 764 AutoScroll property, 758, 766 AutoSize property, 762 CellBorderStyle property, 761 ColumnCount property, 759...
Container Controls 1
A container control is a control that can contain other controls. Technically, any control has this ability by virtue of its Controls collection. However, only some controls provide this functionality in the design-time environment. You can create a container control by inheriting from ContainerControl or a derived class like Panel . This works because these controls use the ParentControlDesigner or one of its derived classes , which has the design-time ability to host other controls. However,...
Customizing the ToolStrip Rendering
The ToolStrip uses a completely different rendering model than other controls that support owner drawing. Although the ToolStripItem does provide an OnPaint method that can perform custom painting, by default a separate renderer class does all the work. The renderer paints the text and image content, and other details like the gradient background to the sizing grips, highlighting, and drop-down buttons. Here's how it works. The ToolStripRenderer defines an abstract base class for all renderers....
Validating Input
Validation is a slightly different task than error handling. With error handling, you deal with the problems reported by the data source. With validation, you catch your own custom error conditions for example, data that may be allowed in the data source, but doesn't make sense in your application. When the user commits a change by navigating to a new cell, the DataGridView control raises the CellValidating and CellValidated events. These are followed by the RowValidating and RowValidated...
The ToolStripMenuItem
The ToolStripMenuItem represents a command in a menu. It renders differently depending on whether it's part of a submenu, or a top-level menu item in a MenuStrip control. When it's in a submenu, the ToolStripMenuItem renders a margin on the left where thumbnail images are displayed for each command if supplied . The ToolStripMenuItem derives from the ToolStripDropDownItem, which means you can create a submenu by adding items to the ToolStripMenuItem.Items collection. The ToolStripMenuItem also...
The Drawing Surface
The drawing application begins with an empty canvas. To create a shape, the user right-clicks the form drawing area, and chooses one of the three menu options. These menu options New Rectangle, New Ellipse, and New Triangle are represented by three menu items mnuRectangle, mnuEllipse, and mnuTriangle . However, the click event for each of these objects triggers the same event handler, which just sets the ShapeType property accordingly. private void mnuNewShape_Click object sender,...
Adding a TypeSafe Resource
To add a resource, start by expanding the Properties folder in the Solution Explorer. The Properties node contains three items AssemblyInfo.cs. This code file includes attributes that set various bits of metadata that are compiled into your assembly, including qthe publisher information and the version number. You can edit this information directly by modifying this file, or by using the project properties dialog box. Resources.resx. This XML file identifies the resources that you've added to...
Synchronizing MDI Children
The MdiParent property allows you to find the MDI container from any child. The ActiveMdiChild property allows you to find the active child from the parent form. The only remaining gap to fill is retrieving the full list of all MDI children. You can accomplish this using the MdiChildren property, which provides an array of form references. That's right, an array not a collection, which means you can't use methods like Add and Remove to manage MDI children. The next example shows how you can use...
DataGridView Styles
One of the challenges of designing the DataGridView was to create a formatting system that was flexible enough to apply different levels of formatting, but remained efficient for very large tables. For flexibility, the best approach is to allow the developer to configure each cell individually. But for efficiency, this approach can be disastrous. A table with thousands of rows will have tens of thousands of cells, and maintaining distinct formatting for each cell is sure to waste vast expanses...
Localizable Properties
All of the Windows Forms controls included with .NET are highly localizable. That means you can use the technique described in Chapter 5 to localize a form, creating multiple versions for different cultures. By default, when you create your own custom controls, none of the new properties you add is localizable. This significantly reduces their value in applications that need to be localized. Fortunately, there's no reason to stick with this limitation. You can easily create a localizable...
DoubleBuffered Controls
There's one limitation with automatic double buffering it works only if you can set the DoubleBuffered property, which is protected. That means the control itself has the ability to control how it uses double buffering for its painting logic, but the application consuming the control can't. For forms, this isn't a problem, because you always derive a new form class when you create a custom form. But for other controls, this isn't the case. When you add a control to your form, you aren't...
A Simple Shaped Form
The following example code creates a shaped form. It defines an ellipse with the same bounds of the form and adds it to a GraphicsPath. Once the GraphicsPath is assigned to the Region property of the form, only the part of the form that fits inside the ellipse is shown. private void SimpleShapedForm_Load object sender, System.EventArgs e GraphicsPath path new GraphicsPath path.AddEllipse 0, 0, this.Width, this.Height this.Region new Region path Figure 23-1 shows this unusual form, displayed...
O
ObjectForScripting property WebBrowser control, 606 OnComponentChanged method IComponentChangeService interface, 912 OnComponentChanging method IComponentChangeService interface, 911 OnDocumentChanged method Order class, 674 OnDrawItem method ComboBox class, 652, 654 OnKeyPress method ComboBox class, 652 TextBox control, 20 OnLayout method Control class, 743 OnMeasureItem method list box custom control, 396 OnMouseDown event overriding to create floating ToolStrip objects, 491 OnMouseDown...
A Custom TreeNode
The ProjectTree makes use of a handy but clumsy approach for linking Project objects to TreeNode objects the TreeNode.Tag property. Although this works, it's not strongly typed, and it breaks down entirely if you need to associate two different objects with the same TreeNode. Another solution is to derive a custom TreeNode class that adds the properties you're interested in. Here's an example public class ProjectTreeNode TreeNode public ProjectTreeNode Project project, string text, int...
ClickOnce Security
ClickOnce security is based on the code access security system in .NET. Code access security acts like a configurable sandbox that restricts the abilities of a .NET application based on certain details, such as where it came from, who created it, and so on. Taken together, these details are called evidence. When you run a .NET application, the code access security system compares the evidence of an application to the current security policy to determine what permissions it should have. For...
The WebBrowser
The WebBrowser control is another new frill in .NET 2.0. Essentially, the WebBrowser allows you to embed a full-featured Internet Explorer inside any window. This feat was technically possible in previous versions of .NET using interop and the Internet Explorer ActiveX control. However, the interop approach suffered from a few annoying quirks that the WebBrowser control deftly avoids. The WebBrowser control also adds a remarkable piece of new functionality the ability to interact with the...
Tip The ToolStrip is optimized so it doesnt attempt to lay out content if the
The default DisplayStyle depends on the type of item. For example, a ToolStripButton starts off in image mode, while a ToolStripLabel uses ImageAndText. The DisplayStyle has no meaning for the ToolStripSeparator and ToolStripControlHost and this Property doesn't appear in their Properties Window for these items . When you use ImageAndText, you have the flexibility to choose how the two components are arranged. By default, the image appears on the left and the text on the right. However, you can...
The Shape Collection
You could use the generic List lt Type gt class to create a collection for storing shapes without needing to create a new class. However, in this case creating a custom collection class makes sense because it gives you a good place to put code that works on groups of shapes like hit-testing and reordering . There are several options for creating the custom shape collection. You could derive from List lt Shape gt to add your logic to the strongly typed List lt Type gt class, or you could derive...
Applying a Key to a Control Assembly
To add the key to a control project, you need to add an attribute to the AssemblyInfo.cs file for your project. To find this file, look under the Properties node in the Solution Explorer. The AssemblyInfo.cs file contains a variety of assembly attributes that configure assembly metadata, including details like versioning and product name. Here's the attribute you need to attach a key file assembly If you specify a relative file name instead of the full path for the key file, the compiler looks...
Note If you use any EditMode value other than EditProgrammatically the user
When the user is editing a cell, the row header will display an editing icon that looks like a pencil, although this too is configurable just set ShowEditingIcon to false . The user can cancel an edit by pressing the Esc key. If the EditCellOnEnter property is set to true, the cell will remain in edit mode, but all changes will be discarded. To commit a change, the user simply needs to move to a new cell just pressing Enter will take care of that or change focus to another control. If your code...
Polling and Callbacks
When you call EndInvoke , the call becomes synchronous. That means that if the underlying method hasn't returned by the time you call EndInvoke , your code simply waits for it to finish, as it would if you called Invoke . If you want to check whether the method is actually complete before you call EndInvoke , you can check the IsCompleted property of the IAsyncResult object that's returned from the BeginInvokeO method. You can check this information repeatedly for example, in a loop while you...
FlowLayoutPanel A Modular Interface
One interesting application of the FlowLayoutPanel is to lay out multiple modules in a portalstyle application. For example, you might have an application that provides different features or data views to different users, depending on their roles or their preferences. You can implement each feature using a separate user control, and then show the appropriate group of user controls in a FlowLayoutPanel. Depending on the way you want to arrange these controls, you might alternatively choose to...
The FlowLayoutPanel
There are two panel controls for custom layout. The FlowLayoutPanel is the simpler of the two. The FlowLayoutPanel arranges controls one after the other in the available space. It's similar to the approach usually used with web pages, where each element is positioned immediately after the preceding element. To try out a FlowLayoutPanel, drag it onto a form and start adding some controls. The FlowLayoutPanel adds two new properties to the Panel class FlowDirection. This property determines how...
The StatusStrip and MenuStrip
So far, you've learned the ToolStrip essentials, including how to control the layout, handle ToolStripItem events, and use the ToolStripContainer to add drag-and-rearrange support. Now, it's time to consider how the ToolStrip model enables status bars and menus. The basic idea behind the ToolStrip model is that you can add the same ToolStripItem objects to different top-level containers. If you need a toolbar, the top-level container is the ToolStrip. If you need a status bar, the StatusStrip...
The ToolStripManager
The ToolStripManager allows you to set a renderer that will be used by multiple ToolStrip objects in your application. This gives you the ability to transform the look of your entire interface by modifying a single line code. Figure 14-22 shows this model. ToolStiip.RenderMode is ToolStripManager ToolStiip.RenderMode is ToolStripManager Figure 14-22. How the ToolStripManager interacts with the ToolStrip Figure 14-22. How the ToolStripManager interacts with the ToolStrip The model is actually...
ActiveX Controls
.NET includes excellent interoperability features that allow you to continue using COM components and ActiveX controls in your current applications. If you're using Visual Studio, the process is even automated for you. To add an ActiveX control to one of your projects in Visual Studio, right-click the toolbox and select Choose Items. Select the COM Components tab, find the appropriate control on the list, and put a check mark next to it. Nothing happens until you add an instance of this control...
The GraphicsPath
As you've learned, the Graphics class allows you to draw all the basic ingredients lines, rectangles, ellipses, arcs, polygons, curves, and strings of text. The GraphicsPath allows you to combine a group of these elements into a single unit. You can then draw them all at once, or perform other tasks like hit testing. To build a GraphicsPath object, you simply create a new instance, and use the methods in Table 7-5 to add all the required elements. Here's an example that creates a GraphicsPath...
Rollover Button
The last button control you'll consider here is an all-purpose rollover button. With the rollover button, very little work is performed with GDI . Instead, button images for all the four states are prepared in a separate program, and imported into the application as resources. These images are then assigned to the control, which switches between them seamlessly. To implement the rollover button, you need to begin by defining the image properties. To save space, the following code shows only the...
Merging Menus
Another unique characteristic of MDI applications is their treatment of menus. If you create a child form with a menu, that menu is added to the main menu when the child form is displayed. This behavior allows you to provide different options depending on the current view, but presents a centralized menu to the user. Using the default menu behavior, menu items from the child form are added to the right of the predefined menu items in the parent and removed from the child menu . This merging...
Changing the Colors of the ProfessionalToolStripRenderer
In the previous example, you saw how you can get complete rendering control by creating a custom renderer for the ToolStrip. However, in some cases a custom renderer is more than you need. For example, you might want to perform the standard drawing logic but simply tweak the colors that are used. In this case, there's a shortcut. By default, the ToolStripProfessionalRenderer chooses colors that match the visual style settings on a Windows XP computer. If you're using the default blue scheme,...
Dealing with Nested Objects
In Chapter 12, you considered a GradientPanel control. Using this control, you can configure two colors, and the results appear immediately in the IDE. However, there is an alternate design that you might want to use with the GradientPanel. Consider the ColorA, ColorB, and GradientFillStyle properties. These properties are really all parts of the same setting, and together they determine the background fill. If you wrapped these three settings into one class, they would be easier to find and...



















