I made a search and successfully found a solution to draw a rectangle inside my Picturebox while mousemoving using a class named Rectangulo:
Public Class Form1
Dim SelectionBoxObj As New Rectangulo()
Dim IsMouseDown As Boolean = False
Public SelectedObjPoint As Point
Private Sub PictureBox1_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
If e.Button = Windows.Forms.MouseButtons.Left Then
IsMouseDown = True
SelectedObjPoint = New Point(e.X, e.Y)
End If
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
If IsMouseDown = True Then
If e.X < SelectionBoxObj.X Then
SelectionBoxObj.X = e.X
SelectionBoxObj.Width = SelectedObjPoint.X - e.X
Else
SelectionBoxObj.X = SelectedObjPoint.X
SelectionBoxObj.Width = e.X - SelectedObjPoint.X
End If
If e.Y < SelectedObjPoint.Y Then
SelectionBoxObj.Y = e.Y
SelectionBoxObj.Height = SelectedObjPoint.Y - e.Y
Else
SelectionBoxObj.Y = SelectedObjPoint.Y
SelectionBoxObj.Height = e.Y - SelectedObjPoint.Y
End If
Me.Refresh()
End If
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp
IsMouseDown = False
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
If SelectionBoxObj.Width > 0 And SelectionBoxObj.Height > 0 Then
Dim oGradientBrush As Brush = New Drawing.Drawing2D.LinearGradientBrush(SelectionBoxObj.RectangleF, SelectionBoxObj.FillColor, SelectionBoxObj.FillColor, Drawing.Drawing2D.LinearGradientMode.Vertical)
e.Graphics.FillRectangle(oGradientBrush, SelectionBoxObj.RectangleF)
Dim TempPen = New Pen(SelectionBoxObj.BorderLineColor, SelectionBoxObj.BorderLineWidth)
TempPen.DashStyle = SelectionBoxObj.BorderLineType
e.Graphics.DrawRectangle(TempPen, SelectionBoxObj.RectangleF.X, SelectionBoxObj.RectangleF.Y, SelectionBoxObj.RectangleF.Width, SelectionBoxObj.RectangleF.Height)
End If
End Sub
End Class
And the Rectangle Class code:
Public Class Rectangulo
Private m_BorderLineColor As Color = Drawing.Color.FromArgb(255, 51, 153, 255)
Private m_FillColor As Color = Drawing.Color.FromArgb(40, 51, 153, 255)
Private m_BorderLineType As Drawing2D.DashStyle = Drawing2D.DashStyle.Solid
Private m_BorderLineWidth As Integer = 1
Private m_X As Single
Private m_Y As Single
Private m_Width As Single
Private m_Height As Single
Private m_RectangleF As RectangleF
Public Property BorderLineWidth() As Integer
Get
Return m_BorderLineWidth
End Get
Set(ByVal value As Integer)
m_BorderLineWidth = value
End Set
End Property
Public Property BorderLineType() As Drawing2D.DashStyle
Get
Return m_BorderLineType
End Get
Set(ByVal value As Drawing2D.DashStyle)
m_BorderLineType = value
End Set
End Property
Public Property BorderLineColor() As Color
Get
Return m_BorderLineColor
End Get
Set(ByVal value As Color)
m_BorderLineColor = value
End Set
End Property
Public Property FillColor() As Color
Get
Return m_FillColor
End Get
Set(ByVal value As Color)
m_FillColor = value
End Set
End Property
Public Property X() As Single
Get
Return m_RectangleF.X
End Get
Set(ByVal value As Single)
m_RectangleF.X = value
End Set
End Property
Public Property Y() As Single
Get
Return m_RectangleF.Y
End Get
Set(ByVal value As Single)
m_RectangleF.Y = value
End Set
End Property
Public Property Width() As Single
Get
Return m_RectangleF.Width
End Get
Set(ByVal value As Single)
m_RectangleF.Width = value
End Set
End Property
Public Property Height() As Single
Get
Return m_RectangleF.Height
End Get
Set(ByVal value As Single)
m_RectangleF.Height = value
End Set
End Property
Public Property RectangleF() As RectangleF
Get
Return m_RectangleF
End Get
Set(ByVal value As RectangleF)
m_RectangleF = value
End Set
End Property
End Class
So far I found this article and adjusted with my code in mousemove event like this:
Dim top As Integer = Integer.Parse(SelectionBoxObj.Y)
Dim left As Integer = Integer.Parse(SelectionBoxObj.X)
Dim width As Integer = Integer.Parse(SelectionBoxObj.Width)
Dim height As Integer = Integer.Parse(SelectionBoxObj.Height)
' Make a Bitmap to hold the result.
If width > 0 And height > 0 Then
Dim bm As New Bitmap(width, height)
' Associate a Graphics object with the Bitmap
Using gr As Graphics = Graphics.FromImage(bm)
' Define source and destination rectangles.
Dim src_rect As New Rectangle(left, top, width, _
height)
Dim dst_rect As New Rectangle(0, 0, width, height)
' Copy that part of the image.
gr.DrawImage(PictureBox1.Image, dst_rect, src_rect, _
GraphicsUnit.Pixel)
End Using
' Display the result.
PictureBox2.Image = bm
And It's almost done! But the only problem now is the points are incorrect, the image displayed is always from the middle of selection to right and not his full size of selection
Thanks in advance
Related
Good afternoon!
There is a custom class that adds a text column with an image to the DataGridView.
Public Class DataGridViewTextAndImageColumn
Inherits DataGridViewTextBoxColumn
Private imageValue As Image
Private imageSize_Renamed As Size
Public Sub New()
CellTemplate = New TextAndImageCell()
End Sub
Public Overrides Function Clone() As Object
Dim c As DataGridViewTextAndImageColumn = TryCast(MyBase.Clone(), DataGridViewTextAndImageColumn)
c.imageValue = imageValue
c.imageSize_Renamed = imageSize_Renamed
Return c
End Function
Public Property Image() As Image
Get
Return imageValue
End Get
Set(ByVal value As Image)
If Image IsNot value Then
imageValue = value
imageSize_Renamed = value.Size
If InheritedStyle IsNot Nothing Then
Dim inheritedPadding As Padding = InheritedStyle.Padding
DefaultCellStyle.Padding = New Padding(imageSize_Renamed.Width, inheritedPadding.Top, inheritedPadding.Right, inheritedPadding.Bottom)
End If
End If
End Set
End Property
Friend ReadOnly Property ImageSize() As Size
Get
Return imageSize_Renamed
End Get
End Property
End Class
Public Class TextAndImageCell
Inherits DataGridViewTextBoxCell
Private imageValue As Image
Private imageSize As Size
Public Overrides Function Clone() As Object
Dim c As TextAndImageCell = TryCast(MyBase.Clone(), TextAndImageCell)
c.imageValue = imageValue
c.imageSize = imageSize
Return c
End Function
Public Property Image() As Image
Get
If OwningColumn Is Nothing OrElse Me.OwningTextAndImageColumn Is Nothing Then
Return imageValue
ElseIf imageValue IsNot Nothing Then
Return imageValue
Else
Return OwningTextAndImageColumn.Image
End If
End Get
Set(ByVal value As Image)
If imageValue IsNot value Then
imageValue = value
imageSize = value.Size
Dim inheritedPadding As Padding = InheritedStyle.Padding
Style.Padding = New Padding(imageSize.Width, inheritedPadding.Top, inheritedPadding.Right, inheritedPadding.Bottom)
End If
End Set
End Property
Protected Overrides Sub Paint(ByVal graphics As Graphics, ByVal clipBounds As Rectangle, ByVal cellBounds As Rectangle, ByVal rowIndex As Integer, ByVal cellState As DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As DataGridViewCellStyle, ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, ByVal paintParts As DataGridViewPaintParts)
' Paint the base content
MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
If Image IsNot Nothing Then
' Draw the image clipped to the cell.
Dim container As Drawing2D.GraphicsContainer = graphics.BeginContainer()
graphics.SetClip(cellBounds)
graphics.DrawImageUnscaled(Image, cellBounds.Location)
graphics.EndContainer(container)
End If
End Sub
Private ReadOnly Property OwningTextAndImageColumn() As DataGridViewTextAndImageColumn
Get
Return TryCast(OwningColumn, DataGridViewTextAndImageColumn)
End Get
End Property
End Class
Form:
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With DataGridView1
.DefaultCellStyle.WrapMode = DataGridViewTriState.True
.Columns(1).DefaultCellStyle.WrapMode = DataGridViewTriState.True
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
.SelectionMode = DataGridViewSelectionMode.FullRowSelect
End With
End Sub
End Class
Result of work:
The question is:
The question is:
When a column is line-wrapped, the text is centered vertically in the cell. How to make a picture in a cell also centered regardless of the line height?
I am trying to make a fancy home screen which alternates between three pictures, every 3 seconds. How will i do this and, if possible, is it possible to make them fade in and out to look a bit better?
Here is my code:
Private Sub frmLoadUp_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim images As New List(Of Image)()
images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\home pc.png"))
images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\mid range pc.png"))
images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\high end pc.png"))
Dim pictureChangeTimer As New Timer()
AddHandler pictureChangeTimer.Tick, AddressOf pictureChangeTimer_tick
pictureChangeTimer.Interval = 3000
pictureChangeTimer.Start()
End Sub
Private Sub pictureChangeTimer_tick(sender As Object, e As EventArgs)
Index = (Index + 1) Mod images.Count()
PictureBox1.Image = images(Index)
PictureBox1.Image = Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\home pc.png")
PictureBox1.Image = Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\mid range pc.png")
PictureBox1.Image = Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\high end pc.png")
End Sub
Fill your list in the Form.Load but makes the list a Form level (class level) variable so you can see it from any method in the form. You can add the Timer in the designer and set its properties there. The image will start out at index 0; Integer initializes to zero.
When your timer ticks we increment Index (which is also a Form level variable; it will hold its value between calls to the method). Next we check if we have come to the end of the list and reset to zero if we have.
Private Index As Integer
Private images As New List(Of Image)()
Private Sub frmLoadUp_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\home pc.png"))
images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\mid range pc.png"))
images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\high end pc.png"))
Dim pictureChangeTimer As New Timer()
AddHandler pictureChangeTimer.Tick, AddressOf pictureChangeTimer_tick
pictureChangeTimer.Interval = 3000
PictureBox1.Image = images(Index)
pictureChangeTimer.Start()
End Sub
Private Sub pictureChangeTimer_tick(sender As Object, e As EventArgs)
Index += 1
If Index > 2 Then 'There is no Index 3 so we start from the beginning again
Index = 0
End If
PictureBox1.Image = Images(Index)
End Sub
You need a few changes:
(1) Declare Images at the class level
(2) Change your picture timer to set the image by index and reset the index
Dim Images As New List(Of Image)()
Dim Index as Integer
Private Sub frmLoadUp_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\home pc.png"))
Images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\mid range pc.png"))
Images.Add(Image.FromFile("C:\Users\lukem\Desktop\TO COPY TO ONEDRIVE\PCs\high end pc.png"))
Index = -1;
Dim pictureChangeTimer As New Timer()
AddHandler pictureChangeTimer.Tick, AddressOf pictureChangeTimer_tick
pictureChangeTimer.Interval = 3000
pictureChangeTimer.Start()
End Sub
Private Sub pictureChangeTimer_tick(sender As Object, e As EventArgs)
Index = If(Index = 2, 0, Index + 1)
PictureBox1.Image = Images(Index)
End Sub
Consider using a ColorMatrix to blend images.
First of all, create custom picture box.(code from another question)
Imports System.Drawing.Imaging
Public Class CustomPictureBox
Inherits PictureBox
Private mImg1 As Image
Private mImg2 As Image
Private mBlend As Single
Public Sub New()
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True)
End Sub
Public Property Image1 As Image
Get
Return mImg1
End Get
Set(ByVal value As Image)
mImg1 = value
Invalidate()
End Set
End Property
Public Property Image2 As Image
Get
Return mImg2
End Get
Set(ByVal value As Image)
mImg2 = value
Invalidate()
End Set
End Property
Public Property Blend As Single
Get
Return mBlend
End Get
Set(ByVal value As Single)
mBlend = value
Invalidate()
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
If mImg1 Is Nothing OrElse mImg2 Is Nothing Then
e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), New Rectangle(0, 0, Me.Width, Me.Height))
Else
Dim rc As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height)
Dim cm As ColorMatrix = New ColorMatrix()
Dim ia As ImageAttributes = New ImageAttributes()
cm.Matrix33 = mBlend
ia.SetColorMatrix(cm)
e.Graphics.DrawImage(mImg2, rc, 0, 0, mImg2.Width, mImg2.Height, GraphicsUnit.Pixel, ia)
cm.Matrix33 = 1.0F - mBlend
ia.SetColorMatrix(cm)
e.Graphics.DrawImage(mImg1, rc, 0, 0, mImg1.Width, mImg1.Height, GraphicsUnit.Pixel, ia)
End If
MyBase.OnPaint(e)
End Sub
End Class
Then drag 'CustomPictureBox' and 'Timer' from Toolbox to the form.
Finally, you can refer to the following code to change the contents of a picture box every 3 seconds.
Private mBlend As Single
Private mDir As Integer = 1
Public index As Integer = 0
Public Images As List(Of Image) = New List(Of Image)()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Images.Add(New Bitmap("path of picture1"))
Images.Add(New Bitmap("path of picture2"))
Images.Add(New Bitmap("path of picture3"))
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Timer1.Interval = 60
CustomPictureBox1.Image1 = Images(index)
index += 1
CustomPictureBox1.Image2 = Images(index)
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
mBlend += mDir * 0.02F
If mBlend > 1 Then
mBlend = 0.0F
If (index + 1) < Images.Count Then
CustomPictureBox1.Image1 = Images(index)
index += 1
CustomPictureBox1.Image2 = Images(index)
Else
CustomPictureBox1.Image1 = Images(index)
CustomPictureBox1.Image2 = Images(0)
index = 0
End If
End If
CustomPictureBox1.Blend = mBlend
End Sub
Result of my test.
i have class inherited from textbox , and when i try to add the control from the toolbox i have this error in the picture.
this is class inherited from textbox control ,using listbox control to choose from auto complete list
Public Structure Account
Dim Name As String
Dim Number As String
Public Sub New(Namee As String, Num As String)
Name = Namee
Number = Num
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Structure
Public Class AutoCompleteTextBox
Inherits TextBox
Private ACL As List(Of Account), CACL As List(Of Account)
Private CaseSensitive As Boolean
Private MinChar As Integer
Private LS As ListBox
Private OLDText As String
Private PN As Panel
Public Sub New()
MyBase.New
MinTypedCharacters = 2
CaseSesitivity = False
ACL = New List(Of Account)
LS = New ListBox
LS.Name = "SeggestionListBox"
LS.Font = Font
LS.Visible = True
PN = New Panel
PN.Visible = False
PN.Font = Font
PN.AutoSizeMode = AutoSizeMode.GrowAndShrink
PN.ClientSize = New Size(1, 1)
PN.Name = "SeggestionPanel"
PN.Padding = New Padding(0, 0, 0, 0)
PN.Margin = New Padding(0, 0, 0, 0)
PN.BackColor = Color.Transparent
PN.ForeColor = Color.Transparent
PN.PerformLayout()
If Not PN.Controls.Contains(LS) Then
PN.Controls.Add(LS)
End If
LS.Dock = DockStyle.Fill
LS.SelectionMode = SelectionMode.One
AddHandler LS.KeyDown, AddressOf LS_KeyDown
AddHandler LS.MouseClick, AddressOf LS_MouseClick
AddHandler LS.MouseDoubleClick, AddressOf LS_MouseDoubleClick
CACL = New List(Of Account)
LS.DataSource = CACL
OLDText = Text
End Sub
#Region "Properties"
Public Property AutoCompleteList As List(Of Account)
Get
Return ACL
End Get
Set(value As List(Of Account))
ACL.Clear()
ACL = value
End Set
End Property
Public Property CaseSesitivity As Boolean
Get
Return CaseSensitive
End Get
Set(value As Boolean)
CaseSensitive = value
End Set
End Property
Public Property MinTypedCharacters As Integer
Get
Return MinChar
End Get
Set(value As Integer)
MinChar = value
End Set
End Property
Public Property SelectedIndex As Integer
Get
Return LS.SelectedIndex
End Get
Set(value As Integer)
If LS.Items.Count <> 0 Then
LS.SelectedIndex = value
End If
End Set
End Property
Private ReadOnly Property ParentForm As Form
Get
Return Me.Parent.FindForm
End Get
End Property
#End Region
Public Sub HideSuggestionListBox()
If Not ParentForm Is Nothing Then
PN.Hide()
If ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Remove(PN)
End If
End If
End Sub
Private Function SelectItem() As Boolean
If LS.Items.Count > 0 AndAlso LS.SelectedIndex > -1 Then
Text = LS.SelectedItem.ToString
HideSuggestionListBox()
End If
Return True
End Function
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
If e.KeyCode = Keys.Up Then
MoveSelection(SelectedIndex - 1)
e.Handled = True
ElseIf e.KeyCode = Keys.Down Then
MoveSelection(SelectedIndex + 1)
e.Handled = True
ElseIf e.KeyCode = Keys.PageUp Then
MoveSelection(SelectedIndex - 10)
e.Handled = True
ElseIf e.KeyCode = Keys.PageDown Then
MoveSelection(SelectedIndex + 10)
e.Handled = True
ElseIf e.KeyCode = Keys.Enter Then
SelectItem()
e.Handled = True
Else
MyBase.OnKeyDown(e)
End If
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
If Not PN.ContainsFocus Then
MyBase.OnLostFocus(e)
If Not CheckItem(Text) Then
Text = ""
End If
HideSuggestionListBox()
End If
End Sub
Protected Overrides Sub OnTextChanged(e As EventArgs)
If Not DesignMode Then
ShowSuggests()
End If
MyBase.OnTextChanged(e)
OLDText = Text
End Sub
Private Sub LS_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If (e.KeyCode = Keys.Enter) Then
Me.SelectItem()
e.Handled = True
End If
End Sub
Private Sub LS_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
' select the current item
Me.SelectItem()
MsgBox(LS.SelectedItem.number)
End Sub
Private Sub LS_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.SelectItem()
End Sub
Private Function CheckItem(ItemSTR As String) As Boolean
For Each STR As Account In ACL
If ItemSTR.ToLower = STR.ToString.ToLower Then
Return True
Exit Function
End If
Next
Return False
End Function
Private Sub MoveSelection(Index As Integer)
If Index <= -1 Then
SelectedIndex = 0
ElseIf Index > (LS.Items.Count - 1) Then
SelectedIndex = LS.Items.Count - 1
Else
SelectedIndex = Index
End If
End Sub
Private Sub ShowSuggests()
If Text.Length >= MinTypedCharacters Then
PN.SuspendLayout()
If Text.Length > 0 AndAlso OLDText = Text.Substring(0, Text.Length - 1) Then
UpdateCurrentAutoCompleteList()
ElseIf OLDText.Length > 0 AndAlso Text = OLDText.Substring(0, OLDText.Length - 1) Then
UpdateCurrentAutoCompleteList()
Else
UpdateCurrentAutoCompleteList()
End If
If Not CACL Is Nothing AndAlso CACL.Count > 0 Then
PN.Show()
PN.BringToFront()
Focus()
Else
HideSuggestionListBox()
End If
PN.ResumeLayout()
Else
HideSuggestionListBox()
End If
End Sub
Private Sub UpdateCurrentAutoCompleteList()
CACL.Clear()
For Each STR As Account In ACL
If CaseSesitivity = True Then
If STR.ToString.IndexOf(Text) > -1 Then
CACL.Add(STR)
End If
Else
If STR.ToString.ToLower.IndexOf(Text.ToLower) > -1 Then
CACL.Add(STR)
End If
End If
Next
If CACL.Count > 0 Then
UpdateListBoxItems()
Else
HideSuggestionListBox()
End If
End Sub
Private Sub UpdateListBoxItems()
If Not ParentForm Is Nothing Then
PN.Width = Width
'PN.Height = ParentForm.ClientSize.Height - Height - Location.Y
Dim F As Integer = ParentForm.ClientSize.Height - Height - Location.Y
Dim Ten As Integer = Font.Height * 10
Dim CUr As Integer = Font.Height * (CACL.Count + 1)
If F < CUr Then
PN.Height = F
ElseIf CUr < Ten Then
PN.Height = CUr
ElseIf Ten < F Then
PN.Height = Ten
Else
PN.Height = F
End If
'PN.Height = Font.Height * 10
PN.Location = Location + New Size(0, Height)
If Not ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Add(PN)
End If
CType(LS.BindingContext(CACL), CurrencyManager).Refresh()
End If
End Sub
End Class
firstly i used list(of string) before using the structure account .
the problem appears after using the structure
Any Idea about this error ?
**** additional picture show another problem after substitutes the structure with class and adds attribute.
***** changed the Structure to class
<Serializable> Public Class Account
Private Nam As String
Private Numbe As String
Public Sub New(Namee As String, Num As String)
Name = Namee
Number = Num
End Sub
Public Property Name As String
Get
Return Nam
End Get
Set(value As String)
Nam = value
End Set
End Property
Public Property Number As String
Get
Return Numbe
End Get
Set(value As String)
Numbe = value
End Set
End Property
Public Overrides Function ToString() As String
Return Name
End Function
End Class
Problem Resolved*
i will share the solve with you.
all the problem is coming from the line
ACL = New List(Of Account)
and the line
CACL = New List(Of Account)
because it declare new list(of account) in design time.
i solved the problem by deleting the both of line and modified the property (AutoCompleteList) to be like that.
Public WriteOnly Property AutoCompleteList As List(Of Account)
Set(value As List(Of Account))
ACL = value
CACL = New List(Of Account)
End Set
End Property
and the final code will be like that:-
the structure:
Public Structure Account
Public Name As String
Public Number As String
Public Sub New(Namee As String, Num As String)
Name = Namee
Number = Num
End Sub
Public Overrides Function ToString() As String
Return Name
End Function
End Structure
the class:
Public Class AutoCompleteTextBox
Inherits TextBox
Private ACL As List(Of Account), CACL As List(Of Account)
Private CaseSensitive As Boolean
Private MinChar As Integer
Private LS As ListBox
Private OLDText As String
Private PN As Panel
Public Sub New()
MyBase.New
MinTypedCharacters = 2
CaseSesitivity = False
LS = New ListBox
LS.Name = "SeggestionListBox"
LS.Font = Font
LS.Visible = True
PN = New Panel
PN.Visible = False
PN.Font = Font
PN.AutoSizeMode = AutoSizeMode.GrowAndShrink
PN.ClientSize = New Size(1, 1)
PN.Name = "SeggestionPanel"
PN.Padding = New Padding(0, 0, 0, 0)
PN.Margin = New Padding(0, 0, 0, 0)
PN.BackColor = Color.Transparent
PN.ForeColor = Color.Transparent
PN.PerformLayout()
If Not PN.Controls.Contains(LS) Then
PN.Controls.Add(LS)
End If
LS.Dock = DockStyle.Fill
LS.SelectionMode = SelectionMode.One
AddHandler LS.KeyDown, AddressOf LS_KeyDown
AddHandler LS.MouseClick, AddressOf LS_MouseClick
AddHandler LS.MouseDoubleClick, AddressOf LS_MouseDoubleClick
LS.DataSource = CACL
OLDText = Text
End Sub
Public WriteOnly Property AutoCompleteList As List(Of Account)
Set(value As List(Of Account))
'ACL.Clear()
ACL = value
CACL = New List(Of Account)
End Set
End Property
Public Property CaseSesitivity As Boolean
Get
Return CaseSensitive
End Get
Set(value As Boolean)
CaseSensitive = value
End Set
End Property
Public Property MinTypedCharacters As Integer
Get
Return MinChar
End Get
Set(value As Integer)
MinChar = value
End Set
End Property
Public Property SelectedIndex As Integer
Get
Return LS.SelectedIndex
End Get
Set(value As Integer)
If LS.Items.Count <> 0 Then
LS.SelectedIndex = value
End If
End Set
End Property
Private ReadOnly Property ParentForm As Form
Get
Return Me.Parent.FindForm
End Get
End Property
Public Sub HideSuggestionListBox()
If Not ParentForm Is Nothing Then
PN.Hide()
If ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Remove(PN)
End If
End If
End Sub
Private Function SelectItem() As Boolean
If LS.Items.Count > 0 AndAlso LS.SelectedIndex > -1 Then
Text = LS.SelectedItem.ToString
MsgBox(LS.SelectedItem.number)
HideSuggestionListBox()
End If
Return True
End Function
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
If e.KeyCode = Keys.Up Then
MoveSelection(SelectedIndex - 1)
e.Handled = True
ElseIf e.KeyCode = Keys.Down Then
MoveSelection(SelectedIndex + 1)
e.Handled = True
ElseIf e.KeyCode = Keys.PageUp Then
MoveSelection(SelectedIndex - 10)
e.Handled = True
ElseIf e.KeyCode = Keys.PageDown Then
MoveSelection(SelectedIndex + 10)
e.Handled = True
ElseIf e.KeyCode = Keys.Enter Then
SelectItem()
e.Handled = True
Else
MyBase.OnKeyDown(e)
End If
End Sub
Protected Overrides Sub OnLostFocus(e As EventArgs)
If Not PN.ContainsFocus Then
MyBase.OnLostFocus(e)
If Not CheckItem(Text) Then
Text = ""
End If
HideSuggestionListBox()
End If
End Sub
Protected Overrides Sub OnTextChanged(e As EventArgs)
If Not DesignMode Then
ShowSuggests()
End If
MyBase.OnTextChanged(e)
OLDText = Text
End Sub
Private Sub LS_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If (e.KeyCode = Keys.Enter) Then
Me.SelectItem()
e.Handled = True
End If
End Sub
Private Sub LS_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs)
' select the current item
Me.SelectItem()
MsgBox(LS.SelectedItem.number)
End Sub
Private Sub LS_MouseDoubleClick(ByVal sender As Object, ByVal e As MouseEventArgs)
Me.SelectItem()
End Sub
Private Function CheckItem(ItemSTR As String) As Boolean
For Each STR As Account In ACL
If ItemSTR.ToLower = STR.ToString.ToLower Then
Return True
Exit Function
End If
Next
Return False
End Function
Private Sub MoveSelection(Index As Integer)
If Index <= -1 Then
SelectedIndex = 0
ElseIf Index > (LS.Items.Count - 1) Then
SelectedIndex = LS.Items.Count - 1
Else
SelectedIndex = Index
End If
End Sub
Private Sub ShowSuggests()
If Text.Length >= MinTypedCharacters Then
PN.SuspendLayout()
If Text.Length > 0 AndAlso OLDText = Text.Substring(0, Text.Length - 1) Then
UpdateCurrentAutoCompleteList()
ElseIf OLDText.Length > 0 AndAlso Text = OLDText.Substring(0, OLDText.Length - 1) Then
UpdateCurrentAutoCompleteList()
Else
UpdateCurrentAutoCompleteList()
End If
If Not CACL Is Nothing AndAlso CACL.Count > 0 Then
PN.Show()
PN.BringToFront()
Focus()
Else
HideSuggestionListBox()
End If
PN.ResumeLayout()
Else
HideSuggestionListBox()
End If
End Sub
Private Sub UpdateCurrentAutoCompleteList()
CACL.Clear()
For Each STR As Account In ACL
If CaseSesitivity = True Then
If STR.ToString.IndexOf(Text) > -1 Then
CACL.Add(STR)
End If
Else
If STR.ToString.ToLower.IndexOf(Text.ToLower) > -1 Then
CACL.Add(STR)
End If
End If
Next
If CACL.Count > 0 Then
UpdateListBoxItems()
Else
HideSuggestionListBox()
End If
End Sub
Sub Fill()
For Each A As Account In CACL
LS.Items.Add(A)
Next
End Sub
Private Sub UpdateListBoxItems()
If Not ParentForm Is Nothing Then
PN.Width = Width
'PN.Height = ParentForm.ClientSize.Height - Height - Location.Y
Dim F As Integer = ParentForm.ClientSize.Height - Height - Location.Y
Dim Ten As Integer = Font.Height * 10
Dim CUr As Integer = Font.Height * (CACL.Count + 1)
If F < CUr Then
PN.Height = F
ElseIf CUr < Ten Then
PN.Height = CUr
ElseIf Ten < F Then
PN.Height = Ten
Else
PN.Height = F
End If
'PN.Height = Font.Height * 10
PN.Location = Location + New Size(0, Height)
If Not ParentForm.Controls.Contains(PN) Then
ParentForm.Controls.Add(PN)
End If
Fill()
End If
End Sub
End Class
thank you all.
I'm trying to create a class for custom button control that will have 2 ingradient top and bottom color with rounded corners.
Below is the code that gives me two gradients color on top and bottom. However, I'm facing some issue with this where mouse hover property is not working and image also not showing (since new ingredients color overlaping the button text and image that is hidden in the back of ingradients color)
Can somebody help me with this control where all the control should work like they work with windows button control in addition to gradient color and rounded corners?
Please let me know in case you require any additional information.
Thanks in advance.
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
Class MyButton
Inherits Button
Private m_TopColor As Color = Color.LightGreen
Private m_BottomColor As Color = Color.Orange
Public Property TopColor As Color
Get
Return m_TopColor
End Get
Set(ByVal value As Color)
m_TopColor = value
Me.Invalidate()
End Set
End Property
Public Property BottomColor As Color
Get
Return m_BottomColor
End Get
Set(ByVal value As Color)
m_BottomColor = value
Me.Invalidate()
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
Using lgb As LinearGradientBrush = New LinearGradientBrush(Me.ClientRectangle, m_TopColor, m_BottomColor, 90.0F)
Using textBrush As SolidBrush = New SolidBrush(Me.ForeColor)
Using format As StringFormat = New StringFormat()
format.Alignment = GetHorizontalAlignment()
format.LineAlignment = GetVerticalAlignment()
e.Graphics.FillRectangle(lgb, Me.ClientRectangle)
e.Graphics.DrawString(Me.Text, Me.Font, textBrush, Me.ClientRectangle, format)
End Using
End Using
End Using
End Sub
Private Function GetVerticalAlignment() As StringAlignment
Return CType(Math.Log(Me.TextAlign, 2D) / 4, StringAlignment)
End Function
Private Function GetHorizontalAlignment() As StringAlignment
Return CType(Math.Log(Me.TextAlign, 2D) Mod 4, StringAlignment)
End Function
End Class
customize a rounded button,code:
Imports System.Drawing.Drawing2D
Class MyButton
Inherits Button
Private m_TopColor As Color = Color.LightGreen
Private m_BottomColor As Color = Color.Orange
Public Property TopColor As Color
Get
Return m_TopColor
End Get
Set(ByVal value As Color)
m_TopColor = value
Me.Invalidate()
End Set
End Property
Public Property BottomColor As Color
Get
Return m_BottomColor
End Get
Set(ByVal value As Color)
m_BottomColor = value
Me.Invalidate()
End Set
End Property
Public Sub New()
FlatStyle = FlatStyle.Flat
FlatAppearance.BorderSize = 0
FlatAppearance.BorderColor = Color.FromArgb(0, 0, 0, 0)
FlatAppearance.MouseDownBackColor = Color.Transparent
FlatAppearance.MouseOverBackColor = Color.Transparent
BackColor = Color.Transparent
Me.BackgroundImageLayout = ImageLayout.Zoom
AddHandler Me.MouseMove, AddressOf MyMouseMove
AddHandler Me.MouseLeave, AddressOf MyMouseLeave
End Sub
Private Sub MyMouseLeave(ByVal sender As Object, ByVal e As EventArgs)
End Sub
Private Sub MyMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
End Sub
Private Sub Draw(ByVal rectangle As Rectangle, ByVal g As Graphics, ByVal cusp As Boolean)
Dim span As Integer = 2
g.SmoothingMode = SmoothingMode.AntiAlias
Dim myLinearGradientBrush As LinearGradientBrush = New LinearGradientBrush(Me.ClientRectangle, m_TopColor, m_BottomColor, 90.0F)
g.FillPath(myLinearGradientBrush, DrawRoundRect(rectangle.X, rectangle.Y, rectangle.Width - span, rectangle.Height - 1, 20))
End Sub
Private Function DrawRoundRect(ByVal x As Integer, ByVal y As Integer, ByVal width As Integer, ByVal height As Integer, ByVal radius As Integer) As GraphicsPath
Dim gp As GraphicsPath = New GraphicsPath()
gp.AddArc(x, y, radius, radius, 180, 90)
gp.AddArc(width - radius, y, radius, radius, 270, 90)
gp.AddArc(width - radius, height - radius, radius, radius, 0, 90)
gp.AddArc(x, height - radius, radius, radius, 90, 90)
gp.CloseAllFigures()
Return gp
End Function
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
Draw(e.ClipRectangle, e.Graphics, False)
End Sub
Private Function GetVerticalAlignment() As StringAlignment
Return CType(Math.Log(Me.TextAlign, 2D) / 4, StringAlignment)
End Function
Private Function GetHorizontalAlignment() As StringAlignment
Return CType(Math.Log(Me.TextAlign, 2D) Mod 4, StringAlignment)
End Function
End Class
I have a PictureBox inside a Panel, to get automatic scrollbars when the picture is big, a Label with the photo title.
If I place the Label over the PictureBox, the "transparent" backcolor shows correctly but the Label remains at the top of the PictureBox and gets out of the screen if I scroll up-down or side-side the Panel's scrollbar!
Instead, if I put the Label outside the Panel (over the Form), the Label remains static on top of the screen, as I want, but the transparent backcolor doesn't show correctly becomes opaque.
Then if I set the Label's Parent property to the PictureBox, the transparent backcolor works fine again, but the static position of the Label is not respected anymore and joins PictureBox again!
How can I get a static Label with transparent backcolor over a PictureBox when using the scrollbars of the Panel?
I've tested the Overlay Form. It seems to work pretty well in your context.
Source Code in PasteBin
Uploaded the modified Project in OneDrive
(I don't have FW 4.5.2, tested with FW 4.5.1 and FW 4.7.1)
An Overlay can be an interesting feature, but, as I already said, this can also be done with TextRender.DrawText() or Graphics.DrawString(), backed by the simple math needed to offset the painted text when the picture container is scrolled.
In your Project, I've eliminated Label1 and all references to it.
Then, I've set this class field:
Private OverlayShown As Boolean = False
In frmPho_Load()
Overlay.Size = New Size(200, 50)
Overlay.OverlayPosition = Overlay.Alignment.Center
Overlay.Reposition(Me.Location, Me.Size)
OverlayShown = True
Overlay.Visible = False
Overlay.Show(Me)
In frmPho_Deactivate():
If OverlayShown = False Then
antip.Width = Me.Width
antip.Height = Me.Height
antip.Visible = True
End If
OverlayShown = False
These are all the changes made to the hosting Form (Form4), the form that uses the Overlay.
Public Class frmPho
Private Overlay As New OverlayForm
Private Sub frmPho_Load(sender As Object, e As EventArgs) Handles Me.Load
Overlay.Size = New Size(200, 50)
Overlay.OverlayPosition = Overlay.Alignment.Center
Overlay.Reposition(Me.Location, Me.Size)
OverlayShown = True
Overlay.Visible = False
Overlay.Show(Me)
'(...)
Overlay.Text = IO.Path.GetFileNameWithoutExtension(_ImageFileNames(_CurrentImage))
End Sub
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.CheckState = False Then
Overlay.Visible = False
Else
OverlayShown = True
Overlay.Visible = True
End If
End Sub
Private Sub ShowPrevImage()
'(...)
OverlayShown = True
Overlay.Text = IO.Path.GetFileNameWithoutExtension(_ImageFileNames(_CurrentImage))
End Sub
Private Sub ShowNextImage()
'(...)
OverlayShown = True
Overlay.Text = IO.Path.GetFileNameWithoutExtension(_ImageFileNames(_CurrentImage))
End Sub
Private Sub frmPho_Deactivate(sender As Object, e As EventArgs) Handles Me.Deactivate
If OverlayShown = False Then
antip.Width = Me.Width
antip.Height = Me.Height
antip.Visible = True
End If
OverlayShown = False
End Sub
Private Sub frmPho_Move(sender As Object, e As EventArgs) Handles Me.Move
Overlay.Reposition(Me.Location, Me.Size)
End Sub
Private Sub frmPho_Resize(sender As Object, e As EventArgs) Handles Me.Resize
Overlay.Reposition(Me.Location, Me.Size)
End Sub
Private Sub frmPho_Shown(sender As Object, e As EventArgs) Handles Me.Shown
ShowOverlay(300)
End Sub
Private Async Sub ShowOverlay(Delay As Integer)
Await Task.Delay(Delay)
Overlay.Visible = True
Me.Focus()
End Sub
And this is the complete OverlayForm:
All Borders/Control Boxes to None (It's a borderless Form)
.StartPosition = Manual
.TransparncyKey = WhiteSmoke <= Depends on the font color (mod. when needed)
.BackColor = WhiteSmoke <= Depends on the font color (mod. when needed)
.ShowInTaskbar = False
Public Class OverlayForm
Private _Text As String
Private TextPosition As Point
Private _Brush As SolidBrush = New SolidBrush(Color.White)
Private _Flags As StringFormatFlags = StringFormatFlags.NoWrap
Public Enum Alignment
Left = 0
Right = 1
Center = 2
End Enum
Public Sub New()
InitializeComponent()
End Sub
Public Overrides Property Text() As String
Get
Return Me._Text
End Get
Set(ByVal value As String)
_Text = value
Me.Invalidate()
End Set
End Property
Public Property OverlayPosition As Alignment
Private Sub OverlayForm_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
e.Graphics.TextContrast = 12
Dim _Size As SizeF = e.Graphics.MeasureString(Me._Text, Me.Font,
New SizeF(Me.Width, Me.Height),
New StringFormat(Me._Flags))
e.Graphics.DrawString(Me._Text, Me.Font, Me._Brush, New RectangleF(TextAlign(_Size.Width), _Size))
End Sub
Private Sub OverlayForm_ForeColorChanged(sender As Object, e As EventArgs) Handles Me.ForeColorChanged
Me._Brush = New SolidBrush(Me.ForeColor)
Me.Invalidate()
End Sub
Public Sub Reposition(ParentPosition As Point, ParentSize As Size)
Select OverlayPosition
Case Alignment.Left
Me.Location = New Point(ParentPosition.X + 20, ParentPosition.Y + 40)
Case Alignment.Right
Me.Location = New Point(ParentSize.Width - Me.Width - 20, ParentPosition.Y + 40)
Case Alignment.Center
Me.Location = New Point(ParentPosition.X + 20 + (ParentSize.Width \ 2) - (Me.Width \ 2), ParentPosition.Y + 40)
End Select
End Sub
Private Function TextAlign(TextWidth As Single) As PointF
Select Case OverlayPosition
Case Alignment.Left
Return New PointF(1, 1)
Case Alignment.Right
Return New PointF((Me.Width - TextWidth) - 1, 1)
Case Alignment.Center
If TextWidth > Me.Width Then TextWidth = Me.Width - 2
Return New PointF(CSng((Me.Width - TextWidth) / 4) - 1, 1)
End Select
End Function
End Class