Azioni del controllo
Ad ogni controllo possono essere aggiunte una o più azioni. Le azioni sono visualizzate nell'apposito menù a destra del controllo:
Questi sono di tipi di azione disponibili:
- UpdateData: azione di aggiornamento dei dati del controllo
- SetNavigation: azione di navigazione a un'altra sezione o item
- SetLocalAction: azione per l'esecuzione di codice personalizzato lato server
- SetRemoteAction: azione per l'esecuzione di codice personalizzato lato client
La classe ControlBase mette a disposizione alcuni metodi per aggiungere rapidamente una nuova azione alla lista Actions del controllo.
Questo è un esempio di implementazioni di questi metodi:
public void AddActionSetNavigation(string title, Action.Step currentStep, List<Action.Step> newSteps)
{
this.Actions.Add(new Action()
{
Mode = ActionMode.SetNavigation,
Title = title,
CurrentStep = currentStep,
NewSteps = newSteps != null ? newSteps : new List<Action.Step>(),
Type = ActionType.Navigation
});
}
Azione UpdateData
Il metodo aggiunge un'azione di aggiornamento dei dati nel controllo in modo da non dover ricaricare la pagine se la sorgente dati è stata modificata dopo l'apertura del form. Il codice seguente aggiunge l'opzione di aggiornamento per il controllo predefinito CheckBoxList.
using System;
using System.Threading.Tasks;
namespace DataWeb.Data.Controls
{
public class CheckBoxList : ControlBase
{
public CheckBoxList(Form form, IServiceProvider serviceProvider) : base(form, serviceProvider)
{
}
public override Task InitAsync()
{
AddActionUpdateData();
return Task.CompletedTask;
}
}
}
Va segnalato che tutti i controlli predefiniti che gestiscono liste di valori (CheckBoxList, ListBox, RadioButtonList, DropDownList, ecc.) hanno già impostata questa azione.
Azione SetNavigation
Il metodo aggiunge un'azione che permette all'utente di aprire una sezione o un item rapidamente. Ad esempio, dato un DropDownList con un elenco di categorie, si vuole permettere all'utente di aggiungerne una nuova, modificare quella selezionata o aprire la sezione dedicata.
DataWeb salverà automaticamente i dati dell'item prima di impostare la navigazione. La navigazione viene aggiunta a quella esistente ovvero quando l'utente chiude la categoria viene riportato all'item di partenza rendendo l'esperienza più piacevole.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using DataWeb.Structure;
using DataWeb.Identity;
using DataWeb.Data;
using DataWeb.Data.Controls;
using DataWeb.WebApp.Infrastructure;
using Microsoft.Extensions.Localization;
namespace DataWeb.WebApp.DataWeb.Data.Controls
{
public class Product_CategoryName : DropDownList
{
private readonly CategoryRepository categoryRepository;
private readonly IStringLocalizer localizer;
public Product_CategoryName(Form form, IServiceProvider serviceProvider) : base(form, serviceProvider)
{
categoryRepository = serviceProvider.GetService<CategoryRepository>();
localizer = serviceProvider.GetService<IStringLocalizer>();
}
public override async Task InitAsync()
{
await base.InitAsync();
AddActionSetNavigation(localizer["DataWeb.Form.ControlAction_EditSelected"], new List<Action.Step>()
{
new Action.Step{ IdMaster = StructureDefinition.RootIdMaster, SectionName = AppStructureDefinition.SectionDemoCategories, IsHidden = true },
new Action.Step{ IdMaster = "{ {IdMaster} }", SectionName = AppStructureDefinition.SectionDemoCategoryData }
});
AddActionSetNavigation(localizer["DataWeb.Form.ControlAction_New"], new List<Action.Step>()
{
new Action.Step{ IdMaster = StructureDefinition.RootIdMaster, SectionName = AppStructureDefinition.SectionDemoCategories, IsHidden = true },
new Action.Step{ IdMaster = StructureDefinition.VoidIdMaster, SectionName = AppStructureDefinition.SectionDemoCategoryData }
});
AddActionSetNavigation(localizer["DataWeb.Form.ControlAction_OpenSection"], new List<Action.Step>()
{
new Action.Step{ IdMaster = StructureDefinition.RootIdMaster, SectionName = AppStructureDefinition.SectionDemoCategories }
});
}
}
}
Al metodo deve essere fornito il titolo dell'azione (nell'esempio localizzato con Localizer) e i nuovi step di navigazione. Il parametro opzionale currentStep permette di spostarsi iin una sezione adiacente a quella attuale.
Azione SetLocalAction
Il metodo aggiunge un'azione che permette all'utente di eseguire del codice client posizionato nel componente Vue.js personalizzato.
Ad esempio nel controllo User_AccountNewsletter troviamo l'aggiunta dell'azione locale (client) Edit:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DataWeb.Identity;
using DataWeb.Structure;
using DataWeb.Validation;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
namespace DataWeb.Data.Controls
{
public class User_AccountNewsletter : ControlBase
{
private readonly IStringLocalizer localizer;
public User_AccountNewsletter(Form form, IServiceProvider serviceProvider) : base(form, serviceProvider)
{
localizer = serviceProvider.GetService<IStringLocalizer>();
}
public override Task InitAsync()
{
AddActionSetLocalAction(localizer["DataWeb.Form.AccountNewsletter_Edit"], "Edit", ActionType.Edit);
return Task.CompletedTask;
}
public override Task<List<ValidationError>>ValidateAsync(object value, List<Form.ProvidedValue> providedValues, Dictionary<string, object> sectionData, IUser user, string itemId = null, NavigationContext navigationContext = null)
{
var errors = new List<ValidationError>();
return Task.FromResult(errors);
}
public override Task<bool> IsUpdateDataAsync(object value, List<Form.ProvidedValue> providedValues, Dictionary<string, object> sectionData, IUser user, string itemId = null, NavigationContext navigationContext = null)
{
return Task.FromResult(false);
}
}
}
E nel codice del componente Vue.js intecettiamo la selezione dell'azione Edit:
public startLocalAction(action: any) {
switch (action.name) {
case "Edit":
this.edit();
break;
}
}
Azione SetRemoteAction
Il metodo aggiunge un'azione che verrà eseguita lato server, da un metodo C# dedicato.
Qui ad esempio stiamo impostando un'azione di notifica tramite email:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using DataWeb.Structure;
using DataWeb.Identity;
using DataWeb.Data;
using DataWeb.Data.Controls;
using DataWeb.WebApp.Infrastructure;
using Microsoft.Extensions.Localization;
namespace MyApp.DataWeb.Data.Controls
{
public class Product_ActionListAreaName : ActionList
{
private readonly IStringLocalizer localizer;
private readonly ProductStore productStore;
public Product_ActionListAreaName(Form form, IServiceProvider serviceProvider) : base(form, serviceProvider)
{
localizer = serviceProvider.GetService<IStringLocalizer>();
productStore = serviceProvider.GetService<ProductStore>();
}
public override async Task InitAsync()
{
await base.InitAsync();
AddActionSetRemoteAction("Notify status", "NotifyStatus", ActionType.Notification);
}
public override async Task<ActionResult> SetCustomActionAsync(Action action, IUser user, string itemId = null, NavigationContext navigationContext = null)
{
var result = await base.SetCustomActionAsync(action, user, itemId, navigationContext);
if (!result.IsValid)
{
return result;
}
switch (action.Name)
{
case "NotifyStatus":
result = await NotifyStatus(itemId);
break;
}
return result;
}
public async Task<ActionResult> NotifyStatus(string itemId = null)
{
bool isSuccess = await productStore.SendEmailAsync(itemId);
return new ActionResult { IsValid = isSuccess };
}
}
}
Va segnalato che l'esecuzione di un'azione remota aggiorna sempre il form ricaricando i dati. Inoltre prima di eseguire l'azione, i dati vengono validati e salvati.