En uno de mis momentos libres pense en como podia mejorar el sistema de avisos por defecto que viene en Visual Studio, ya que me parecia poco ortodoxo el tener que pulsar sobre un boton para quitar el mensaje de aviso de la pantalla y ademas que conlleva que se pare la ejecucion del programa hasta que se cierra el aviso.
De esta manera pense como lo hacian en otros sistema y me fije en Android, el famoso Toast, que al cabo de unos segundos desaparecia sin intervencion del usuario y me propuse intentarlo hacer en .NET. Lo consegui de la siguiente manera.
Me cree un modulo llamado Notificacion con las siguientes caracteristicas:
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Module Notificacion
'Timers
Dim WithEvents tmrAnimacion As Timer
Dim WithEvents tmrRetraso As Timer
'Control where the message will be displayed.
Dim WithEvents displaycontrol As New ExtendedControl()
'Some property variables.
Dim bEsUnError As Boolean = False
Dim miColorBorde As Color = Color.Red
Dim alphaval As Single = 0
Dim incremento As Single = 0.1
Dim bVisible As Boolean = False
Dim TamañoTexto As SizeF
Dim sMensaje As String = ""
Dim clColor As Color = Color.Red
Dim clColorFuente As Color = Color.White
Dim prnt As Control
'Measure message
Dim miFont As New Drawing.Font("Microsoft Sans Serif",
9,
Drawing.FontStyle.Bold,
Drawing.GraphicsUnit.Point)
#Region "eventhandlers"
'Handles the paint event of the display control.
Private Sub Control_Paint(ByVal sender As Object, ByVal pe As PaintEventArgs) Handles displaycontrol.Paint
'This BITMAP object will hold the appearance of the notification dialog.
'Why paint in bitmap? because we will set its opacity and paint it on the control later with a specified alpha.
displaycontrol.Width = displaycontrol.Width
displaycontrol.Height = displaycontrol.Height
Dim img As New Bitmap(displaycontrol.Width, displaycontrol.Height)
Dim e As Graphics = Graphics.FromImage(img)
'Set smoothing.
e.SmoothingMode = SmoothingMode.AntiAlias
If bEsUnError Then
miColorBorde = Color.Red
Else
miColorBorde = Color.DodgerBlue
End If
If clColor <> Color.Red Then
miColorBorde = clColor
End If
'Prepare drawing tools.
Dim bru As Brush = New SolidBrush(Color.FromArgb(50, miColorBorde))
Dim pn As Pen = New Pen(bru, 6)
Dim gp As New GraphicsPath()
'Make connecting edges rounded.
pn.LineJoin = LineJoin.Round
'Draw borders
'Outmost, 50 alpha
gp.AddRectangle(New Rectangle(3, 3, displaycontrol.Width - 10, displaycontrol.Height - 10))
e.DrawPath(pn, gp)
'level 3, A bit solid
gp.Reset()
gp.AddRectangle(New Rectangle(5, 5, displaycontrol.Width - 14, displaycontrol.Height - 14))
e.DrawPath(pn, gp)
'level 2, a bit more solid
gp.Reset()
gp.AddRectangle(New Rectangle(7, 7, displaycontrol.Width - 18, displaycontrol.Height - 18))
e.DrawPath(pn, gp)
'level 1, more solidness
gp.Reset()
gp.AddRectangle(New Rectangle(9, 9, displaycontrol.Width - 22, displaycontrol.Height - 22))
e.DrawPath(pn, gp)
'Draw Content Rectangle.
gp.Reset()
'bru = New SolidBrush(Color.FromArgb(7, 7, 7))
If bEsUnError Then
bru = New SolidBrush(Color.Red)
Else
bru = New SolidBrush(Color.DodgerBlue)
End If
If clColor <> Color.Red Then
bru = New SolidBrush(clColor)
End If
pn = New Pen(bru, 5)
pn.LineJoin = LineJoin.Round
gp.AddRectangle(New Rectangle(8, 8, displaycontrol.Width - 20, displaycontrol.Height - 20))
e.DrawPath(pn, gp)
e.FillRectangle(bru, New Rectangle(9, 9, displaycontrol.Width - 21, displaycontrol.Height - 21))
'Set COLORMATRIX (RGBAw).
'Matrix [3,3] will be the Alpha. Alpha is in float, 0(transparent) - 1(opaque).
Dim cma As New ColorMatrix()
cma.Matrix33 = alphaval
Dim imga As New ImageAttributes()
imga.SetColorMatrix(cma)
'Draw the notification message..
Dim sf As New StringFormat()
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
' e.DrawString(sMensaje, prnt.Font, New SolidBrush(Color.FromArgb(247, 247, 247)), New Rectangle(9, 9, displaycontrol.Width - 21, displaycontrol.Height - 21), sf)
e.DrawString(sMensaje, miFont, New SolidBrush(clColorFuente), New Rectangle(9, 9, displaycontrol.Width - 21, displaycontrol.Height - 21), sf)
'Now, draw the content on the control.
pe.Graphics.DrawImage(img, New Rectangle(0, 0, displaycontrol.Width, displaycontrol.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imga)
'Free the memory.
cma = Nothing
sf.Dispose()
imga.Dispose()
e.Dispose()
img.Dispose()
bru.Dispose()
pn.Dispose()
gp.Dispose()
End Sub
'Handles the window animation.
Private Sub tmr_tick(ByVal sender As Object, ByVal e As EventArgs) Handles tmrAnimacion.Tick
If (incremento > 0) Then
If (alphaval < 1) Then
If (alphaval + incremento <= 1) Then
alphaval += incremento
displaycontrol.Refresh()
Else
alphaval = 1
displaycontrol.Refresh()
tmrAnimacion.Enabled = False
tmrRetraso.Enabled = True
End If
End If
Else
If (alphaval > 0) Then
If (alphaval + incremento >= 0) Then
alphaval += incremento
displaycontrol.Refresh()
Else
alphaval = 0
tmrAnimacion.Enabled = False
tmrAnimacion.Dispose()
tmrRetraso.Dispose()
displaycontrol.Dispose()
incremento = 0.1
bVisible = False
End If
End If
End If
End Sub
'handles the delay.
Private Sub tmrRetraso_tick(ByVal sender As Object, ByVal e As EventArgs) Handles tmrRetraso.Tick
incremento = -0.1
tmrAnimacion.Enabled = True
tmrRetraso.Enabled = False
End Sub
#End Region
#Region "Function"
'Public Sub Show(ByRef Parent As Control, ByVal Message As String, ByVal glw As Color, ByVal delay As Integer)
'''
''' Shows the message to the user.
'''
''' The message to show. ''' The time before the message to disappear, in Milliseconds. '''
Public Sub Show(ByRef Parent As Control,
ByVal EsUnError As Boolean,
ByVal Mensaje As String,
ByVal Retraso As Integer,
Optional ByVal Largo As Integer = 0,
Optional ByVal Alto As Integer = 0,
Optional ByVal TamanoFuente As Integer = 0,
Optional ByVal ColorOpcional As Color = Nothing,
Optional ByVal ColorFuente As Color = Nothing)
If Not (bVisible) Then
bVisible = True
prnt = Parent
sMensaje = Mensaje
bEsUnError = EsUnError
'Set up notification window.
displaycontrol = New ExtendedControl()
displaycontrol.IsTransparent = True
If ColorFuente <> Nothing Then
clColorFuente = ColorFuente
End If
If ColorOpcional <> Nothing Then
clColor = ColorOpcional
End If
If TamanoFuente <> 0 Then
miFont = New Drawing.Font("Microsoft Sans Serif",
TamanoFuente,
Drawing.FontStyle.Bold,
Drawing.GraphicsUnit.Point)
End If
' TamañoTexto = displaycontrol.CreateGraphics().MeasureString(Mensaje, Parent.Font)
TamañoTexto = displaycontrol.CreateGraphics().MeasureString(sMensaje, miFont)
displaycontrol.Height = 25 + TamañoTexto.Height + Alto
displaycontrol.Width = 35 + TamañoTexto.Width + Largo
If (TamañoTexto.Width > Parent.Width - 100) Then
displaycontrol.Width = Parent.Width - 100
Dim hf As Integer = CInt(TamañoTexto.Width) / (Parent.Width - 100)
displaycontrol.Height += (TamañoTexto.Height * hf)
End If
'Position control in parent
displaycontrol.Left = (Parent.Width - displaycontrol.Width) / 2
displaycontrol.Top = (Parent.Height - displaycontrol.Height) / 2
Parent.Controls.Add(displaycontrol)
displaycontrol.BringToFront()
' displaycontrol.Height
' GlowColor = glw
'Set up animation
tmrAnimacion = New Timer()
tmrAnimacion.Interval = 15
tmrAnimacion.Enabled = True
tmrRetraso = New Timer()
tmrRetraso.Interval = Retraso
Else
tmrRetraso.Stop()
tmrRetraso.Start()
End If
End Sub
#End Region
End Module
Una vez creado el modulo me cree una funcion que creara una instancia del modulo con las caracteristicas que yo requeria (retraso, alto, largo, tamaño fuente, etc) y lo ejecutara.
Public Shared Sub MostrarNotificacion(ByVal Formulario As Form,
ByVal EsUnError As Boolean,
ByVal Mensaje As String,
Optional Retraso As Integer = 0,
Optional ByVal Alto As Integer = 0,
Optional ByVal Largo As Integer = 0,
Optional TamanoFuente As Short = 0,
Optional Color As Color = Nothing,
Optional ColorFuente As Color = Nothing)
Try
Dim iRetraso As Integer = 0
If EsUnError Then
iRetraso = 5000 + Retraso
Else
iRetraso = 3000 + Retraso
End If
Notificacion.Show(Formulario, EsUnError, UCase(Trim(Mensaje)), iRetraso, Largo, Alto, TamanoFuente, Color, ColorFuente)
Catch ex As Exception
MessageBox.Show("ERROR " & ex.Message & " ... UtilForm.MostrarNotificacion", "Administrador",
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Tan solo tendreis que llamar a la funcion descrita y el funcionamiento seria el mismo que en Android.
Espero que os sirva de ayuda.
Espero vuestros comentarios. Gracias.
0 comentarios:
Publicar un comentario