VB.net Basics: A simple custom control Mypicturebox

Source: Internet
Author: User
Tags definition exit thread
Control first explains that some lines of code are longer so it is not easy to see. It is recommended that you paste it into the vs.net first so that it looks better.

In the title of "simple", is not to say that the code is simple, but the idea is relatively simple. A disadvantage of PictureBox in vs.net is that it is difficult to control position and size. So Mypicturebox is such a PictureBox: it has an attribute viewmode that represents the pattern for displaying pictures, including Fitsize,truesize and StretchImage. The latter two see the name also can see the meaning, Fitsize is a compromise way: when the picture size is smaller than mypicturebox size, do not do picture scaling. Also, Mypicturebox automatically put the picture in the middle, when its size changes can also keep the picture in the middle of the mypicturebox. In addition, when the picture size is larger than the Mypicturebox size, the user can "drag" the picture like Photoshop hand tool to facilitate browsing. In short, our mypicturebox on these three major features.

First, create a new project with the Windows Control Library and drag a PictureBox onto the user control. The interface is OK.

And then we're going to define ViewMode. Create an enum First:
Public Enum Vmode
Fitsize = 0
StretchImage = 1
Truesize = 2
End Enum

Then create a variable to store the ViewMode attribute:
Private Vviewmode as Vmode = Vmode.truesize

When ViewMode changes, it is necessary for the control to issue an event to the outside world:
Public Event viewmodechanged (ByVal Mode as Vmode)

You can now write the ViewMode attribute:
Public Property ViewMode () as Vmode
Return Vviewmode
End Get
Set (ByVal Value as Vmode)
Dim changed as Boolean = False
If Value <> vviewmode Then changed = True
Vviewmode = Value
If changed Then showpic ()
RaiseEvent viewmodechanged (Value)
End Set
End Property

Here, Showpic () is a method that has not been defined to display pictures.
In addition, since it is mypicturebox, it must have PictureBox kind. So you add an image property:
Public Property Image () as Image
Return pictureBox1.Image
End Get
Set (ByVal Value as Image)
If value is nothing Then ' determines if value is null.
Picturebox1.borderstyle = BorderStyle.None
Exit Property
Picturebox1.borderstyle = BorderStyle.FixedSingle
End If
Value = New Bitmap (value)
Picturebox1.sizemode = Pictureboxsizemode.stretchimage
pictureBox1.Image = Value
Imagerate = Value.width/value.height
Showpic ()
End Set
End Property

Here imagerate is a variable that avoids the definition of the overhead of a duplicate calculation, which is used to store the width-height ratio of the image, and the type is single. You can precede it with its definition.
Now we're going to write Showpic. For the structure of the code is clear, Showpic content is simple:
Private Sub Showpic ()
If pictureBox1.Image is nothing Then Exit Sub
If picturebox1.visible = False Then picturebox1.visible = True
Resizeimage ()
End Sub

The reason to write resizeimage separately is because there are other places to reuse it. The role of Resizeimage is to change the SizeMode property of the PictureBox1 based on the current ViewMode value and decide whether to scale the picture:
Private Sub Resizeimage ()
If pictureBox1.Image is nothing Then Exit Sub

If Vviewmode = vmode.fitsize Then
If PictureBox1.Image.Width > Me.Width Or PictureBox1.Image.Height > Me.height Then
StretchImage ()
If not Picturebox1.sizemode = pictureboxsizemode.autosize Then Picturebox1.sizemode = pictureboxsizemode.autosize
End If
ElseIf Vviewmode = Vmode.stretchimage Then
StretchImage ()
If not Picturebox1.sizemode = pictureboxsizemode.autosize Then Picturebox1.sizemode = pictureboxsizemode.autosize
End If

Locateimage ()
End Sub

This section of the judgment is somewhat complicated, but it should be able to write a little better. The role of StretchImage and locateimage can probably be seen from the name. First look at StretchImage. It's the way to actually scale the picture. It's not complicated, actually:
Private Sub StretchImage ()
Picturebox1.sizemode = Pictureboxsizemode.stretchimage
If Merate < Imagerate Then
Picturebox1.width = Me.Width
Picturebox1.height = Picturebox1.width/imagerate
Picturebox1.height = Me.height
Picturebox1.width = Picturebox1.height * imagerate
End If
End Sub

Here merate is used to preserve the aspect ratio of the mypicturebox itself. The type is single and can now be preceded by its definition. Obviously, Strechimage is actually changing the width of the PictureBox1. After calculating the size of the picture frame, to keep the picture in the middle, you need to calculate the position of the picture frame. Locateimage is used for this:
Private Sub Locateimage ()
If Picturebox1.width < Me.Width Then
Picturebox1.left = (me.width-picturebox1.width)/2
Picturebox1.left = 0
End If

If Picturebox1.height < Me.height Then
Picturebox1.top = (me.height-picturebox1.height)/2
Picturebox1.top = 0
End If
End Sub

When the Mypicturebox size changes, the size and position of the picture will be recalculated. Yes, it should be written in the resize incident. But wait a minute. If you do not control, in the user drag changes in the Mypicturebox size of the process, because the constant calculation of the size and location of the picture, CPU occupancy rate will reach 100%. This is very unfriendly, even can use "overbearing" to describe. Maybe we should open a thread to avoid this situation with sleep in the thread. But it's a bit too complicated to write. So we use timer as a compromise. Go back to the designer view and drag a timer. Set the interval value to 25. In Timer1_Tick, write:
Private Sub Timer1_Tick (ByVal sender as System.Object, ByVal e as System.EventArgs) Handles Timer1.tick
If Vviewmode = vmode.stretchimage Or Vviewmode = vmode.fitsize Then
Resizeimage ()
Locateimage ()
End If
Timer1.stop ()
End Sub

And then write in the Resize event:
Private Sub mypicturebox_resize (ByVal sender as Object, ByVal e as System.EventArgs) Handles mybase.resize
Merate = Me.width/me.height
Timer1.start ()
End Sub

Such a combination will be able to achieve the goal.

Then we write "drag" the function of the picture. Obviously, this function is only useful when viewmode=truesize. This function is divided into three parts, first, the MouseDown event:
Private Sub Picturebox1_mousedown (ByVal sender as Object, ByVal e as System.Windows.Forms.MouseEventArgs) Handles picture Box1.mousedown
If E.button <> mousebuttons.left Or viewmode <> vmode.truesize Then Exit Sub
moving = True
Me.cursor = System.Windows.Forms.Cursors.Hand
Mousepos = Me.mouseposition
Oldscroll = Me.autoscrollposition
End Sub

Here the moving variable is used to indicate whether the user is dragging a picture, and the type is Boolean. No definition? Go to the front and define it. What else mousepos,oldscroll, the type of them is point. Let's go define it. When the user presses the left mouse button, record the mouse position and picture when the front scroll position.

Then the MouseMove event:

Wait a minute. When the user moves the mouse, it is time to constantly calculate the scroll position of the picture frame. In order to avoid "overbearing" again, we have to drag in a timer. Set the interval value to 1. This timer is like this:
Private Sub Timer2_tick (ByVal sender as System.Object, ByVal e as System.EventArgs) Handles Timer2.tick
Mouseposnow = Me.mouseposition
Dim Deltapos as Point = New point ((mousepos.x-mouseposnow.x), (MOUSEPOS.Y-MOUSEPOSNOW.Y))
Me.autoscrollposition = New Point (-oldscroll.x + deltapos.x,-oldscroll.y + deltapos.y)
Timer2.stop ()
End Sub

Four words, should not be too ugly understand it.
So MouseMove is like this:
Private Sub Picturebox1_mousemove (ByVal sender as Object, ByVal e as System.Windows.Forms.MouseEventArgs) Handles picture Box1.mousemove
If Moving Then
Timer2.start ()
End If
End Sub

The third part is the MouseUp incident, just two sentences:
Private Sub Picturebox1_mouseup (ByVal sender as Object, ByVal e as System.Windows.Forms.MouseEventArgs) Handles Picturebo X1. MouseUp
moving = False
Me.cursor = System.Windows.Forms.Cursors.Default
End Sub

In this way, Mypicturebox is written.

...... Yes, it's written. Run a look.

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.