Capítulo 14: Event Handlers - Reaccionar a eventos
Capítulo 14: Event Handlers - Reaccionar a eventos
Sección titulada «Capítulo 14: Event Handlers - Reaccionar a eventos»Parte II: Primeros pasos con EPLAN API - Sección 5: Atributos de scripting - Nivel: Principiante-Intermedio
Objetivos de aprendizaje
Sección titulada «Objetivos de aprendizaje»Al finalizar este capítulo serás capaz de:
- Entender qué es un event handler y cuándo usarlo
- Diferenciar entre [Start], [DeclareAction] y [DeclareEventHandler]
- Crear scripts que se ejecutan automáticamente al ocurrir eventos
- Conocer los eventos más comunes de EPLAN
- Implementar event handlers con y sin parámetros
Requisitos previos
Sección titulada «Requisitos previos»Antes de comenzar este capítulo debes:
- Haber completado los Capítulos 12 ([Start]) y 13 ([DeclareAction])
- Entender atributos de C#
- Conocer PathMap y CommandLineInterpreter
- Saber usar try-catch para manejo de errores
Introducción
Sección titulada «Introducción»Hasta ahora has aprendido dos formas de ejecutar código en EPLAN:
- [Start] - Se ejecuta manualmente al abrir el script
- [DeclareAction] - Se ejecuta al llamar la acción por nombre
Pero ¿qué pasa si quieres que tu código se ejecute automáticamente cuando ocurre algo en EPLAN?
Por ejemplo:
- Cuando el usuario cierra un proyecto
- Cuando se abre una página
- Cuando se ejecuta cualquier acción
- Cuando ocurre un error
Para eso existen los Event Handlers.
1. ¿Qué es un Event Handler?
Sección titulada «1. ¿Qué es un Event Handler?»1.1 Definición
Sección titulada «1.1 Definición»Un Event Handler (manejador de eventos) es un método que se ejecuta automáticamente cuando ocurre un evento específico en EPLAN.
Analogía: Es como un detector de movimiento que enciende la luz automáticamente cuando alguien entra a una habitación.
1.2 Sintaxis básica
Sección titulada «1.2 Sintaxis básica»[DeclareEventHandler("NombreDelEvento")]public void MiMetodo(){ // Código que se ejecuta cuando ocurre el evento}Componentes:
[DeclareEventHandler("...")]- Atributo con el nombre del evento"NombreDelEvento"- String que identifica el evento a capturarpublic void- Método público sin valor de retorno
1.3 ¿Dónde se define?
Sección titulada «1.3 ¿Dónde se define?»El atributo está en el mismo namespace que los anteriores:
using Eplan.EplApi.Scripting;2. Comparación de atributos de scripting
Sección titulada «2. Comparación de atributos de scripting»| Característica | [Start] | [DeclareAction] | [DeclareEventHandler] |
|---|---|---|---|
| Ejecución | Manual al abrir script | Manual al llamar acción | Automática al ocurrir evento |
| Nombre | Anónimo | Con nombre | Con nombre de evento |
| Cantidad | Solo uno | Múltiples | Múltiples |
| Parámetro | No acepta | Nombre de acción | Nombre de evento |
| Uso típico | Scripts standalone | Acciones reutilizables | Automatización reactiva |
| Cuándo se ejecuta | Al abrir el .cs | Al invocar por nombre | Al ocurrir el evento |
3. Tu primer Event Handler
Sección titulada «3. Tu primer Event Handler»3.1 Event Handler simple: Al cerrar proyecto
Sección titulada «3.1 Event Handler simple: Al cerrar proyecto»Archivo: 01_EventHandlerSimple.cs
using System.Windows.Forms;using Eplan.EplApi.Scripting;
public class EventHandlerSimple{ [DeclareEventHandler("onActionStart.String.XPrjActionProjectClose")] public void AlCerrarProyecto() { MessageBox.Show("Scripting is great!"); }}3.2 Análisis del código
Sección titulada «3.2 Análisis del código»Evento: onActionStart.String.XPrjActionProjectClose
onActionStart- Se ejecuta al INICIAR una acciónString- Tipo de datoXPrjActionProjectClose- Acción de cerrar proyecto
Comportamiento: Cada vez que el usuario cierre un proyecto en EPLAN, se mostrará el MessageBox automáticamente.
3.3 ¿Cómo cargar el Event Handler?
Sección titulada «3.3 ¿Cómo cargar el Event Handler?»A diferencia de [Start] y [DeclareAction], los event handlers NO se ejecutan al abrir el script una vez. Necesitas registrarlos para que estén activos.
Formas de registrar:
- Ejecutar el script una vez - Algunos event handlers se registran temporalmente
- Usar [DeclareRegister] - Para que se carguen automáticamente al iniciar EPLAN (Capítulo 15)
4. Eventos disponibles en EPLAN
Sección titulada «4. Eventos disponibles en EPLAN»Basándome en los scripts oficiales de EPLAN-Scripting-4.0, estos son los eventos documentados:
4.1 Eventos de proyecto
Sección titulada «4.1 Eventos de proyecto»Evento: Eplan.EplApi.OnUserPreCloseProject
- Cuándo se ejecuta: Antes de cerrar un proyecto
- Uso típico: Realizar acciones finales (exportar, guardar configuración, limpiar archivos temporales)
Ejemplo:
[DeclareEventHandler("Eplan.EplApi.OnUserPreCloseProject")]public void AntesDeCerrarProyecto(){ MessageBox.Show("El proyecto se va a cerrar");}4.2 Eventos de acciones
Sección titulada «4.2 Eventos de acciones»Evento: onActionStart.String.<NombreAccion>
- Cuándo se ejecuta: Al INICIAR una acción específica
- Uso típico: Preparar datos antes de ejecutar una acción
Ejemplo:
[DeclareEventHandler("onActionStart.String.XPrjActionProjectClose")]public void AntesDeAccion(){ MessageBox.Show("Se va a ejecutar la acción de cerrar proyecto");}Evento: onActionEnd.String.*
- Cuándo se ejecuta: Al FINALIZAR cualquier acción (el asterisco es wildcard)
- Uso típico: Logging, captura de errores, auditoría
Ejemplo:
[DeclareEventHandler("onActionEnd.String.*")]public void DespuesDeAccion(IEventParameter iEventParameter){ // Se ejecuta después de CUALQUIER acción en EPLAN}Nota: Este event handler requiere el parámetro IEventParameter para obtener información del evento.
5. Event Handlers con parámetros
Sección titulada «5. Event Handlers con parámetros»5.1 ¿Cuándo usar parámetros?
Sección titulada «5.1 ¿Cuándo usar parámetros?»Algunos eventos proporcionan información adicional sobre lo que ocurrió. Para acceder a esa información, el event handler debe aceptar un parámetro de tipo IEventParameter.
5.2 Sintaxis
Sección titulada «5.2 Sintaxis»[DeclareEventHandler("NombreDelEvento")]public void MiMetodo(IEventParameter iEventParameter){ // Acceder a información del evento}5.3 Ejemplo avanzado: Capturar nombre de acción
Sección titulada «5.3 Ejemplo avanzado: Capturar nombre de acción»Este ejemplo está basado en EPLAN-Scripting-4.0/99_AdditionalExamples/12_HTTPServerEplan/ActionNameServer/actionNameOnServer.cs:
using System;using Eplan.EplApi.Scripting;using Eplan.EplApi.ApplicationFramework;using System.Windows.Forms;
public class EventHandlerAvanzado{ [DeclareEventHandler("onActionEnd.String.*")] public long DespuesDeCualquierAccion(IEventParameter iEventParameter) { try { // Convertir IEventParameter a EventParameterString EventParameterString oEventParameterString = new EventParameterString(iEventParameter);
// Extraer el nombre de la acción ejecutada string nombreAccion = oEventParameterString.String;
// Hacer algo con el nombre de la acción // Ejemplo: Logging, auditoría, enviar a servidor, etc. MessageBox.Show("Se ejecutó: " + nombreAccion); } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); }
return 0; }}5.4 Explicación del uso de IEventParameter
Sección titulada «5.4 Explicación del uso de IEventParameter»Línea 14-15: Conversión de parámetro
EventParameterString oEventParameterString = new EventParameterString(iEventParameter);string nombreAccion = oEventParameterString.String;IEventParameteres la interfaz base para parámetros de eventosEventParameterStringes una implementación concreta que contiene un string- Se crea un
EventParameterStringa partir delIEventParameter - La propiedad
.Stringcontiene el valor (en este caso, el nombre de la acción ejecutada)
Valor de retorno:
Los event handlers con IEventParameter pueden devolver long (aunque generalmente se devuelve 0).
6. Proyecto del capítulo: Exportar PDF al cerrar
Sección titulada «6. Proyecto del capítulo: Exportar PDF al cerrar»6.1 Objetivo
Sección titulada «6.1 Objetivo»Crear un event handler que pregunte al usuario si desea exportar el proyecto a PDF antes de cerrarlo.
6.2 Análisis del script oficial
Sección titulada «6.2 Análisis del script oficial»Este script está basado directamente en EPLAN-Scripting-4.0/16_Export/03_PdfOnClosing.cs:
using System.IO;using System.Windows.Forms;using Eplan.EplApi.ApplicationFramework;using Eplan.EplApi.Base;using Eplan.EplApi.Scripting;
public class ExportarPdfAlCerrar{ [DeclareEventHandler("Eplan.EplApi.OnUserPreCloseProject")] public void AlCerrarProyecto() { // Obtener información del proyecto usando PathMap string rutaDocumentos = PathMap.SubstitutePath("$(DOC)"); string nombreProyecto = PathMap.SubstitutePath("$(PROJECTNAME)");
// Preguntar al usuario DialogResult resultado = MessageBox.Show( "Do you want export a PDF for project '" + nombreProyecto + "' ?", "PDF-Export", MessageBoxButtons.YesNo, MessageBoxIcon.Question );
if (resultado == DialogResult.Yes) { // Crear barra de progreso Progress progress = new Progress("SimpleProgress"); progress.SetAllowCancel(true); progress.SetAskOnCancel(true); progress.BeginPart(100, ""); progress.ShowImmediately();
// Preparar exportación CommandLineInterpreter cli = new CommandLineInterpreter(); ActionCallingContext acc = new ActionCallingContext();
string archivoCompleto = Path.Combine(rutaDocumentos, nombreProyecto); acc.AddParameter("TYPE", "PDFPROJECTSCHEME"); acc.AddParameter("EXPORTFILE", archivoCompleto); acc.AddParameter("EXPORTSCHEME", "EPLAN_default_value");
// Ejecutar exportación cli.Execute("export", acc);
// Cerrar barra de progreso progress.EndPart(true); } }}6.3 Explicación línea por línea
Sección titulada «6.3 Explicación línea por línea»Líneas 9-10: Obtener información del proyecto
string rutaDocumentos = PathMap.SubstitutePath("$(DOC)");string nombreProyecto = PathMap.SubstitutePath("$(PROJECTNAME)");$(DOC)- Ruta de la carpeta de documentos del proyecto$(PROJECTNAME)- Nombre del proyecto actual
Líneas 12-18: Preguntar al usuario
DialogResult resultado = MessageBox.Show( "Do you want export a PDF for project '" + nombreProyecto + "' ?", "PDF-Export", MessageBoxButtons.YesNo, MessageBoxIcon.Question);Muestra un diálogo con botones Sí/No.
Líneas 20-27: Crear barra de progreso
Progress progress = new Progress("SimpleProgress");progress.SetAllowCancel(true);progress.SetAskOnCancel(true);progress.BeginPart(100, "");progress.ShowImmediately();Muestra barra de progreso durante la exportación.
Líneas 29-35: Configurar exportación
CommandLineInterpreter cli = new CommandLineInterpreter();ActionCallingContext acc = new ActionCallingContext();
string archivoCompleto = Path.Combine(rutaDocumentos, nombreProyecto);acc.AddParameter("TYPE", "PDFPROJECTSCHEME");acc.AddParameter("EXPORTFILE", archivoCompleto);acc.AddParameter("EXPORTSCHEME", "EPLAN_default_value");TYPE: Tipo de exportación (PDF de esquema de proyecto)EXPORTFILE: Ruta donde guardar el PDFEXPORTSCHEME: Esquema de exportación a usar
Líneas 37-41: Ejecutar y finalizar
cli.Execute("export", acc);progress.EndPart(true);Ejecuta la exportación y cierra la barra de progreso.
7. Ventajas y limitaciones
Sección titulada «7. Ventajas y limitaciones»7.1 Ventajas de Event Handlers
Sección titulada «7.1 Ventajas de Event Handlers»Automatización completa:
- No requiere intervención del usuario
- Se ejecutan en el momento exacto necesario
- Permiten workflows automáticos
Casos de uso:
- Exportar automáticamente al cerrar proyecto
- Validar datos antes de guardar
- Logging de todas las acciones
- Sincronización automática con sistemas externos
- Auditoría de cambios
7.2 Limitaciones
Sección titulada «7.2 Limitaciones»No persisten entre sesiones:
- Los event handlers solo están activos mientras el script esté cargado
- Para tenerlos siempre activos, debes usar
[DeclareRegister](Capítulo 15)
Difíciles de debuggear:
- Se ejecutan automáticamente, puede ser difícil saber cuándo y por qué
- Errores pueden pasar desapercibidos
Documentación limitada:
- No hay lista oficial completa de todos los eventos disponibles
- Debes investigar o basarte en ejemplos
8. Errores comunes
Sección titulada «8. Errores comunes»8.1 Olvidar registrar el event handler
Sección titulada «8.1 Olvidar registrar el event handler»Error: Crear el script pero nunca ejecutarlo, esperando que funcione automáticamente.
Solución:
Debes ejecutar el script al menos una vez para registrar el event handler, o usar [DeclareRegister] para carga automática.
8.2 Nombre de evento incorrecto
Sección titulada «8.2 Nombre de evento incorrecto»Error:
[DeclareEventHandler("onProjectClose")] // ✗ Nombre incorrectoSolución: Usa los nombres exactos de eventos documentados. Los nombres son case-sensitive.
8.3 Event handler que bloquea EPLAN
Sección titulada «8.3 Event handler que bloquea EPLAN»Error:
[DeclareEventHandler("onActionEnd.String.*")]public void Bloqueante(IEventParameter iEventParameter){ // Operación muy larga sin Progress for (int i = 0; i < 1000000; i++) { // ... }}Solución:
Los event handlers deben ser rápidos. Si necesitas operaciones largas, usa Progress o ejecución asíncrona.
Resumen
Sección titulada «Resumen»En este capítulo aprendiste:
- Los Event Handlers se ejecutan automáticamente cuando ocurre un evento
- Se declaran con el atributo [DeclareEventHandler(“NombreEvento”)]
- Eventos principales:
Eplan.EplApi.OnUserPreCloseProject,onActionStart.String.*,onActionEnd.String.* - Event handlers pueden tener parámetros (
IEventParameter) para acceder a información del evento - Usos típicos: exportación automática, validación, logging, auditoría
- Requieren registro para estar activos (temporal o permanente con [DeclareRegister])
Preguntas frecuentes
Sección titulada «Preguntas frecuentes»P: ¿Dónde está la lista completa de eventos disponibles?
R: No hay una lista pública oficial completa. Los eventos documentados aparecen en los scripts de ejemplo de EPLAN-Scripting-4.0. También puedes consultarlos en la documentación de la API (EplanAPI.chm).
P: ¿Puedo tener múltiples event handlers en el mismo script?
R: Sí, puedes tener varios [DeclareEventHandler] para diferentes eventos en el mismo archivo.
P: ¿Los event handlers persisten después de cerrar EPLAN?
R: No. Debes volver a ejecutar el script cada vez que abras EPLAN, o usar [DeclareRegister] para carga automática (próximo capítulo).
P: ¿Puedo cancelar un evento?
R: Depende del evento. Algunos eventos como OnUserPreCloseProject permiten cierta interacción, pero no estoy al 90% seguro de cómo cancelar eventos sin más documentación.
Conexiones
Sección titulada «Conexiones»Capítulo anterior
Sección titulada «Capítulo anterior»Capítulo 13: [DeclareAction] - Acciones personalizadas
Próximo capítulo
Sección titulada «Próximo capítulo»Capítulo 15: Register/Unregister - Carga automática
En el próximo capítulo aprenderás a hacer que tus scripts y event handlers se carguen automáticamente al iniciar EPLAN.
Última actualización: Enero 2025
Tiempo de lectura estimado: 25-30 minutos
Código de ejemplo: code/cap-14/
Scripts de referencia:
EPLAN-Scripting-4.0/01_FirstSteps/03_DeclareEventHandler.csEPLAN-Scripting-4.0/16_Export/03_PdfOnClosing.cs