Vous consultez une page technique concernant le logiciel de gestion Mercator. Celle-ci contient des informations spécifiques destinées aux professionnels de Mercator. Souhaitez-vous être redirigés vers des informations plus générales ?


   Ne plus poser cette question

Considérations relatives à la mise en place de boîtes de dialogue par code

0000003483     -      12/11/2026

Comme Mercator desktop, MercatorPelican met à disposition des développeurs diverses boîtes de dialogue : "Oui-Non", "OK-Annuler", saisie d'une ou deux chaînes de caractères, sélection d'un représentant, … Toutefois, l'environnement de MercatorPelican (Blazor hybride) est très différent de celui de Mercator Desktop (WinForms). En conséquence, les boîtes de dialogue de MercatorUi.Dialogs ne peuvent pas être utilisées. Blazor repose essentiellement sur une programmation asynchrone, alors qu'en WinForms, les boîtes de dialogue bloquent simplement le thread de l'interface utilisateur. De plus, les boîtes de dialogue de MercatorUi.Dialogs sont appelées par des méthodes statiques, alors que Blazor dépend toujours d'un contexte local. (En mode "web", le même AppDomain héberge l'interface de plusieurs utilisateurs simultanés). Toutefois, le cas particulier du code dans des customizers de Mercator a été pris en compte par l'équipe de développement, afin que le code de ces customizers puisse demeurer inchangé.

Programmation de boîtes de dialogue dans un ToolKit 

Les boîtes de dialogue de Mercator peuvent être appelées via les méthodes async du BlazorDialogsHelper. Celui-ci est attaché au MainLayout, qui fournit le contexte local évoqué ci-dessus.

Quelques exemples de code :

Zoom
if (await CascadingParameters.MainLayout.BlazorDialogsHelper.AnswerYesNoAsync(Api.Iif_langue(CascadingParameters.Langue, IifLangueEnum.SaveChanges)))
{

Zoom
string newCustId = await CascadingParameters.MainLayout.BlazorDialogsHelper.AskTargetSigAsync(Api.Iif_langue(CascadingParameters.Langue, "Which customer ?", "Welke klant ?", "Quel client ?"), MercatorUi.Sig._SigEnum.CLI, null);
			

 

Les méthodes disponibles sont celles de cette interface, disponible dans MercatorUi.Dialogs :

Zoom
public interface IBlazorDialogsHelper
{
    Task StopAsync(string message);
    Task<bool> AnswerYesNoAsync(string message);
    Task<bool> AnswerOkCancelAsync(string message);
    Task<int> AnswerYesNoCancelAsync(string message);
    Task<int> Answer3ButtonsAsync(string message, string button1, string button2, string button3);
    Task<double?> AskDoubleAsync(string message, double defaultValue, string mask, double minValue = double.MinValue, double maxValue = double.MaxValue, bool withTouchKeyBoard = false);
    Task<string> AskStringAsync(string message, string defaultValue, bool upperCase = false, int maxLength = int.MaxValue, bool nullIfCancel = false, bool isPassword = false, bool isEmail = false);
    Task<string[]> AskStringsAsync(string message, string defaultValue1, string defaultValue2, bool upperCase = false, int maxLength = 0);
    Task<double[]> AskDoublesAsync(string message, double defaultValue1, double defaultValue2, string mask, double minValue = double.MinValue, double maxValue = double.MaxValue);
    Task<string> AskMemoAsync(string message, string defaultValue, bool hideCancelButton = false, bool allowReadWriteWhenCancelButtonHidden = false);
    Task<DateTime?> AskDateTimeAsync(string message, DateTime defaultValue, bool withTime = false);
    Task<string> AskTargetSigAsync(string message, Sig._SigEnum module, string targetFilter = null);
    Task<_Dialogs.DialogAskComboRet> AskUserAsync(string message, bool withAll = false, string defaultValue = null);
    Task<_Dialogs.DialogAskComboRet> AskDepotAsync(string message, string defaultId = null, bool withAll = false, bool withAllActive = false);
    Task<_Dialogs.DialogAskComboRet[]> AskUsersAsync(string message, bool withAll = false, string defaultValue1 = null, string defaultValue2 = null);
    Task<_Dialogs.DialogAskComboRet[]> AskDepotsAsync(string message, string defaultId1 = null, string defaultId2 = null, bool withAll = false);
    Task<_Dialogs.DialogAskComboRet[]> AskDepotMplaceAsync(string message, string defaultIdDepot, string defaultIdMplace = null, bool disableDepot = false, string reqSqlMplace = null);
    Task<_Dialogs.DialogAskComboRet[]> AskRepsAsync(string message, bool withAll = false);
    Task<_Dialogs.DialogAskComboRet[]> AskExercicesAsync(string message);
    Task<_Dialogs.DialogAskComboRet> AskRepAsync(string message, bool withAll = false);
    Task<_Dialogs.DialogAskPieceRet> AskPieceAsync(string message, _Dialogs.AskPieceEnum typeDoc, int[] types, int defaultType, bool allowTypeChange = true, bool hidePiece = false, string whereSequenc = null, bool withOriginals = false);
    Task<_Dialogs.DialogAskComboRet> AskComboAsync(string message, List<(string id, string lib)> items, string defaultId = null, int width = 0);
    Task<_Dialogs.DialogAskComboRet> AskExerciceAsync(string message, byte defaultExercice = 0);
    Task<MercatorApi.ApiLangues?> AskLangueAsync(string message);
    Task<(int tiroir, string lib)?> AskTirAsync(bool withAll = false, bool withTiroirsLib = false); // null = aucun tiroir trouvé ou erreur / tiroir -1 = annulé / -9 = Tous (somme) / -8 = Tous (détails)
}

 

Programmation de boîtes de dialogue dans les customizers

Afin que le code d'un customizer puisse être identique pour Mercator desktop et MercatorPelican, un mécanisme spécifique doit être mis en place autour de tous les appels de méthodes des engines de Mercator, susceptibles d'appeler un code personnalisé, lequel peut contenir du code montrant des boîtes de dialogue.

Zoom
bool isSaved = false;
await CascadingParameters.MainLayout.ExecuteInMercatorAsync(() => isSaved = currentBillingEngine.Save());
if (!isSaved)
{
    error = string.IsNullOrEmpty(currentBillingEngine.LastError) ? Api.Iif_langue(CascadingParameters.Langue, "Der Verkauf konnte nicht gespeichert werden.", "Unable to save the sale.", "Verkoop kan niet worden opgeslagen.", "Impossible d'enregistrer la vente.") : currentBillingEngine.LastError;
    return;
}

La méthode ExecuteInMercatorAsync crée un contexte local et permet d'exécuter une méthode synchrone depuis un contexte asynchrone.

Une fois un appel d'une méthode d'un engine de Mercator (ici BillingEngine.Save) "encadré" de cette façon, les boîtes de dialogue de MercatorUi.Dialogs deviennent tout simplement utilisables.

💡 Dans les ToolKits standards fournis par Mercator, ce principe est toujours appliqué.

Ci-dessous, un exemple de customizer qui fonctionnera parfaitement en Mercator desktop et en MercatorPelican, si la précaution évoquée ici est prise en compte.

Zoom
namespace Billing
{
    public class Customizer : MercatorUi.ICustomizers.IBillingEngineCreated, MercatorUi.ICustomizers.IBillingEngineClosed
    {

        public void BillingEngineCreated(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.BeforeBeforePaymentOrSave += billingEngine_BeforeBeforePaymentOrSave;
        }

        public void BillingEngineClosed(MercatorUi.Engine.Gescom.BillingEngine billingEngine)
        {
            billingEngine.BeforeBeforePaymentOrSave -= billingEngine_BeforeBeforePaymentOrSave;
        }

        void billingEngine_BeforeBeforePaymentOrSave(object sender, MercatorUi.Engine.Gescom.BillingEngine.BeforeBeforePaymentOrSaveEventArgs e)
        {
            MercatorUi.Engine.Gescom.BillingEngine billingEngine = (MercatorUi.Engine.Gescom.BillingEngine)sender;
            if (!billingEngine.LignesVRecords.Any(l => l.ID_ARTICLE == "PORT"))
            {
                int n = MercatorUi.Dialogs.AnswerYesNoCancel("Voulez-vous ajouter des frais de port ?");
                if (n == 3) // Cancel
                {
                    e.Cancel = true;
                    return;
                }
                if (n == 1) // Yes
                {
                    double port = MercatorUi.Dialogs.AskDouble("Montant frais de port ?", 10, "### ##0.00", true);
                    if (port == double.MinValue) // Cancel 
                    {
                        e.Cancel = true;
                        return;
                    }
                    int nLigne = billingEngine.AppendLine();
                    if (!billingEngine.InsertItem("PORT", billingEngine.LIGNES.Rows[nLigne], 1))
                    {
                        MercatorUi.Dialogs.Stop("Impossible d'ajouter les frais de port. " + billingEngine.LastError);
                        e.Cancel = true;
                        return;
                    }
                    billingEngine.LignesVRecords[nLigne].PU = port;
                    billingEngine.UpdateAmounts();
                }
            }
        }
    }
}

⚠️ Si en MercatorPelican sous Windows, un boîte de dialogue WinForms est quand même affichée, il faut considérer que son équivalent Blazor n'existe pas. Cette boîte de dialogue ne peut dès lors pas être utilisée. Elle ne s'affichera pas correctement sous Windows et provoquera une exception dans les autres plateformes.



Cookies fonctionnels : Cookies nécessaires à l'utilisation du site et cookies de préférence. Ils ne contiennent aucune donnée à caractère personnel. (En savoir plus)

Cookies statistiques : Captation de statistiques liées aux comportements des internautes. (En savoir plus)

Cookies marketing : Pour effectuer le suivi des visiteurs au travers des sites web, à des fins publicitaires. (En savoir plus)