lunes, 30 de septiembre de 2013

Liberar espacio en disco con SQL Server

Algunas veces las bases de datos se hacen demasiado grandes y se "comen" todo el disco duro disponible, pero es fácil liberar espacio sin perder información de la Base de Datos.

Las bases de datos de SQL Server disponen de dos tipos de archivos: el de datos .mdf y el de transacciones .ldf

Este último contiene un histórico de todas las transacciones que se han hecho en la base de datos, por tanto puede hacerse muy grande y ocupar innecesariente casi todo nuestro disco duro. 

Liberar espacio en disco con SQL server

miércoles, 25 de septiembre de 2013

The Unified Modeling Language User Guide (UML 2.0)

Grady Booch
James Rumbaugh
Ivar Jacobson

Publisher: Addison Wesley
ISBN: 0-201-57168-4, 512 pages


Desde hace varios años, el Lenguaje de Modelado Unificado (UML) ha sido un estándar para visualizar, especificar, construir y documentar programas de software. La reciente estandarización de UML 2.0 ha ampliado el alcance y la viabilidad de este método. Su expresividad permite a los usuarios modelar todo el proceso de creación de software, desde los primeros bocetos hasta los últimos detalles de programación. Lo que permite modelar desde los programas más sencillos hasta complejos sistemas de información basados en web o complejas aplicaciones de  tiempo real.

The Unified Modeling Language User Guide



En esta revisión tan esperada de la guía más vendida y definitiva para el uso del UML, está escrita por los propios creadores de este método o lenguaje y proporciona un tutorial para los aspectos básicos en un formato de dos colores diseñado para facilitar el aprendizaje.

Comienza con una vista general de UML y va introduciendo conceptos nuevos de forma gradual en cada capítulo. Contiene múltiples casos complejos de cada tipo en una gran variedad de dominios, los estudia en profundidad y con contenido actualizado.

Hay que destacar la inclusión de un nuevo capítulo para  componentes y su estructura interna, incluyendo nuevas capacidades para la creación de diseños encapsulados Nuevos detalles y cobertura actualizada sobre interface, colaboraciones y perfiles UML, nuevos diagramas de actividad, y muchos otros cambios introducidos por la especificación UML 2.0

The Unified Modeling Language User Guide (UML 2.0)

Con este libro el lector adquiere un conocimiento completo de la técnica UML además:
Entenderá lo que es UML y lo que no es, y por qué es relevante para el desarrollo de los sistemas de uso intensivo de software.
Dominará el vocabulario, las reglas y los modos de UML
Aprenderá a aplicar UML a una serie de problemas  comunes.


Una breve historia del UML


Los lenguajes de modelado orientado a objetos aparecieron a comienzos de la década de 1980 como metodologías enfrentadas a un nuevo género de lenguajes de programación: Los lenguajes Orientados a Objetos con aplicaciones cada vez más complejas, el número de métodos orientados a objetos aumentó de menos de 10 a más de 50 entre 1989 y 1994. Por lo que hubo que buscar una metodología común que satisfaciera todas las necesidades que solventaba cada método distinto de los aparecidos.

Cada método de los citados tenía sus puntos fuertes y débiles, por ejemplo el método propuesto por  Booch es útil durante las fases de diseño y construcción de los proyectos, Oose proporcionó un excelente método para los casos de uso como una forma de expresar los requisitos de captura , análisis , y diseño de alto nivel. Pero había muchas similitudes entre muchos de estos métodos gráficos. A mediados de la década de 1990, Grady Booch (Rational Software Corporation) , Ivar Jacobson ( Objectory ) y James Rumbaugh (General Electric) comenzaron a adoptar en sus métodos ideas de otros métodos, por lo que se estos métodos fueron reconocidos como los principales métodos orientados a objetos en el mundo. Esto motivó a los autores a crear un lenguaje de modelado unificado unificando de estos métodos que ya habían evolucionado y los autores fusionaron.

La elaboración de un lenguaje para su uso en el análisis y diseño orientado a objetos no es diferente a diseñar un lenguaje de programación.
Se trató de limitar el problema, por ejemplo pensando si el nuevo lenguaje debía abarcar la especificación de requisitos  o si permitiría la programación visual.  También hubo que encontrar un equilibrio entre expresividad y sencillez.
Se trató de no cambiar excesivamente los métodos existentes para no confundir a los usuarios existentes; La definición UML se esfuerza por sacar lo mejor de las ventajas de cada una de los sistemas que toma.
En junio de 1996 se publicaron los documentos de UML 0.9. Muchas organizaciones vieron en este método algo estratégico para su negocio y se unieron al proyecto con el fin de mejorarlo lo que desembocó en UML 1.0 bien definido , expresivo , potente y aplicable a una amplia gama de dominios de problemas .
UML 1.0 se presentó para la normalización de la Object Management Group ( OMG ) en enero 1997, para formalizar la Especificación UML y para integrar con otros esfuerzos de estandarización. En noviembre de 1997 se publicó una versión revisada del UML (versión 1.1 ) y una versión UML 1.2 en Junio de 1998 y UML 1.3 en otoño de ese mismo año. A estas le ha seguido la revisión mayor UML 2.0 que fue adoptada por el OMG en 2005.

diagrama de clases UML

Este es el índice de capítulos del Libro


La estructura estándar de cada capítulo es esta:
Getting Started
Terms and Concepts
Common Modeling Techniques
Hints and Tips

Unified Modeling Language User Guide, The

Preface
Goals
Audience
How to Use This Book
Organization and Special Features
A Brief History of the UML
Acknowledgments
For More Information
I: Getting Started
I: Getting Started

1. Why We Model
The Importance of Modeling
Principles of Modeling
Object-Oriented Modeling

2. Introducing the UML
An Overview of the UML
A Conceptual Model of the UML
Architecture
Software Development Life Cycle

3. Hello, World!
Key Abstractions
Mechanisms
Components
II: Basic Structural Modeling

4. Classes
5. Relationships
6. Common Mechanisms
7. Diagrams

8. Class Diagrams
III: Advanced Structural Modeling
III: Advanced Structural Modeling

9. Advanced Classes
10. Advanced Relationships
11. Interfaces, Types, and Roles
12. Packages
13. Instances

14. Object Diagrams
IV: Basic Behavioral Modeling
IV: Basic Behavioral Modeling

15. Interactions
16. Use Cases
17. Use Case Diagrams
18. Interaction Diagrams

19. Activity Diagrams
V: Advanced Behavioral Modeling
V: Advanced Behavioral Modeling

20. Events and Signals
21. State Machines
22. Processes and Threads
23. Time and Space

24. Statechart Diagrams
VI: Architectural Modeling
VI: Architectural Modeling

25. Components
26. Deployment
27. Collaborations
28. Patterns and Frameworks
29. Component Diagrams
30. Deployment Diagrams

31. Systems and Models
VII: Wrapping Up
VII: Wrapping Up

32. Applying the UML
Transitioning to the UML

Where to Go Next

A. UML Notation
Things
Relationships
Extensibility
Diagrams

B. UML Standard Elements
Stereotypes
Tagged Values
Constraints

C. Rational Unified Process
Characteristics of the Process
Phases and Iterations

Glossary

Referencias:






lunes, 23 de septiembre de 2013

Cómo responder a cambios con eventos, delegados

Este artículo describe cómo generar por código tus propios eventos y también cómo 
programar la respuesta a estos.

Delegados


Un delegado es un objeto al que otros objetos ceden (delegan) la ejecución de su código. También se conocen como punteros a función con seguridad de tipos.

Al instanciar un delegado, se asocia con un método de instancia o compartido de un objeto, y posteriormente, durante la ejecución, será el delegado el que se encargue de ejecutar dicho método y no el propio objeto. También se pueden asociar los delegados con procedimientos Sub o Function de módulos.

delegado sin parámetros
Public Delegate Sub EventoMoverPiezaHandler()

‘delegado con parámetros
Public Delegate Sub EventoMoverPiezaHandler(ByVal sender As Object, ByVal e As MuevePiezaArgs)

‘delegado de tipo función
Public Delegate Function EventoMoverPiezaHandler(ByVal sender As Object, ByVal e As MuevePiezaArgs) As string

Creación de Delegados.

Seguidamente, y ya en un procedimiento, declaramos una variable correspondiente al tipo del delegado. A continuación, conectamos el delegado con el procedimiento que posteriormente deberá ejecutar, empleando la palabra clave AddressOf, seguida del nombre del procedimiento.
AddressOf devuelve un puntero o dirección de entrada al procedimiento que será el que utilice el delegado para saber la ubicación del procedimiento que debe ejecutar. Por último, para ejecutar el procedimiento al que apunta el delegado, llamaremos a su método Invoke(). A continuación se muestran dos técnicas para crear un delegado; la segunda es más simple pero en ambas el resultado es el mismo.

Public Delegate Sub EventoMoverPiezaHandler()
    'Modo 1
    Sub Main1()
        'Declarar un delegado
        Dim loDelegTexto As EventoMoverPiezaHandler
       'Obtener la dirección de procedimiento a ejecutar y asignarla   al delegado
        loDelegTexto = AddressOf MostrarTexto
        'ejecutar procedimiento a través del delegado
        loDelegTexto.Invoke()
    End Sub

    'Modo 2
    Sub Main()
 ' Declarar un delegado y asociar con una dirección o puntero a    un procedimiento
Dim loDelegTexto As New EventoMoverPiezaHandler(AddressOf MostrarTexto)
        loDelegTexto.Invoke()

    End Sub

    'Este sera el procedimiento invocado (ejecutado) por el delegado
    Public Sub MostrarTexto()
        MsgBox("Prueba de Delegados")
    End Sub

Una de las ventajas de este tipo de entidades de la plataforma, consiste en que un mismo delegado puede llamara métodos diferentes de objetos distintos. En este caso un delegado invoca a dos procedimientos diferentes.

Public Delegate Sub EventoMoverPiezaHandler()

    Sub Main1()
        'Declarar un delegado
        Dim loDelegMensa As EventoMoverPiezaHandler

        loDelegMensa = AddressOf MostrarTexto
        loDelegMensa.Invoke()

        loDelegMensa = AddressOf VisualizarFecha
        loDelegMensa.Invoke()

    End Sub

    'Procedimientos ejecutados por los delegados
    Public Sub MostrarTexto()
        MsgBox("Prueba de Delegados")
    End Sub

    Public Sub VisualizarFecha()
        Dim ldtFecha As Date
        ldtFecha = Date.Today
        MsgBox("Fecha Actual", , ldtFecha)
    End Sub

La interfaz de usuario de Microsoft Windows está orientada a eventos. El flujo de control del programa se basa principalmente en los eventos del control de Windows Forms. En este artículo, vamos a crear un control que aparece en la caja de herramientas. Se puede arrastrar este control en un formulario tal y como cualquiera de los controles integrados en Windows. El control tendrá eventos que se pueden optar por responder o ignorar en su código. Vamos a usar las excepciones para indicar que algo ha ido mal durante la ejecución. Las excepciones no pueden ser ignoradas. Usando el manejador de excepciones, el código puede tratar de reparar el problema o puede salir del programa.

La tarea en este artículo es crear una representación visual de un tablero de ajedrez, en el que podemos arrastrar y soltar las diferentes piezas sobre dicho tablero.

Un somero análisis textual del problema conduce al diseño de clases siguiente. En este caso, el objeto de la pantalla está representado por la clase de Windows Forms, que contiene un tablero y las diferentes piezas. Las piezas se mueven encima del tablero que es un fondo estático pero cada casilla tiene unas coordenadas fijas “Posición”. Se muestra en el siguiente diagrama de clases UML.


Cómo responder a cambios con eventos, delegados

Se introduce un nuevo elemento de UML, el rombo sólido. El rombo sólido indica una relación llamada "Composición" en la terminología orientada a objetos. La composición es una relación en la que algunos los objetos son "partes" de otro objeto. Lleva el sentido de que el objeto no puede existir sin los otros. Todos los objetos son creados y destruidos como una unidad.
Este análisis refleja sólo lo que está estático en el problema, tales como la ubicación de las piezas  en el tablero. No se describen los movimientos y las capturas de piezas.
¿Cómo saber si se ha realizado un movimiento?  Para saber lo que sucede en un programa de este tipo  se necesitan eventos  que son los acontecimientos, las señales que envía un objeto a otro, de que algo ha sucedido.

§ MuevePieza para la clase de CTablero, este evento, generado por la pieza,
será recibido por el formulario para indicar la nueva posición de la pieza en el tablero.

§ CapturadePieza para la clase CPieza. Este evento se generará cuando una pieza captura a otra. La ubicación de la pieza depende de su posición y del movimiento que realiza, si el nuevo movimiento coincide con la posición de otra pieza, se produce una captura y se lanza un evento CapturadePieza que pone la propiedad EnJuego de la pieza capturada en False.

El uso de los eventos
MuevePieza y CapturaPieza en el código del formulario puede coordinar el comportamiento del tablero y las piezas. En UML, los eventos se modelan como señales, que son similares a las clases. En la ilustración siguiente, una flecha de puntos marcados <<envío>> indica que en una clase particular, se genera un evento particular.

Cómo responder a cambios con eventos, delegados

El UML también proporciona una sintaxis para indicar que las clases de recibir los eventos. La clase Form recibe tanto el evento MuevePieza como el CapturaPieza.

La última decisión de diseño es cómo implementar la interfaz de usuario, teniendo en cuenta el modelo de objetos. Sabemos que tiene que haber un tablero y unas piezas que se mueven sobre ese tablero como elementos visuales del formulario. Las propiedades de estos elementos visuales están íntimamente ligadas a las clases. De hecho, se pueden implementar las clases como clases derivadas de la genérica de control de Windows, la clase
UserControl, lo que significa que la presentación visual y el comportamiento de un objeto son todos los contenidos en una clase. Además, el control se puede agregar a la caja de herramientas, y luego arrastrado a la forma en el diseñador de formularios. Aquí está el diseño completo UML:

Cómo responder a cambios con eventos, delegados

Implementando la clase CTablero


Implementaremos la clase CTablero. Esta clase se deriva de la Clase UserControl de este modo el tablero pasa a ser como un control más de la caja de herramientas, y se dibuja el tablero a sí mismo, también dibujará las piezas encima del tablero.

Public Class CTablero
    Inherits UserControl
End Class

El nuevo control de Usuario está vacío, vamos a definir la forma y el color del nuevo control reemplazando el método OnPaint.

No es necesario añadir código para las propiedades del tablero pues ya están creadas en la clase base UserControl.


Pintando el Tablero.

Se dibuja el contorno del tablero como una serie cuadrados iguales alternando el color de cada tesela del tablero.

Añadir constante a la clase CTablero para modificar el tamaño de las casillas.

Private Const LongitudCasilla As Integer = 50 'debe ser divisible entre 5

Este código introduce la palabra clave Const. El modificador constante indica que el valor de la variable no puede ser modificado. Los valores constantes  pueden ser de cualquier tipo, pero el compilador debe ser capaz de evaluar la expresión a la derecha del signo igual. Debido a que el compilador no asigna memoria para instancias de la clase, la expresión no puede contener una declaración new. El resultado es que los valores de referencia constante serán  nothing o null, o una cadena. En este caso se utiliza el campo de la constante para que pueda cambiar el tamaño y proporciones de cada casilla al cambiar este valor. Todos los dibujos utilizan este campo, en lugar de literales enteros, como por ejemplo "50". El uso del modificador const permitirá que el compilador nos ayude, evitando accidentalmente cambiar estos valores en el código.

 En el menú Ver, hacer clic en Diseñador para ver el control en el diseño del formulario. Hacer doble clic en el control para crear el método Load en el editor de código. Agregar  este código para fijar la propiedad Height de cada casilla a 50 píxeles.

Agregar un objeto creado por el usuario

Dentro de la clase CTablero ponemos un control para cada casilla posteriormente iremos alternando los colores.

Private Sub CTablero_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Me.BackColor = Color.Brown
        Me.Top = 50
        Me.Left = 50
    End Sub

Ahora pintamos el tablero en tiempo de ejecucución haciendo que cada casilla sea un control diferente.

En la clase CTablero definimos el método Dibuja_Tablero para ubicar cada control CTablero en un lugar diferente y con el color correspondiente

Public Sub Dibuja_Tablero()
Dim casilla As New CTablero
      Dim ArrCasillas As New ArrayList
      Dim i As Integer
      Dim par As Boolean
      
'Introduce en un ArrayList los 64 controles de casilla que                  conforman el tablero completo

      ArrCasillas.Add(Form1.CTableroA8)
      ArrCasillas.Add(Form1.CTableroB8)
      ArrCasillas.Add(Form1.CTableroC8)
      ArrCasillas.Add(Form1.CTableroD8)
      ArrCasillas.Add(Form1.CTableroE8)
      ArrCasillas.Add(Form1.CTableroF8)
      ArrCasillas.Add(Form1.CTableroG8)
      ArrCasillas.Add(Form1.CTableroH8)

      ArrCasillas.Add(Form1.CTableroA7)
      ...
      ... (introduce 64 controles casilla)
...
      ArrCasillas.Add(Form1.CTableroF2)
      ArrCasillas.Add(Form1.CTableroG2)
      ArrCasillas.Add(Form1.CTableroH2)

      ArrCasillas.Add(Form1.CTableroA1)
      ArrCasillas.Add(Form1.CTableroB1)
      ArrCasillas.Add(Form1.CTableroC1)
      ArrCasillas.Add(Form1.CTableroD1)
      ArrCasillas.Add(Form1.CTableroE1)
      ArrCasillas.Add(Form1.CTableroF1)
      ArrCasillas.Add(Form1.CTableroG1)
      ArrCasillas.Add(Form1.CTableroH1)

      i = 0
      For Each casilla In ArrCasillas
            'Asigna el color alternativamente (por filas)
If i <> 8 And i <> 16 And i <> 24 And i <> 32 And i <> 40 And i <> 48 And i <> 56 And i <> 64 Then
                  If par = True Then
                        par = False
                  Else
                        par = True
                  End If
            End If
'Llama lal método Asigna posición que ubica cada casilla y        le da el color
            Asigna_Posicion(ArrCasillas(i), par)
            i = i + 1
        Next

End Sub

Private Sub Asigna_Posicion(ByVal Casilla As CTablero, ByVal Par As Boolean)

Nombre = Mid(Casilla.Name, 9, 2)

'(para Longitud casilla = 50 Si viene de la fila 1 top = 400, fila 2 top = 350 ...Fila 8 top = 50
Casilla.Top = (LongitudCasilla * 9) - (Mid(Nombre, 2, 1) * LongitudCasilla)

        'Coloca las casillas por Columnas
        Select Case Mid(Nombre, 1, 1)
            Case "A"
                Casilla.Left = LongitudCasilla
            Case "B"
                Casilla.Left = LongitudCasilla * 2
            Case "C"
                Casilla.Left = LongitudCasilla * 3
            Case "D"
                Casilla.Left = LongitudCasilla * 4
            Case "E"
                Casilla.Left = LongitudCasilla * 5
            Case "F"
                Casilla.Left = LongitudCasilla * 6
            Case "G"
                Casilla.Left = LongitudCasilla * 7
            Case "H"
                Casilla.Left = LongitudCasilla * 8
        End Select
        'pone el color alternativamente
        If Par = True Then
            Casilla.BackColor = Color.LightSalmon
        Else
            Casilla.BackColor = Color.Brown
        End If

    End Sub

El tablero queda pintado del siguiente modo:

diseño con .net de un tablero de ajedrez


Si reescribimos el método OnSizeChanged podemos establecer la propiedad Height y la Width de la casilla a n pixeles y para modificar el ancho del control a nxn el valor de una casilla. Se puede escribir el código que sigue o  usar  la funcionalidad que proporciona Visual Studio.

El código agregado a este métodose muestra aquí:

Protected Overrides Sub OnSizeChanged(ByVal e As System.EventArgs)
Me.Height = LongitudCasilla
      Me.Width = LongitudCasilla
End Sub

Si ahora cambiamos LongitudCasilla por 30

Private Const LongitudCasilla As Integer = 30 'debe ser divisible por 5

Veremos este tablero con las casillas más pequeñas, de 30 x 30.

diseño con .net de un tablero de ajedrez


Implementar Eventos en una clase

En los procedimientos siguientes se describe cómo implementar un evento en una clase. El primer procedimiento implementa un evento que no tiene datos asociados, sino que utiliza las clases System.EventArgs y System.EventHandler de los datos del evento y un controlador de delegado. El segundo procedimiento implementa un evento personalizado con los datos, que define las clases personalizadas de los datos del evento y el controlador de eventos delegado.

Implementar un evento sin datos asociados

1. Definir un evento public en la clase, poner en el tipo miembro de tipo de Evento el delegado System.EventHandler .
Public Class MuevePieza
    ' ...

            Public Event MoverPieza As EventoMoverPiezaHandler
End Class
2. Proporcionar un método protegido en la clase que provoca el evento. Nombrar el método On[NombreEvento]. Provocar el evento dentro del método.
Public Class MuevePieza
   
            Public Event MoverPieza As EventoMoverPiezaaHandler

' El método protegido OnMoverPieza levanta el evento invocando el delegado. El enviador es siempre la instacia actual de la clase
Protected Overridable Sub OnMoverPieza(ByVal e As MuevePiezaArgs)
                  MsgBox("Levanta el evento MoverPieza")
                  RaiseEvent MoverPieza(Me, e)
      End Sub
End Class

3. Determinar el momento de generar el evento en su clase. Llamar a On[NombreEvento para provocar el evento.

Public Class MuevePieza
      Private nclickpieza As Integer = 0
      Private PosicionAnterior As String = "PD"
   
      Public Event MoverPieza As EventoMoverPiezaaHandler

' El método protegido OnMoverPieza levanta el evento invocando el delegado. El enviador es siempre la instacia actual de la clase
Protected Overridable Sub OnMoverPieza(ByVal e As MuevePiezaArgs)
        MsgBox("Levanta el evento MoverPieza")
        RaiseEvent MoverPieza(Me, e)
      End Sub

      Public Sub Comienzo()
        Dim e As New MuevePiezaArgs(nclickpieza, PosicionAnterior)
            OnMoverPieza(e)
      End Sub
 End Class

Implementar Eventos con datos específicos

1. Definir una clase que proporciona datos para el evento. Nombrar  la clase como [NombreEvento]Args, y derivarla de la clase  System.EventArgs, para  añadir cualquier miembro  específico.
'Esta clase define un constructor con los argumentos del evento, en este caso NclickPieza que contiene el Número de veces que
'se ha movido la pieza y PosicionAnterior que contiene en eun string la posicion anterior
Public Class MuevePiezaArgs
    Inherits EventArgs
    Private nclickpieza As Integer
    Private PosicionAnterior As String
    'Constructor.
Public Sub New(ByVal nclickpieza As Integer, ByVal PosicionAnterior As String)
        Me.nclickpieza = nclickpieza
        Me.PosicionAnterior = PosicionAnterior
    End Sub
End Class

2. Declarar un delegado para el evento. Nombrando el delegado como  [NombreEvento]Handler.

' Declaracion del delegado.
  Public Delegate Sub EventoMoverPiezaaHandler(ByVal sender As Object, ByVal e As MuevePiezaArgs)

3. Definir un evento miembro público llamado NombreEvento en su clase. Establecer el tipo de miembro de evento en el tipo de delegado del evento. (Como implementar eventos sin datos asociados)

Public Class MuevePieza
    ' ...

            Public Event MoverPieza As EventoMoverPiezaHandler
End Class

 4. Definir un método protegido en la clase que dispara el evento. El nombre del método On[NombreEvento. Dispara el evento dentro del método. Esto elimina la necesidad de manejar el NullReferenceException que se produce cuando se provoca un evento, pero no se han unido a él controladores de eventos. Esta comprobación es necesaria en este caso porque la clase simplemente produce el evento, pero no proporciona un controlador para ello.

Public Class MuevePieza
   
            Public Event MoverPieza As EventoMoverPiezaaHandler

' El método protegido OnMoverPieza levanta el evento invocando el delegado. El enviador es siempre la instacia actual de la clase
Protected Overridable Sub OnMoverPieza(ByVal e As MuevePiezaArgs)
                  MsgBox("Levanta el evento MoverPieza")
                  RaiseEvent MoverPieza(Me, e)
      End Sub
End Class

5. Determinar el momento de levantar el evento en la clase. Llamar a On[NombreEvento] para disparar el evento y pasar en el caso específico de los datos mediante el uso de [NombreEvento]EventArgs.

Public Class MuevePieza
      Private nclickpieza As Integer = 0
      Private PosicionAnterior As String = "PD"
   
      Public Event MoverPieza As EventoMoverPiezaaHandler

' El método protegido OnMoverPieza levanta el evento invocando el delegado. El enviador es siempre la instacia actual de la clase
Protected Overridable Sub OnMoverPieza(ByVal e As MuevePiezaArgs)
        MsgBox("Levanta el evento MoverPieza")
        RaiseEvent MoverPieza(Me, e)
      End Sub

      Public Sub Comienzo()
        Dim e As New MuevePiezaArgs(nclickpieza, PosicionAnterior)
            OnMoverPieza(e)
      End Sub
 End Class


Cómo dibujar una pieza sobre el tablero


1. En el Explorador de soluciones, hacer doble clic en Form1 para abrirlo en la forma diseñador.


2. Desde el área de Windows Forms del Cuadro de herramientas, arrastre un PictureBox

control en el formulario.

3. Establecer la propiedad Name del control PictureBox a FiguraPeonBlanco, y la Propiedad SizeMode a AutoSize.

4. Hacer  click en el botón (...) junto a la propiedad Image para seleccionar una imagen para

el peón blanco.
5. Definimos el evento a disparar  la acción desde el Form1.



El siguiente programa de ejemplo  coloca un picturebox de un peón sobre una casilla determinada al hacer click sobre él. En un programa real esto debería colocarse en el mouse-up de un drag-and-drop pero para mostrar cómo se dispara un evento basta con este pequeño ejemplo.

Llamada desde el evento Click de un PictureBox1 del Form1. (Este es el único código que va en el Form1 del programa de Ajedrez)

Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click

        ' Instancia el evento que recibe.
        Dim Coloca As New ColocaPieza()
        ' Instancia el evento fuente.
        Dim Pieza As New MuevePieza()

'Dirige el método RangoMoverPiezaa hacia el evento de    MoverPiezaa.
        AddHandler Pieza.MoverPieza, AddressOf Coloca.RangoMoverPieza
        Pieza.Comienzo()
    End Sub

Finalmente se implementa la clase ColocaPieza que es la que mueve la pieza realmente.
(Todas las clases descritas van en el módulo de la clase CPieza de nuestro programa de ajedrez)
' La clase ColocaPieza tiene el método RangoMoverPieza que maneja el evento mover pieza
Public Class ColocaPieza
    Public Sub RangoMoverPiezaa(ByVal sender As Object, ByVal e As MuevePiezaArgs)
        Form1.PictureBox1.Left = 200
        Form1.PictureBox1.Top = 200
    End Sub
End Class

Configurar Métodos de Eventos sin utilizar el Diseñador


En el ejemplo anterior se ha creado control de usuario con los eventos. Cuando se arrastra una pieza en el formulario, los eventos están disponibles en la lista de métodos.
Pero no es necesario utilizar el diseñador para conectar un evento caso a las instancias de los métodos de la clase, se puede hacer simplemente mediante el uso de declaraciones de código. El establecimiento de métodos de eventos en el código permite:

§  Crear instancias de control en tiempo de ejecución y responder a sus eventos.
§   Cambiar el controlador de eventos para un evento determinado en tiempo de ejecución.

Se puede elegir entre dos formas de configurar los métodos de evento. Una vía es el uso de la palabra clave Handles. Y en la otra forma se utiliza la instrucción AddHandler. Para utilizar la palabra clave Handles, se debe declarar la instancia con la palabra clave WithEvents como un campo de una clase. El problema es que no se puede utilizar la palabra clave New en la declaración, por lo que la clase debe crear una instancia en otras partes de la clase, lo más probable en el constructor.  Una vez se declara la clase utilizando la palabra clave WithEvents, los eventos están disponibles para la instancia en la lista de métodos del editor de código, que es el método utilizado por el Diseñador de formularios.

Ejemplo completo

Esto es un ejemplo completo de manejo de Eventos, consiste en la creación de una clase que controla un Timer que descuenta de 10 a 0 y va mostrando en una caja de texto el valor, cuando termina muestra Done en la caja de texto.

En el formulario de la aplicación se pone un botón llamado Boton_Prueba y una caja de texto llamada Text_Evento. En el Form1_Load de la aplicación se ponen las siguientes líneas:

'Lineas de Evento
Boton_Prueba.Text = "Start"  
mText = New TimerState

dentro de la clase formulario se define el siguiente código:

Se define la variable mText como Timer

Private WithEvents mText As TimerState

'Al hacer click en el botón se pone el contador a 10.  Se dispara al pulsar el botón Boton_Prueba
Private Sub Boton_Prueba_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Boton_Prueba.Click
mText.StartCountdown(10.0, 0.1)
End Sub

'Este Procedimiento es el que se dispara al ejecutar el RaiseEvent UpdateTime en la clase TimerState
Private Sub mText_UpdateTime(ByVal Countdown As Double) _
Handles mText.UpdateTime
Text_Evento.Text = Format(Countdown, "##0.0")
        ' Use DoEvents to allow the display to refresh.
     My.Application.DoEvents()
End Sub

'Este evento se dispara cuando el evento termina RaiseEvent finished
Private Sub mText_ChangeText() Handles mText.Finished
Text_Evento.Text = "Done"
End Sub

Y la clase que maneja el evento se declara a parte

'Clase del evento

Class TimerState
    'Definición de eventos
    Public Event UpdateTime(ByVal Countdown As Double)
    Public Event Finished()
    'Procedimiento llamado desde el Click del Botón 
    Public Sub StartCountdown(ByVal Duration As Double, ByVal            Increment As Double)
      Dim Start As Double = DateAndTime.Timer
      Dim ElapsedTime As Double = 0
      Dim SoFar As Double = 0

      Do While ElapsedTime < Duration
            If ElapsedTime > SoFar + Increment Then
                  SoFar += Increment
'Esta línea   dispara mText_UpdateTime            RaiseEvent UpdateTime(Duration - SoFar)     
End If
            ElapsedTime = DateAndTime.Timer - Start
      Loop
      RaiseEvent Finished()
    End Sub
End Class

Configurar Métodos de Eventos sin utilizar el Diseñador

Programación Orientada a Objetos