Vai al contenuto

Gestione degli Eventi: BubbleEvent e BeforeAction

Nel SAP Business One SDK, la gestione degli eventi UI (come il click su un bottone, la modifica di un campo, ecc.) segue un pattern molto particolare basato su una "doppia chiamata" (double-call). Comprendere questo meccanismo è fondamentale per sviluppare addon performanti e senza bug.

Il Meccanismo della Doppia Chiamata

Ogni volta che l'utente esegue un'azione nell'interfaccia (es. clicca su "Aggiungi"), SAP Business One scatena l'evento corrispondente due volte:

  1. Prima dell'azione standard di SAP (BeforeAction = true): L'evento viene scatenato prima che SAP processi internamente l'azione. In questa fase, hai la possibilità di analizzare cosa sta per succedere ed eventualmente bloccare l'azione.
  2. Dopo l'azione standard di SAP (BeforeAction = false): L'evento viene scatenato dopo che SAP ha eseguto la sua logica. In questa fase, puoi reagire a ciò che è successo (es. aggiornare un campo dopo che un altro è stato modificato).

Il ruolo di BubbleEvent

Il parametro BubbleEvent (che è un parametro di tipo out bool o passato per riferimento in C#) è il "semaforo" del tuo evento. Se imposti BubbleEvent = false durante la fase BeforeAction = true, stai dicendo a SAP: "Ferma tutto, annulla l'azione dell'utente".

Nota importante

Impostare BubbleEvent = false ha senso (ed ha effetto) solo quando BeforeAction == true. Se lo fai quando BeforeAction == false, l'azione di SAP è ormai già stata eseguita e non può essere annullata in questo modo.

Flusso degli Eventi

Ecco un diagramma che mostra l'intero ciclo di vita di un evento:

sequenceDiagram
    actor User as Utente
    participant UI as SAP B1 UI
    participant Addon as Tuo Addon
    participant Core as SAP B1 Core

    User->>UI: Clicca bottone "Aggiungi"
    UI->>Addon: Scatena ItemEvent (BeforeAction = true)

    alt Addon imposta BubbleEvent = false
        Addon-->>UI: BubbleEvent = false
        UI-->>User: Azione annullata (nessun salvataggio)
    else Addon lascia BubbleEvent = true
        Addon-->>UI: BubbleEvent = true
        UI->>Core: Esegue salvataggio standard
        Core-->>UI: Salvataggio completato
        UI->>Addon: Scatena ItemEvent (BeforeAction = false)
        Addon-->>UI: Logica post-azione completata
        UI-->>User: Ritorna il controllo all'utente
    end

Pattern di Sviluppo

A seconda di cosa vuoi ottenere, userai la fase Before o After.

1. Pattern di Validazione (Blocco)

Vuoi controllare i dati prima del salvataggio e bloccarlo se non sono corretti.

public void OnItemEvent_ValidateBeforeSave(string formUID, ref SAPbouiCOM.ItemEvent pVal, out bool bubbleEvent)
{
    // 1. INIZIALIZZARE SEMPRE A TRUE
    bubbleEvent = true;

    // 2. FILTRARE L'EVENTO E LA FASE (BeforeAction = true)
    if (pVal.EventType == SAPbouiCOM.BoEventTypes.et_ITEM_PRESSED && 
        pVal.ItemUID == "1" && // "1" è l'UID standard del bottone Aggiungi/Aggiorna
        pVal.BeforeAction == true)
    {
        // 3. LA TUA LOGICA DI VALIDAZIONE
        string valoreCampo = OttieniValoreCampo(formUID, "MioCampo");

        if (string.IsNullOrEmpty(valoreCampo))
        {
            SAPApplication.StatusBar.SetText("Il campo non può essere vuoto!", SAPbouiCOM.BoMessageTime.bmt_Short, SAPbouiCOM.BoStatusBarMessageType.smt_Error);

            // 4. BLOCCARE L'AZIONE SAP
            bubbleEvent = false;
        }
    }
}

2. Pattern di Reazione (Post-Azione)

Vuoi ricalcolare un totale dopo che l'utente ha modificato la quantità.

public void OnItemEvent_ReactAfterChange(string formUID, ref SAPbouiCOM.ItemEvent pVal, out bool bubbleEvent)
{
    bubbleEvent = true;

    // Filtriamo BeforeAction = false
    if (pVal.EventType == SAPbouiCOM.BoEventTypes.et_VALIDATE && 
        pVal.ItemUID == "Quantita" && 
        pVal.ItemChanged == true &&
        pVal.BeforeAction == false)
    {
        // Ricalcola totali e aggiorna la UI
        RicalcolaTotaliDocumento(formUID);
    }
}

Applicabilità

Questo meccanismo di BeforeAction e BubbleEvent è universale in SAP B1 e si applica ai principali tipi di eventi: - ItemEvent: Interazioni con i controlli della form (click, modifiche, focus). - MenuEvent: Click sulle voci del menu in alto o laterale. - FormDataEvent: Eventi legati ai dati (Caricamento, Aggiunta, Aggiornamento, Cancellazione record). - RightClickEvent: Apertura di menu contestuali (click destro).

Errori Comuni

Dimenticare l'inizializzazione

Se usi parametri out in C#, devi assegnare un valore. Dimenticarsi di impostare bubbleEvent = true all'inizio del tuo gestore significa che bloccherai inavvertitamente l'azione dell'utente!

Codice eseguito due volte

Se non metti un if (pVal.BeforeAction == ...) nel tuo codice, la tua logica verrà eseguita sia prima che dopo l'azione di SAP. Questo causa rallentamenti e spesso bug inspiegabili (es. righe aggiunte due volte, log moltiplicati).

Operazioni pesanti

Evita di fare query SQL pesanti o chiamate di rete durante la fase BeforeAction = true di eventi frequenti come et_MOUSE_MOVE o et_VALIDATE. L'interfaccia utente di SAP rimarrà bloccata finché il tuo codice non termina.

Tabella Riassuntiva

Fase Valore BeforeAction Valore BubbleEvent utile Scopo Principale
Prima true false per annullare Validare dati, controllare permessi, impedire l'apertura di form o menu.
Dopo false Ininfluente Reagire a modifiche, formattare dati, aggiornare campi dipendenti.