Un evento del DOM es una notificación que genera el navegador cuando el usuario o la página realizan una acción.
En Blazor podemos responder a clics, teclas o cambios de formulario con métodos de C# enlazados desde el marcado Razor, sin registrar manualmente un listener con addEventListener.
Sintaxis básica @onevent
La regla general en Blazor es muy sencilla: cualquier evento estándar del DOM HTML tiene un equivalente en sintaxis Razor que empieza por @on seguido del nombre del evento.
onclick=>:@onclickonchange=>@onchangeoninput=>@oninputonkeydown=>@onkeydown
Para manejar el evento, simplemente asignamos un método de C# a ese atributo.
<button class="btn btn-primary" @onclick="ProcesarClick">
Haz Click Aquí
</button>
<p>Mensaje: @mensaje</p>
@code {
private string mensaje = "Esperando...";
private void ProcesarClick()
{
mensaje = "¡Botón pulsado a las " + DateTime.Now.ToLongTimeString() + "!";
}
}Cuando el evento termina de ejecutarse, Blazor llama automáticamente a StateHasChanged(). Esto hace que el componente se vuelva a renderizar para reflejar los cambios en la UI (como la actualización de la variable mensaje).
Argumentos del evento
A menudo, el simple hecho de saber que “ha ocurrido algo” no es suficiente. Necesitamos detalles.
- Si es un clic, ¿dónde ha hecho clic el usuario? ¿Tenía pulsada la tecla CTRL?
- Si es una tecla, ¿qué letra ha pulsado?
Blazor nos permite recibir un objeto de argumentos en nuestro método manejador. El tipo de este objeto depende del evento.
MouseEventArgs
Para eventos de ratón (@onclick, @onmousemove, etc.), el método puede aceptar un parámetro MouseEventArgs.
<div style="background-color: lightgray; height: 200px;"
@onclick="MostrarCoordenadas">
Haz clic dentro de este cuadro.
</div>
<p>@coordenadas</p>
@code {
private string coordenadas;
private void MostrarCoordenadas(MouseEventArgs e)
{
coordenadas = $"X: {e.ClientX}, Y: {e.ClientY}";
if (e.CtrlKey)
{
coordenadas += " (¡Con tecla CTRL pulsada!)";
}
}
}KeyboardEventArgs
Para eventos de teclado, usamos KeyboardEventArgs. Esto es fundamental para crear atajos de teclado o inputs interactivos.
<input type="text" @onkeydown="VerificarTecla" placeholder="Escribe algo..." />
<p>@estado</p>
@code {
private string estado;
private void VerificarTecla(KeyboardEventArgs e)
{
if (e.Key == "Enter")
{
estado = "¡Has pulsado ENTER! Procesando...";
}
else
{
estado = $"Tecla pulsada: {e.Key} (Código: {e.Code})";
}
}
}En un campo de texto, @onchange se dispara cuando el usuario confirma el cambio (normalmente al perder el foco o pulsar Intro), mientras que @oninput responde a cada modificación del valor. Para una búsqueda en tiempo real suele interesar @oninput.
Pasar argumentos personalizados con expresiones lambda
Este es el escenario más común y donde más gente se atasca al principio.
Supongamos que tienes una lista generada con @foreach y quieres que el botón «Eliminar» actúe sobre un elemento concreto.
El manejador de eventos estándar no nos sirve, porque necesitamos pasarle el Id o el objeto Item. La solución es usar una Expresión Lambda.
<h3>Lista de Tareas</h3>
<ul>
@foreach (var tarea in Tareas)
{
<li>
@tarea.Nombre
<button @onclick="() => BorrarTarea(tarea.Id)">
🗑️ Eliminar
</button>
</li>
}
</ul>
@code {
private void BorrarTarea(int idTarea)
{
var tareaABorrar = Tareas.FirstOrDefault(t => t.Id == idTarea);
if (tareaABorrar != null)
{
Tareas.Remove(tareaABorrar);
}
}
// ... definición de lista Tareas ...
}La sintaxis () => Metodo(parametro) crea una función anónima pequeña que Blazor ejecutará cuando ocurra el evento.
Modificadores de eventos: preventDefault y stopPropagation
A veces necesitamos controlar el comportamiento nativo del navegador.
preventDefault: Evita la acción por defecto. Por ejemplo, evitar que un formulario se envíe o que al pulsar una tecla en un input se escriba el carácter.stopPropagation: Evita que el evento “burbujee” hacia los elementos padres.
En Blazor, esto se hace mediante directivas de atributos.
<a href="https://google.com"
@onclick="LogClick"
@onclick:preventDefault="true">
Enlace desactivado
</a>
<div @onclick="ClickPadre">
Padre
<button @onclick="ClickHijo" @onclick:stopPropagation="true">
Hijo (No dispara el evento del padre)
</button>
</div>Eventos asíncronos
Los manejadores de eventos pueden devolver Task. Si al hacer clic vas a esperar una base de datos o una API, usa async Task en lugar de async void.
private async Task CargarDatos()
{
IsLoading = true;
// Blazor detecta este await y permite que la UI se actualice para mostrar el "Cargando..."
await Task.Delay(2000);
IsLoading = false;
}Blazor es lo suficientemente listo para esperar a que termine la Task y hacer un renderizado final.