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