Custom programming of the intercept keystrokes VB.NET control action
I. Introduction
First of all, this article assumes you are familiar with VB.NET and Visual Studio.NET Windows Forms designer.
In the development of custom Windows Forms controls, drop-down box to provide our own type of editor to manipulate the controls attribute is often very convenient. Custom type editor can not only provide a more rich design time experience and may be user controls if you like determinants.
If you decide to create your own drop-down type of editor, then it should follow the drop-down box with built-in editors similar type of model. Let us take the Anchor property as an example. A typical operation of the property's design time user interaction are described below:
??the user selects the Anchor property in the property grid and click the Properties box to the right of the drop-down button.
??a good graphic control is the drop-down box, which allows users to use the mouse to click the edge or use the arrow keys to highlight an edge and use the space key to select / deselect it.
??user can press the ENTER key or click on the drop-down control to receive changes in the external. In order to cancel this change, the user can press the ESC key.
Now, let us discuss the specific implementation technology.
Second, to achieve
First, let us build a ResourceImageEditor type editor, which allows the file system from the current select an image file (the same as the built-in ImageEditor class) or from an assembly manifest file to select an image resource. Moreover, the user experience, this behavior should be similar to the system ResourceImageEditor built-in type editors. The following is a summary of our requirements:
1. When the user select from a property a property grid, the grid will be displayed - a drop-down box displays the UI to edit the properties.
2. When you click the drop-down button, the current program will focus on resources of all images displayed.
3. When the user selects an image resource item, the corresponding image is loaded from the assembly.
4. Allows you to select an image file, and in the drop-down list box will be marked as the last one “Browse …”??When the user click “Browse …” item, will display the classic open file dialog box, users can choose an image file.
5. By clicking the mouse or use the arrow keys to highlight an item and press the Enter key to allow the user to actually select it from the drop-down list box, select one. This drop-down selection by pressing the ESC key to cancel.
ResourceImageEditor is a type of editor, so it is directly or indirectly derived from the System.Drawing.Design.UITypeEditor class. I decided to built System.Drawing.Design.ImageEditor derived class because it has achieved the image file options. In other words, ImageEditor.EditValue achieve will display a File Open dialog box to allow users to select from the file system image file. Then, from my derived class call the function simply call MyBase.EditValue can.
The first requirement in order to achieve the above (in the property grid to display the drop-down arrow button), I have overloaded GetEditStyle ways to return from UITypeEditorEditStyle appropriate enumeration constants:
Public Overloads Overrides Function GetEditStyle (_
ByVal context As ITypeDescriptorContext) As UITypeEditorEditStyle
Return UITypeEditorEditStyle.DropDown
End Function
To display the image resource list, I have cited a given assembly of all resources and only display images in the list of resources. To simplify, I decided to use a simple convention: When a resource name to a valid image file extension (. Bmp,. Jpg,. Gif …) at the end, we think this is an image resource, and to include it to the drop-down list box. Also, I use the image resource name of the collection to fill the drop-down ListBox control, followed by detailed pre-order details.
Initially, to be enumerated in order to check the image resources of the assembly that contains ResourceImageEditor class assembly. However, we can put ResourceImageEditor.ResourceAssembly property to any valid System.Reflection.Assembly reference to change it.
When the user select an image from the list box resource name, the image can be a given assembly from the manifest file to load. This is achieved within LoadResourceImage methods:
Private Function LoadResourceImage (ByVal resourceName As String) As Image
Debug.Assert (Not resourceName Is Nothing)
Dim ImageStream As System.IO.Stream =
Me.ResourceAssembly.GetManifestResourceStream (resourceName)
Return System.Drawing.Bitmap.FromStream (ImageStream)
End Function
Drop-down user interface is overloaded EditValue way through dynamically create and fill a ListBox control is achieved. Editor also handles generated by the ListBox Click and KeyDown event, as it is to intercept the ENTER and ESC keys necessary. The following pseudo code shows the method of implementation in EditValue logic:
Public Overloads Overrides Function EditValue (…)
??store context information for use in the drop-down ListBox event handlers.
??Create and use the available resources were filled with images of the ListBox.
??add our special “Browse …” item.
??Bind ListBox event.
??In a drop-down window to display the ListBox.
End Function
Third, several key problems and solutions of the case
In order to develop ResourceImageEditor, I created a heavy Image property MyPictureBox (derived from System.Windows.Forms.PictureBox), in order to ResourceImageEditor specify the type of property for the Image Editor.
Then I compile the control code. , You can put into a form that MyPictureBox control and call the drop-down box on the user interface ……
Mouse interface worked well. However, when I use the keyboard to select one and press the Enter key, the drop-down list box disappears, and I lost the selected content (that is, the first select the image has not changed). I soon found that when pressing the Enter key, the ListBox does not generate KeyDown event.
Although the ESC key also produced KeyDown event, but this is not a problem; because the drop-down list box will be automatically closed, and I do not have to deal with the currently selected item.
Obviously, in the ListBox control to deal with them before, the property grid “shield” of the ENTER and ESC.
In order to simplify but also to solve the problem, I would like to use ProcessDialogKey method. Pretreatment period in the message (processing dialog characters, such as TAB, RETURN, ESCAPE, and arrow keys), the call to this method. This method is declared within the System.Windows.Forms.Control class - it's simply that the call agent to the control of the parent (if any). I subclass the ListBox control and override the ProcessDialogKey way to intercept the enter key, as follows:
Protected Overrides Function ProcessDialogKey (ByVal keyData As Keys) As Boolean
If keyData = System.Windows.Forms.Keys.Return Then
RaiseEvent EnterPressed (Me, EventArgs.Empty)
Return True''True means that we have dealt with the corresponding key
Else
Return MyBase.ProcessDialogKey (keyData)
End If
End Function
Not achieve the internal generated from ProcessDialogKey KeyDown event, I decided to use a more direct way: EnterPressed event. In order, I modified the ResourceImageEditor.EditValue implementation to deal with this incident (not KeyDown event), and everything went very smoothly.
You can use this technology to block any Control derived classes (you use it to achieve the type of editor you the drop-down UI) in the ENTER key.
????:
