Ir al contenido

Capítulo 29: Cambiar cursor durante operaciones

Capítulo 29: Cambiar cursor durante operaciones

Sección titulada «Capítulo 29: Cambiar cursor durante operaciones»

Parte VIII: Windows Forms - Sección 16: Interfaces gráficas - Nivel: Intermedio


Al finalizar este capítulo serás capaz de:

  • Usar Cursors.WaitCursor para indicar que el sistema está ocupado
  • Entender el patrón try-finally aplicado a interfaces gráficas
  • Mejorar la experiencia de usuario (UX) en operaciones de duración media

  • Capítulo 28 (Formulario completo)
  • Concepto de Try-Finally (Capítulo 11)

Si el usuario hace clic en “Procesar” y el programa se congela por 3 segundos sin feedback, pensará que se bloqueó. Para operaciones cortas (1-4 segundos), una barra de progreso es excesiva. La solución estándar: Cambiar el cursor del mouse a un reloj de arena (o círculo giratorio).


Windows Forms proporciona la clase estática Cursor y la propiedad Current.

using System.Windows.Forms;
// Cambiar a "Cargando"
Cursor.Current = Cursors.WaitCursor;
// Volver a "Flecha normal"
Cursor.Current = Cursors.Default;

Si cambias el cursor y tu código falla antes de restaurarlo, el usuario se quedará con el reloj de arena para siempre (o hasta que reinicie EPLAN).

Por eso, SIEMPRE debes usar try-finally.

private void BtnProcesar_Click(object sender, EventArgs e)
{
try
{
// 1. Cambiar cursor
Cursor.Current = Cursors.WaitCursor;
// 2. Operación pesada
RealizarTrabajo();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
finally
{
// 3. Restaurar cursor (SIEMPRE se ejecuta)
Cursor.Current = Cursors.Default;
}
}

Vamos a mejorar nuestro formulario anterior. Cuando el usuario exporta, cambiamos el cursor.

Basado en EPLAN-Scripting-4.0/09_Forms/03_Cursor.cs:

using System;
using System.Drawing;
using System.Threading; // Para simular delay
using System.Windows.Forms;
using Eplan.EplApi.Scripting;
public class FormularioCursor : Form
{
private Button btnProcess;
public FormularioCursor()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.Text = "Ejemplo de Cursor";
this.Size = new Size(300, 150);
this.StartPosition = FormStartPosition.CenterScreen;
btnProcess = new Button();
btnProcess.Text = "Procesar Datos";
btnProcess.Location = new Point(80, 40);
btnProcess.Size = new Size(120, 30);
btnProcess.Click += new EventHandler(BtnProcess_Click);
this.Controls.Add(btnProcess);
}
private void BtnProcess_Click(object sender, EventArgs e)
{
// Deshabilitar botón para evitar doble clic
btnProcess.Enabled = false;
try
{
// CAMBIAR CURSOR
Cursor.Current = Cursors.WaitCursor;
// Simular trabajo pesado (3 segundos)
// En la vida real, aquí iría tu lógica de EPLAN
Thread.Sleep(3000);
MessageBox.Show("Proceso terminado correctamente.");
}
finally
{
// RESTAURAR CURSOR Y BOTÓN
Cursor.Current = Cursors.Default;
btnProcess.Enabled = true;
}
}
[Start]
public void Function()
{
FormularioCursor frm = new FormularioCursor();
frm.ShowDialog();
}
}

  • Cursors.WaitCursor: Reloj de arena. Sistema bloqueado.
  • Cursors.AppStarting: Flecha + Reloj. Trabajando en segundo plano, pero interactivo.
  • Cursors.Hand: Mano. Usar sobre enlaces o botones especiales.
  • Cursors.Help: Flecha + Interrogación. Para modo de ayuda.

  • Usa Cursor.Current = Cursors.WaitCursor para operaciones de 1 a 4 segundos.
  • Para operaciones más largas, usa Progress (Capítulo 26).
  • Siempre restaura el cursor en un bloque finally.
  • Deshabilitar el botón que inició la acción (Enabled = false) es una buena práctica complementaria.

Capítulo 28: Formulario completo

Ver capítulos siguientes

Pondremos todo en práctica con una aplicación real para buscar y abrir proyectos.