Build a pop-up image button

Source: Internet
Author: User
Tags abstract border color implement visual studio
button to build a Windows control is not a particularly complicated matter. I've talked in previous articles about how to build complex controls with the most professional techniques, but that doesn't mean it's so complicated to build all the controls. In this article I will address a real-world problem in a simple way that I have encountered in my work. Even if you have some or no experience building a control, you can use it to add complex functionality to your desktop application.

I need a pop-up button with a different image to implement the normal, mouse-hover, and Mouse-down states. I can use a regular WinForm button to achieve most of the effects I want, but I can't add color to the border. I also want to move the image to the right edge of the button, just like the menu button. To be exact, I need a menu button that can represent its own function.

You can build this control with about 150 lines of code, and the longest process contains about 25 lines of code. This method is a good starting point; You can add a lot of performance to it and use it as a pattern for other types of controls. The properties of the process may be one of the most complex in this project-a true proof of the thoughtful base class provided by. Net.

The basic approach is to start with a control that already exists and to add or change its behavior through inheritance. The paint event of the control allows you to draw arbitrarily in the form. For a ListBox or TreeView, it may take a lot of work to complete this function, but for a button, just use the image as a surface. You can draw the appropriate image using the Paint event of a button control by deriving from the button class the ImageButton class you need. However, Button properties such as image, FlatStyle, and autosize are meaningless for a pop-up button. Instead, you can derive it from the control base class and add a border to it yourself. This does not require you to write additional code, it will generate a more efficient control and a generic template for building other control forms.

The behavior of a pop-up button is very simple. It has three states, each with a border and an image. The control base class supports a set of mouse processes that can be overwritten (override), as well as paint programs. You can start a program by simply deriving it from the Windows.Forms.Control. Strangely, the control base class is not a "must-inherit class" (usually an abstract class), which means that you do not have to overwrite any methods when deriving from the class as a base class. Overwrite means that Windows and. NET allow you to execute your own code when someone or something (the system) invokes a method of the base class. This is very useful.

Make selections when drawing
When one end user switches to another page, ImageButton, Windows, and. NET notify the control class. The control class passes Windows information to the successor's OnPaint program. You can run your own code while writing the overlay program, rather than following the basic class approach. Although the control class is not an abstract base class, it does not finish any drawing itself. However, when you need to inherit a class--such as a button or a label class--you usually replace the painting of the base class instead of adding it to your program. The OnPaint overlay includes a call to MyBase, not because the base class needs processing to implement the drawing, but rather to provide the user with a paint event of its own. An inheriting class does not directly represent its base class to trigger an event, and a call to Mybase.onpaint causes the base class to trigger a client paint event.

This will have an impact on your future build controls, so in order for you to have a more comprehensive understanding I will tell it from another perspective. If you support your own work by overwriting a onpaint (that is, for a standard button base class), and you do not just want to implement the base class to draw, then your OnPaint overlay should not contain mybase.onpaint calls. In this scenario, if you also want to provide a paint event for developers who use derived controls, you must provide a Paint event declaration in the base class. If a paint event already exists in the base class, you must use the SHADOWS keyword to declare your own event to hide the base class event. Don't try to use shadows easily, because it's easy to confuse developers who use the control, although it may seem safer to use this method in an event.

Shadows simply displays a derived version of a method to the user with a name similar to the base class. The potential problem with it is that users can still get methods in the base class by using CType to convert objects in your class to base classes. Some of the methods in the control class are of no use to ImageButton. For example, the Text property is not required. You can replace Control.text with a ReadOnly property in Visual Studio's Properties window, returning an empty string. Users may find it troublesome, but this avoids some problems: Dim Pop1 as New ImageButton
CType (POP1, control). Text = "Hi"





The preceding code does not cause an error, but it does not really work; ImageButton does not draw the control through the Text property of its base class. However, if a user attempts to fill in the ImageButton Text property, a design-time (compiled) read-only error will result: Dim Pop1 as New ImageButton
Pop1. Text = "Hi" ' Error





Finally, the Text property is hidden by adding the <browsable (False) > property to the Declaration. It also requires you to provide a new default attribute to the user, otherwise it is invalid because the control's lack of property is text. Use the Displayimageindex property as a new <defaultproperty by adding the Displayimageindex > to the class declaration.

Painted Blue
As with menu buttons, ImageButton must have different image and border styles, depending on the location of the mouse. Unlike a menu button, ImageButton must be able to get focus and display the focus rectangle. All attributes must be implemented through code because the control class will not handle it. However, you can implement it in just a short piece of code, as you would see from the OnPaint process.

You can get mouse notifications from the system through the Onmouseenter, Leave, up, and down overlay processes. You can use them just as you would with a normal mouse event, but using overrides means you can add new behavior before or after the base class provides the behavior, or replace the behavior of the base class. By setting a mousebuttonstate variable, you can use each procedure to decide which image to drag into the control interface. OnMouseDown also sets the focus: Overrides Sub OnMouseDown (ByVal Ma as _
MouseEventArgs)
Mybase.onmousedown (MA)
_mousebuttonstate = Down
Me.focus ()
Mybase.invalidate ()
End Sub




The control.invalidate call is used to tell the base class that the control needs to be repaint. The base class calls the overridden OnPaint method in turn, which provides a GDI + image object through PaintEventArgs. You can use this object-shared DrawImage method to draw a bitmap (bitmap) in one line of code, providing the DrawImage with images, locations, and sizes, and choosing which image to draw to the mouse position. A convenient design-state-specific Displayimageindex property allows the user to choose which image to display. You can use both attributes in the declaration of the method: <category ("Design") > Tell the Visual Studio Properties window where to list the property, <designonly (True) > is used to hide it at run time. Add an enumeration to the Displayimageindex value to allow the user to see down, up, and hover by simply clicking on the value. Displayimageindex users do not need to open the ImageList control to ensure that they choose the correct imageindex value for down, up, and hover.

You can use the mouse position to select the border color you want to draw. When the focus is on the control, the code sets the border thickness to two pixel points and is used only for the up state. Create a new Pen object (do not use the default system's brush) to draw a row larger than a pixel point. Don't forget to call the Dispose method when you finish. You should resize the bounding rectangle based on the width of the border, because the control cannot be drawn outside the form at will.

I never like to use the button image algorithm operation to show up, over and down state, each ImageButton with three separate bitmaps. Using many imagebuttons in a form can result in a large number of images, so I give ImageButton a ImageList attribute instead of three image attributes. This property is declared as Forms.imagelist, and the NET and Vs.net IDE handles a lot of work for you. You don't need to write code to detect ImageList, and the Properties window will show it. Another benefit of using ImageList is that it excludes the possibility of using code to handle user-supplied image sizes. When the user loads it at a different size, the ImageList represents a single size and proportions of the image.

The size of the image determines the size of the ImageButton; the control has no AutoSize property. If a user tries to resize a control by dragging its border or through the property window, ImageButton is immediately reset to the size of the image. You can get that behavior by overwriting the onsizechanged process, and you can also hide the non-overwritten size attribute of the control class with a read-only version. This poses a problem for the IDE because he wants to serialize the size property and try to set it to the "Designer generated code" area of the user form. Add <designerserializationvisibility (Designerserializationvisibility.hidden) > Properties to prevent users from reading its property serialization at design time. It provides a more user-friendly tool to the user.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.