Patrones de uso

Cinco ejemplos completos con DinaZen y el SDK: informe a tabla, datos tipados, selector correcto, diálogo y estados de carga.

Ejemplos para copiar y adaptar. Cada uno resuelve una tarea habitual de una app Blazor sobre el SDK .NET: traer datos con el Cliente Dinaup y mostrarlos con DinaZen.

El reparto es siempre el mismo: el cliente trae el dato y DinaZen lo muestra. Cuando un ejemplo pide un DinaupClientC, sale de crear y conectar el cliente.


De un informe a una tabla

Un informe de Dinaup Flex (su GUID) se muestra como tabla con paginación, búsqueda, filtros y exportación a CSV. DnzReportView ejecuta el informe con tu cliente y genera la rejilla a partir de la definición del informe. No declaras columnas.

Crea y conecta el cliente

@code {
    private DinaupClientC _client;

    protected override async Task OnInitializedAsync()
    {
        _client = await DinaupClientC.ConnectAsync(endpoint, publicKey, secretKey);
    }
}

Muestra el informe en la página

Pasa el cliente y el GUID del informe. Columnas, tipos y formatos salen de la definición.

@if (_client.IsNotNull())
{
    <div style="height:600px; overflow:auto;">
        <DnzReportView Client=@_client ReportId="3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f" Limit="50" />
    </div>
}

Reacciona a la fila pulsada

Por defecto, al pulsar una fila el componente abre la ficha del registro. Para tu propio comportamiento, captura OnItemSelect.

<DnzReportView Client=@_client ReportId="3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f" OnItemSelect=@AbrirDetalleAsync />

@code {
    private async Task AbrirDetalleAsync(DinaupDynamicRowDTO row)
    {
        var nombre = row.GetLegible("nombre");
        await DnzFormView.OpenAsync(DialogService, _client, row.SectionId, row.ID);
    }
}

DnzReportView llama a Client.Report_GetAsync por dentro y gestiona carga, errores y paginación en servidor. Tú pones cliente y GUID.

Para abrirlo en un diálogo o en una ventana flotante en lugar de en la página, el componente expone dos métodos estáticos.

@inject DialogService DialogService

@code {
    private async Task AbrirInformeAsync()
    {
        await DnzReportView.OpenAsync(DialogService, _client, "3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f", title: "Ventas del mes");
    }
}
@inject DnzWindowManagerService WindowManager

@code {
    private void AbrirInformeEnVentana()
    {
        DnzReportView.OpenAsWindow(WindowManager, _client, "3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f", title: "Ventas");
    }
}

Firmas de los métodos estáticos

Task DnzReportView.OpenAsync(DialogService ds, DinaupClientC client, string reportId, Dictionary<string, string> vars = null, string title = "Informe", string width = "90%", string height = "80%", List<FilterCondition> filter = null)
string DnzReportView.OpenAsWindow(DnzWindowManagerService wm, DinaupClientC client, string reportId, Dictionary<string, string> vars = null, string title = "Informe", string icon = "analytics")

DnzReportView

Ejecuta un informe de Flex y lo muestra como tabla con búsqueda, filtros, paginación en servidor y exportación a CSV.

<DnzReportView Client=@_client ReportId="3f2a9c10-8b4e-4d21-9f77-1a2b3c4d5e6f" Limit="50" Title="Ventas" />

Parámetros

ParámetroTipoPor defectoQué hace
ClientDinaupClientCObligatorio. Cliente del SDK ya inicializado.
ReportIdstring""Obligatorio. GUID del informe a ejecutar.
VariablesValuesDictionary<string, string>nullValores para las variables del informe.
QuerySearchstring""Búsqueda textual inicial.
AdvancedFilterList<FilterCondition>nullCondiciones de filtro aplicadas de entrada.
Limitint25Filas por página. El usuario elige entre 25, 50, 100, 250, 500, 1000 y 3000.
OrdenDictionary<string, bool>nullOrden inicial (clave = columna, valor true = descendente).
ShowTitlebooltrueMuestra la cabecera con título e icono de la sección.
Titlestring""Sobrescribe el título; vacío usa el del informe.
ShowSearchbooltrueMuestra la caja de búsqueda.
FiltrablebooltrueHabilita los filtros por columna.
ShowAddbooltrueMuestra el botón de añadir registro.
ShowLoadTimebooltrueMuestra el tiempo de carga del informe.
AdminModeboolfalseEjecuta el informe en modo administrador.
ToolBarTemplateRenderFragmentnullContenido extra en la barra de herramientas.
OnItemSelectEventCallback<DinaupDynamicRowDTO>Se dispara al seleccionar una fila y sustituye la apertura automática de la ficha.
OnDataChangedEventCallbackSe dispara cuando los datos se recargan.
AllowCellSelectionboolfalseDeja elegir celdas con Ctrl+clic (una) y Mayús+clic (un rango); un clic sin teclas sigue abriendo la ficha.
SelectedCellsChangedEventCallback<DnzCellSelection>Selección de celdas, con Cells, RowIds y Keywords.
FetchInterceptorFunc<string, bool, Func<Task<ReportResponse>>, Task<ReportResponse>>nullGancho de caché: recibe la clave de la petición, si es refresco forzado y la función de carga real.

DnzReportProvider

Variante sin tabla: ejecuta el informe y expone las filas como ReportContext en cascada, sin mostrar nada. Sirve para usar los datos del informe con tu propio marcado o con DnzCardList, DnzChartView y DnzTopN.

<DnzReportProvider Client=@_client ReportId="7c1d4e90-2f5a-41b8-bc63-9e0a1b2c3d4f" Limite="500">
    <DnzChartView ChartType="DnzChartView.ChartTypeE.Column" />
    <DnzTopN N="5" />
</DnzReportProvider>

Parámetros

ParámetroTipoPor defectoQué hace
ClientDinaupClientCObligatorio. Cliente del SDK ya inicializado.
ReportIdstring""Obligatorio. GUID del informe a ejecutar.
VariablesValuesDictionary<string, string>nullValores para las variables del informe.
QuerySearchstring""Búsqueda textual inicial.
AdvancedFilterList<FilterCondition>nullCondiciones de filtro aplicadas de entrada.
Limiteint500Máximo de filas a traer.
OrdenDictionary<string, bool>nullOrden inicial (clave = columna, valor true = descendente).
AdminModeboolfalseEjecuta el informe en modo administrador.
ChildContentRenderFragmentnullLas vistas que leen el ReportContext en cascada.
OnDataLoadedEventCallbackSe dispara cuando las filas terminan de cargar.

Mostrar datos tipados

Un importe, una fecha o unos minutos se muestran con su formato (moneda de la región, fecha legible, color según el signo) sin formatear a mano. Lo hace la familia de Spans: cada uno formatea su tipo según la cultura del cliente.

<div class="d-flex flex-column gap-2">
    <DnzSpanMoney Amount=@factura.Total Label="Total" Icon="payments" AutoColor=true />
    <DnzSpanDate Value=@factura.Vencimiento ShowStatus=true />
</div>

En DnzSpanMoney, AutoColor=true muestra el importe en verde si es positivo y en rojo si es negativo. Para una sola de las dos reglas, usa AutoColorGreen o AutoColorRed.

DnzSpanMoney

Muestra un importe con la moneda de la región del cliente, con etiqueta, icono y color por signo opcionales.

<DnzSpanMoney Amount=@total Label="Total" Icon="payments" AutoColor=true />

Parámetros

ParámetroTipoPor defectoQué hace
Amountdecimal?0Importe a mostrar. Si es nulo, no muestra nada.
Labelstring""Etiqueta encima del importe.
Iconstring""Icono Material a la izquierda (requiere Label).
AutoColorboolfalseVerde si positivo, rojo si negativo.
AutoColorGreenboolfalseSolo verde cuando es positivo.
AutoColorRedboolfalseSolo rojo cuando es negativo.
IsVisiblebooltrueOculta el componente si es false.
CssClassstring""Clases CSS extra en el span del importe.
FontSizestring"16px"Tamaño de fuente del importe.

DnzSpanDate

Muestra una fecha con el formato legible de la región, texto emergente con la fecha exacta y una etiqueta de estado opcional (Hoy, Mañana, Ayer, Pasado, Futuro).

<DnzSpanDate Value=@pedido.Fecha ShowStatus=true />

Parámetros

ParámetroTipoPor defectoQué hace
ValueDateOnly?nullFecha a mostrar. Si es nula, no muestra nada.
FriendlyModebooltrueUsa el formato legible de la región.
ShowBadgeboolfalseMuestra la fecha dentro de una etiqueta (RadzenBadge).
ShowStatusboolfalseAñade una etiqueta de color con el estado relativo a hoy.
Classstring""Clases CSS extra en el contenedor.
FontSizestring"0.875rem"Tamaño de fuente.

Hay un Span por cada tipo de dato: DnzSpanDateTime, DnzSpanDecimal, DnzSpanInteger, DnzSpanPercent, DnzSpanMinutes, DnzSpanGrams, DnzSpanBytes, DnzSpanGigaBytes, DnzSpanKV. Todos reciben el valor sin formato y lo formatean. Referencia completa en Datos tipados.


Elegir el selector correcto

El desplegable para que el usuario elija un valor depende de dónde salen las opciones.

  • Un enum: DnzEnumDropDown. Obtiene las opciones del propio tipo.
  • Una lista acotada que ya está en memoria (impuestos, almacenes, estados): DnzDataGridDropDown. Desplegable con búsqueda en cliente y columnas.
  • Un catálogo que crece sin tope (clientes, productos): DnzRowSelector. Busca en el servidor contra un informe mientras escribes.

La regla completa, con RadzenDropDown, DnzDropDown y DnzSectionDropDown, está en Selectores.

El enlace es @bind-Value sobre tu enum. Las opciones salen del tipo.

<DnzEnumDropDown TEnum="EstadoPedidoE" @bind-Value=@_estado Placeholder="Estado" />

@code {
    private EstadoPedidoE _estado;
}

El enlace es @bind-Value sobre un objeto que implemente IDinaupRow. Recibe la lista por Data y la propiedad a mostrar con TextProperty.

<DnzDataGridDropDown T="DinaupBasicInformation" @bind-Value=@_cliente Data=@_clientes TextProperty=@nameof(DinaupBasicInformation.Label) Label="Cliente" Width="320px" />

@code {
    private DinaupBasicInformation _cliente;
    private List<DinaupBasicInformation> _clientes = new();
}

El enlace es @bind-SelectedRow. Recibe el cliente y el GUID del informe en el que busca.

<DnzRowSelector Client=@_client ReportId=@SectionsD.EntidadesD._SectionID @bind-SelectedRow=@_clienteSel Label="Cliente" Placeholder="Buscar cliente" />

@code {
    private IDinaupRow _clienteSel;
}

DnzEnumDropDown

Desplegable cuyas opciones salen de un enum. La etiqueta de cada opción se toma del atributo [Display(Name = "...")] si existe; si no, del nombre del valor.

<DnzEnumDropDown TEnum="EstadoPedidoE" @bind-Value=@_estado />

Parámetros

ParámetroTipoPor defectoQué hace
ValueTEnumValor seleccionado. Usa @bind-Value.
ValueChangedEventCallback<TEnum>Se dispara al cambiar la selección.
Namestring""Nombre del campo (para formularios).
Stylestring"width:200px"Estilo CSS del desplegable.
Placeholderstring""Texto cuando no hay selección.
DisabledboolfalseDesactiva el control.

Acepta atributos extra que se pasan al elemento raíz.

DnzDataGridDropDown

Desplegable con búsqueda y columnas para una lista en memoria. T tiene que implementar IDinaupRow.

<DnzDataGridDropDown T="DinaupBasicInformation" @bind-Value=@_cliente Data=@_clientes TextProperty=@nameof(DinaupBasicInformation.Label) Label="Cliente" />

Parámetros

ParámetroTipoPor defectoQué hace
ValueTElemento seleccionado. Usa @bind-Value.
ValueChangedEventCallback<T>Se dispara al cambiar la selección.
DataIEnumerable<T>lista vacíaOrigen de datos en memoria.
TextPropertystringnullObligatorio. Propiedad a mostrar como texto.
ColorPropertystringnullPropiedad que da el color de etiqueta a cada opción.
IconoPropertystringnullPropiedad que aporta el icono de cada opción.
LabelstringnullEtiqueta del campo.
IconstringnullIcono a la izquierda del campo.
Widthstring"280px"Ancho del control.
StylestringnullEstilo CSS extra.
VisiblebooltrueMuestra u oculta el control.
IsRequiredboolfalseMarca el campo como obligatorio.
DisabledboolfalseDesactiva el control.
OpenInWindowbooltrueEl botón de abrir lanza la ficha en una ventana.
ClientDinaupClientCnullCliente para abrir la ficha del valor.
ColumnsRenderFragmentnullColumnas personalizadas del desplegable.
ValueTemplateRenderFragment<dynamic>nullPlantilla del valor seleccionado.
IconTemplateRenderFragment<T>nullPlantilla del icono por elemento.
ColumnWidthstring""Ancho de las columnas.
OnAddEventCallbackAl pulsar el botón de añadir.
OnRemoveEventCallback<T>Al limpiar la selección.
OnOpenEventCallback<T>Al pulsar abrir la ficha del valor.

Acepta atributos extra que se pasan al elemento raíz.

DnzRowSelector

Selector que busca en un informe del servidor mientras escribes, de 20 en 20 filas. Para fichas del servidor que son demasiadas para tenerlas en memoria.

<DnzRowSelector Client=@_client ReportId=@SectionsD.EntidadesD._SectionID @bind-SelectedRow=@_clienteSel Label="Cliente" />

Parámetros

ParámetroTipoPor defectoQué hace
ClientDinaupClientCObligatorio. Cliente del SDK ya inicializado.
ReportIdstringnullGUID del informe en el que busca.
SelectedRowIDinaupRownullFila seleccionada. Usa @bind-SelectedRow.
SelectedRowChangedEventCallback<IDinaupRow>Se dispara al cambiar la selección.
LabelstringnullEtiqueta del campo.
IconstringnullIcono a la izquierda.
PlaceholderstringnullTexto cuando no hay selección.
Widthstring"280px"Ancho del control.
Stylestring"flex:1"Estilo CSS extra.
Classstring""Clases CSS extra.
IsRequiredboolfalseMarca el campo como obligatorio.
DisabledboolfalseDesactiva el control.
AdminModeboolfalseBusca en modo administrador.
AdvancedFilterList<FilterCondition>nullCondiciones aplicadas a la búsqueda.
OpenInWindowbooltrueEl botón de abrir lanza la ficha en una ventana.
DefaultIDGuidGuid.EmptyPreselecciona una fila por su ID al cargar (una consulta al servidor).
DefaultLabelstringnullEtiqueta ya conocida para DefaultID: muestra la selección inicial sin consultar.
OnAddEventCallback<Guid>Al pulsar el botón de añadir.
OnOpenRecordEventCallback<IDinaupRow>Al pulsar abrir la ficha de la fila.
FetchInterceptorFunc<string, bool, Func<Task<ReportResponse>>, Task<ReportResponse>>nullGancho de caché, el mismo que en DnzReportView.

Acepta atributos extra que se pasan al elemento raíz.


Un diálogo con la estructura de Play lleva el título en la cabecera, el contenido en el cuerpo y los botones al pie. DnzDialogLayout aporta los tres huecos.

@inject DialogService DialogService

<DnzDialogLayout Title="Editar pedido" Icon="edit" AltoAuto=true>
    <BodyContent>
        <div class="d-flex flex-column gap-3 p-3">
            <RadzenTextBox @bind-Value=@_nombre Placeholder="Nombre" />
        </div>
    </BodyContent>
    <FooterContent>
        <div class="d-flex gap-2 justify-content-end">
            <RadzenButton Text="Cancelar" Variant="Variant.Text" ButtonStyle="ButtonStyle.Danger" Click=@Cancelar />
            <RadzenButton Text="Guardar" ButtonStyle="ButtonStyle.Success" Click=@GuardarAsync IsBusy=@_guardando />
        </div>
    </FooterContent>
</DnzDialogLayout>

@code {
    private string _nombre = "";
    private bool _guardando;

    private void Cancelar() => DialogService.Close();

    private async Task GuardarAsync()
    {
        if (_guardando) return;
        _guardando = true;
        try
        {
            await PersistirAsync();
            DialogService.Close(true);
        }
        finally
        {
            _guardando = false;
        }
    }
}

La convención del pie: Cancelar en Danger + Text, Aceptar en Success sólido. Marca el botón de confirmar con IsBusy=@_guardando mientras procesa: el botón muestra el indicador de carga. IsBusy no impide una segunda llamada al método; la primera línea de GuardarAsync lo evita.

DnzDialogLayout

Estructura de diálogo con cabecera, cuerpo desplazable y pie. Sin TitleContent, genera la cabecera con Title + Icon + botón de cerrar; sin FooterContent, muestra un botón Cerrar.

Parámetros

ParámetroTipoPor defectoQué hace
TitlestringnullTítulo de la cabecera automática.
IconstringnullIcono Material de la cabecera automática.
TitleContentRenderFragmentnullCabecera personalizada completa.
BodyContentRenderFragmentnullContenido del cuerpo (desplazable).
FooterContentRenderFragmentnullPie personalizado (botones de acción).
ContentStylestringnullEstilo CSS del cuerpo.
HeaderStylestringnullEstilo CSS de la cabecera.
IsLoadingboolfalseSustituye el cuerpo por un esqueleto de carga.
LoadingTextstringnullCon texto, muestra un indicador de carga con ese mensaje en lugar del esqueleto.
ErrorTextstringnullCon texto, sustituye el cuerpo por un aviso de error. Tiene prioridad sobre IsLoading.
OnRetryEventCallbackCon delegado, el aviso de error muestra el botón Reintentar.
FlatboolfalseDiálogo plano, sin degradados ni fondo gris.
AltoAutoboolfalseEl diálogo se ajusta a su contenido hasta un máximo de 85vh. Ábrelo con Height = null en las DialogOptions.

DnzConfirmDialog

Para una acción destructiva (eliminar, vaciar), no montes un diálogo entero: abre la confirmación con el método estático OpenAsync, que devuelve true si el usuario confirma.

@code {
    private async Task EliminarAsync()
    {
        var ok = await DnzConfirmDialog.OpenAsync(DialogService, "Esta acción no se puede deshacer. Se elimina el pedido.", title: "Eliminar pedido", severity: DnzConfirmSeverity.Danger, okText: "Eliminar");
        if (ok == false) return;
        await BorrarPedidoAsync();
    }
}

Firma del método estático

Task<bool> DnzConfirmDialog.OpenAsync(DialogService dialogService, string message, string title = "Confirmar", DnzConfirmSeverity severity = DnzConfirmSeverity.Warning, string okText = "Confirmar", string cancelText = "Cancelar")

El severity (Info, Warning, Danger, Success) cambia el icono, el color de acento y el estilo del botón de confirmar. Para algo irreversible, usa DnzConfirmSeverity.Danger.


Estados de carga

DinaZen tiene tres piezas para indicar que algo está en curso, una para cada momento.

  • DnzLoader: hay una acción en curso (guardar, calcular, llamar a la API). Indicador de carga.
  • DnzSkeleton: la interfaz aún no tiene datos; reserva su silueta.
  • DnzDeferredContent: renderiza contenido pesado un poco más tarde, con un esqueleto mientras tanto.
@if (_procesando)
{
    <DnzLoader />
}
@if (_cargando)
{
    <DnzSkeleton Lines="3" />
}
<DnzDeferredContent DelayMs="500">
    <GraficoPesado Data=@_datos />
</DnzDeferredContent>

DnzLoader

Indicador de operación en curso. Centrado por defecto; horizontal para una barra o cabecera.

<DnzLoader />

Parámetros

ParámetroTipoPor defectoQué hace
HorizontalboolfalseVariante horizontal en lugar de centrada.

DnzSkeleton

Silueta gris animada que ocupa el sitio del contenido mientras carga.

<DnzSkeleton Lines="3" Height="1.2rem" />

Parámetros

ParámetroTipoPor defectoQué hace
Linesint1Número de líneas (rectángulos).
Heightstring"1rem"Altura de cada línea.
Radiusstring"0.25rem"Radio de las esquinas.
MaxWidthstring"100%"Ancho máximo del bloque.

DnzDeferredContent

Retrasa el renderizado del contenido pesado y muestra un esqueleto mientras tanto. Sirve para que las subpáginas pesadas no bloqueen el primer renderizado.

<DnzDeferredContent DelayMs="500">
    <SeccionPesada />
</DnzDeferredContent>

Parámetros

ParámetroTipoPor defectoQué hace
DelayMsint500Milisegundos antes de mostrar el contenido.
ChildContentRenderFragmentContenido que se renderiza tras el retardo.
LoadingContentRenderFragmentnullIndicador de carga personalizado (por defecto, un DnzSkeleton).
Classstring""Clases CSS del contenedor de carga.

Relacionado

En esta página