Crear Notificacion mensaje en .NET parecido al de Android

0 comentarios
Resultado de imagen de .net

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

Related Posts Plugin for WordPress, Blogger...
Copyright 2011 INFORMATICUCHO.
Blogger Template by Noct.