PDF de programación - Parámetros personalizados en los eventos

<<>>

Parámetros personalizados en los eventosgráfica de visualizaciones

Actualizado el 10 de Octubre del 2020 (Publicado el 17 de Julio del 2017)
798 visualizaciones desde el 17 de Julio del 2017
227,2 KB
6 paginas
Guillermo “Guille” Som

dnm.inicio.fundamentos
dnm.incio.taller

Parámetros personalizados en los eventos

En este cuarto artículo dedicado a los delegados y eventos nos centraremos en cómo
comunicarnos entre la clase que define los eventos y la que los intercepta.Veremos esa
comunicación de dos formas diferentes,usando parámetros por referencia y de la for-
ma recomendada, que es definiendo nuestra propia clase para usar como parámetro
de los eventos.También abordaremos una característica exclusiva de C#,que es la posi-
bilidad de usar clases base como parámetros de los métodos que reciben los eventos.

<<

Comunicarse con la clase que produce el evento

Hasta ahora hemos estado usando los eventos de
la forma habitual: para comunicarle a la aplicación
receptora que algo ha ocurrido, y en esa comunica-
ción solo hemos usado una vía, de forma que la cla-
se que produce el evento “informe” de qué es lo que
está ocurriendo, información que enviamos con los
parámetros pasados al método receptor. Pero, ¿cómo
podemos hacer que la aplicación receptora (el clien-
te) pueda comunicarse con la clase que produce el
evento (el servidor), por ejemplo, para cancelar una
acción o para pasarle cierta información?

Usando parámetros por referencia en los eventos

En principio, esto es algo sencillo de realizar, ya
que lo único que tenemos que hacer es declarar por
referencia uno (o varios) de los parámetros. De esta
forma podemos asignar un valor a ese parámetro y
usarlo en la clase que produce el evento. Por ejem-
plo, si tenemos el evento usado en los ejemplos de
los artículos anteriores que avisa del cambio en el
valor de una propiedad, podemos agregar un tercer
parámetro para indicar si cancelamos dicha asigna-
ción. En el código del fuente 1 vemos cómo definir
el delegado, el evento y la propiedad, que tiene en
cuenta esta nueva posibilidad de cancelar la asigna-
ción, dato que sabremos si la aplicación cliente
devuelve un valor verdadero en la variable usada para
el tercer parámetro.

Como es de esperar, el método de la clase clien-
te que recibe la notificación de que el evento se ha
producido debe tener la misma “firma” que el dele-

Guillermo “Guille” Som
Es Microsoft MVP de Visual Basic
desde 1997.Es redactor de
dotNetManía,mentor de Solid
Quality Iberoamericana,tutor de
campusMVP,miembro de Ineta
Speakers Bureau Latin
America,y autor de
los libros “Manual Imprescindible
de Visual Basic .NET” y
“Visual Basic 2005”.
http://www.elguille.info

public delegate void NombreCambiadoEventHandler(

string nuevo, string anterior, ref bool cancelar);

public event NombreCambiadoEventHandler NombreCambiadoRef;

private string m_Nombre;
public string Nombre
{

get { return m_Nombre; }
set
{

// Lanzar el evento
// indicando el nuevo valor y el anterior,
// además de la variable para saber si cancela
if( NombreCambiadoRef != null )
{

bool cancelado = false;
NombreCambiadoRef(value, m_Nombre, ref cancelado);
if( cancelado )
{

// Lo que haya que hacer para avisar
// que se ha cancelado la asignación
return;

}

}
m_Nombre = value;

}

}

Fuente 1. Definición de un evento que permite cancelar la acción

gado, incluyendo el parámetro por referencia y, como
es natural, podemos ignorar dicho parámetro o asig-
narle un valor verdadero en el caso de que queramos
cancelar la asignación. En el código del fuente 2 can-
celamos esa asignación si el nuevo valor es una cade-
na vacía o la longitud de la misma es inferior a 3
caracteres.

a
í
n
a
M
t
e
N
t
o
d
<
<

35

<<

dnm.inicio.taller

a
í
n
a
M
t
e
N
t
o
d
<
<

36

static void cli_NombreCambiadoRef(

string nuevo, string anterior, ref bool cancelar)

{

// Cancelamos la acción si el nuevo valor no
// cumple las condiciones que estimemos oportunas
if( string.IsNullOrEmpty(nuevo) || nuevo.Length < 3 )
{

Console.WriteLine( “cancelando... debe tener más” +

“ de 2 caracteres...”);

cancelar = true;

}

}

Fuente 2. El método que recibe el evento puede
cancelar la asignación

Hay que aclarar que esa comprobación que hace-
mos en el lado del cliente en realidad la podíamos
hacer en la propiedad, pero de lo que aquí se trata es
de ver un ejemplo de cómo cancelar (o informar a la
clase que ésa es nuestra intención), no de la solución
mágica a todos nuestros problemas. Además, al hacer-
lo en el lado del cliente, esto nos da la posibilidad de
que cada aplicación que use esa clase decida la com-
probación que debe hacer. Por ejemplo, si la propie-
dad fuera una contraseña, el cliente podría validar si
cumple ciertos requisitos impuestos por la aplicación.

Usando clases como parámetro de los eventos

Si necesitamos pasar más datos (ya sean por valor
o por referencia), tendremos que indicar más pará-
metros en la definición del delegado asociado con el
evento, y aunque eso no es ningún problema, .NET
nos permite una forma más elegante de hacerlo: usan-
do un tipo personalizado como parámetro, es decir,
una clase. Es más, el propio .NET Framework tiene
una clase que podemos usar para estos menesteres:
EventArgs. De hecho, todos los eventos de los contro-
les del espacio de nombres Windows.Forms se basan (o
se derivan) de esa clase; por tanto, podemos hacer lo
mismo que hace el entorno en el que estamos progra-
mando, y crear nuestra propia clase basada en
EventArgs. De esa forma también nos resultará más
cómodo pasar (y recuperar) datos en ambos sentidos,
con lo que de camino nos ahorramos la definición de
parámetros por referencia, que entre otras cosas, no
son deseables, al menos a la hora de dar claridad a
nuestro código.

Crear clases para usar como parámetro
de un evento

Para mantener las cosas sencillas, vamos a crear
una clase que usaremos como parámetro de los even-
tos. Esta clase tendrá la misma funcionalidad que la
mostrada en el código del fuente 1; es decir, la clase
tendrá tres propiedades, dos de solo lectura y la ter-
cera de lectura/escritura, ya que será la usada para
saber si se quiere cancelar la acción de asignar un nue-

vo valor a la propiedad. Las otras dos, las que indican
los valores nuevo y anterior, serán de solo lectura, ya
que lo único que le interesa al método receptor del
evento es saber qué valores contienen, y como son
valores directamente relacionados con una propiedad
de una clase, no deberíamos manipularlos, ya que si
lo hacemos nos estaríamos saltando a la torera uno de
los pilares de la programación orientada a objetos: la
encapsulación. Pero... como somos los diseñadores de
la clase, podemos hacer lo que mejor nos parezca, aun-
que no voy a ser yo el que incite a esa decisión.

Las dos propiedades que vamos a exponer como
de solo lectura las vamos a definir con los dos bloques
de código que habitualmente tienen todas las propie-
dades, que como sabemos son el bloque get, que nos
permite obtener el valor de la propiedad, y el bloque
set, que es el usado cuando asignamos el valor. Para
dar esa funcionalidad de solo lectura a pesar de defi-
nir el bloque set, vamos a usar la nueva característi-
ca de .NET Framework 2.0 que nos permite cambiar
el ámbito (o visibilidad) de uno de los bloques de las
propiedades (ver el número 20 de dotNetManía). De
esta forma, la clase expondrá públicamente solo el blo-
que get, y el bloque set lo dejaremos como internal
(Friend en Visual Basic) para que solo podamos usar-
lo desde el propio ensamblado.

En el código del fuente 3 vemos la definición de
la clase DatosCambiadosEventArgs, que es la que usa-
remos como parámetro del delegado y el evento
definidos en la clase Cliente (ver el fuente 4). Ambas
clases están definidas en una biblioteca de clases,
que tendremos que añadir a las referencias del pro-

public class DatosCambiadosEventArgs : EventArgs
{

// Propiedad de solo lectura cuando se accede
// desde fuera del propio ensamblado
private string m_Nuevo;
public string Nuevo
{

get { return m_Nuevo; }
internal set { m_Nuevo = value; }

}

// Propiedad de solo lectura cuando se accede
// desde fuera del propio ensamblado
private string m_Anterior;
public string Anterior
{

get { return m_Anterior; }
internal set { m_Anterior = value; }

}

private bool m_Cancelar;
public bool Cancelar
{

get { return m_Cancelar; }
set { m_Cancelar = value; }

}

}

Fuente 3. La definición de la clase basada en EventArgs

<<

dnm.inicio.taller

public class Cliente
{

public delegate void DatosCambiadosEventHandler(

DatosCambiadosEventArgs e);

public event DatosCambiadosEventHandler NombreCambiado;

private string m_Nombre;
public string Nombre
{

get { return m_Nombre; }
set
{

// Lanzar el evento
// indicando el nuevo valor y el anterior
if( NombreCambiado != null )
{

// Declaramos un objeto del tipo de la clase
// usada para usar como parámetro del evento.
DatosCambiadosEventArgs e =

new DatosCambiadosEventArgs();

e.Cancelar = false;
// Desde el propio ensamblado podemos acceder
// al bloque set de las propiedadades Nuevo
// y Anterior
e.Nuevo = value;
e.Anterior = m_Nombre;
// Lanzamos el evento usando como argumento el
// objeto creado a partir de la clase.
NombreCambiado(e);
// Comprobar si se cancela la asignación
if( e.Cancelar )
{

// Lo que haya que hacer para avisar
// que se ha cancelado la asignación
return;

}

}
m_Nombre = value;

}

yecto en el que definimos la clase que interceptará
los eventos y añadir la importación correspondien-
te del espacio de nombres que las contiene. Una vez
hecho eso, la podremos usar tal como vemos en el
código fuente 5.

Definir la clase del evento en el mismo ensamblado
que el cliente

Si en lugar de crear un ensamblado para las clases
(la que produce el evento y la que define el paráme-
tro de dicho evento) decidimos que estén todas en el
mismo ensamblado (proyecto), el hecho de propor-
cionar ámbitos diferentes a los bloques set de las dos
propiedades que queremos que sean de solo lectura
no nos soluciona la papeleta, ya que al estar declara-
dos esos bloques con internal, serán accesibles desde
cualquier parte del mismo ensamblado, y por tanto
también desde el código de la aplica
  • Links de descarga
http://lwp-l.com/pdf5511

Comentarios de: Parámetros personalizados en los eventos (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad