public override async Task OnBeforeAddLineAsync(BeforeAddLineEventArgs e)
{
    IEditEntry editEntryQ = Controls.OfType<IEditEntry>().FirstOrDefault(c => c.Source?.Equals("line|q", StringComparison.InvariantCultureIgnoreCase) ?? false);
    if (!await Dialogs.AnswerYesNo(Page, $"Voulez-vous vraiment ajouter une ligne avec l'article \"{e.EntryArt.TargetSigLabel.Text}\" et Q = {editEntryQ.Text} ?"))
    {
        e.CancelAddLine = true;
    }
}

public override async Task OnAfterAddLineAsync(AfterAddLineEventArgs e)
{
    await Dialogs.Stop(Page, $"La ligne n° {e.Ligne.Table.Rows.Count} a été ajoutée avec succès ! Elle contient l'article \"{e.Ligne["designatio"]}\".");
}
public override async Task OnBeforeDeleteLineAsync(BeforeDeleteLineEventArgs e)
{
	if (!await Dialogs.AnswerYesNo(Page, $"Voulez-vous vraiment supprimer cette ligne {e.Ligne["id_article"]} sur ce picking ?"))
	{
		e.CancelDeleteLine = true;
	}
}

public override async void OnAfterDeleteLine(AfterDeleteLineEventArgs e)
{
	await Dialogs.Stop(Page, $"La ligne a été sumprimée avec succès !");
}

public override async Task OnBeforeChangeLineAsync(BeforeChangeLineEventArgs e)
{
	if (!await Dialogs.AnswerYesNo(Page, $"Voulez-vous vraiment modifier la colonne {e.ColumnToChange} de cette ligne {e.Line["id_article"]} avec cette nouvelle valeur {e.NewValue} ?"))
	{
		e.CancelChangeLine = true;
	}
}