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:
- 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. - 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. |