Personalizzazione di un controllo

I controlli possono essere personalizzati sia lato server con una classe derivata da ControlBase sia lato client con un componente Vue.js.
Non è necessario applicare le due personalizzazioni in contemporanea, anzi, nella maggior parte dei casi, la personalizzazione della class è più che sufficiente per ottenere il compotamento desiderato.
 
Classe controllo personalizzata
Per avere una classe personalizzata, crea un nuova classe C# nel progetto.
Normalmente il file viene posizionato in Areas/DataWeb/Infrastructure/Data/Form/Controls creando una cartella con il nome dell'item (ad esempio Product).
Il nome della classe è prefissato con il nome dell'item più "_" più in nome del controllo (ad esempio: Product_Code).
 
Class path
 
Per una migliore organizzazione del codice, la classe può utilizzare il namespace [NamespaceProgetto].DataWeb.Data.Controls.
La classe può derivare direttamente da ControlBase o più comodamente da un controllo predefinito come TextBox.
In questo modo la quantità di codice da scrivere sarà ulteriormente ridotta lasciando al controllo predefinito gran parte della personalizzazione.
Ecco un esempio di classe personalizzata di un TextBox per validare l'univocità di un codice prodotto.
 
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.Validation;
using DataWeb.WebApp.Infrastructure;

namespace MyApp.DataWeb.Data.Controls
{
    public class Product_Code :  TextBox
    {
        private readonly ProductStore productRepository;

        public Product_Code(Form form, IServiceProvider serviceProvider) : base(form, serviceProvider)
        {
            productRepository = serviceProvider.GetService<ProductStore>();
        }

        public override async Task<List<ValidationError>>ValidateAsync(object value, List<Form.ProvidedValue> providedValues, Dictionary<string, object> sectionData, IUser user, string itemId = null, NavigationContext navigationContext = null)
        {
            var errors = await base.ValidateAsync(value, providedValues, sectionData, user, itemId, navigationContext);

            var products = await productRepository.GetProductsAsync(new ProductStore.Filter { PublishMode = PublishMode.Management }, "en-US");
            if (products.Any(x => x.Code.Equals(Convert.ToString(value), StringComparison.OrdinalIgnoreCase) && x.IdMaster != itemId))
            {
                errors.Add(new ValidationError { Name = "Code", Message = "Code already exists" });
            }

            return errors;
        }
    }
}
 
L'ultimo passaggio richiede l'aggiornamento del form in DataWeb per segnalare al controllo di utilizzare questa classe personalizzata.
Il valore inserito deve essere il namespace più "." più il nome della classe. In questo caso: MyApp.DataWeb.Data.Controls.Product_Code.
 
Form custom class
 
Componente controllo personalizzato
Per personalizzare l'ergonomia di un controllo è possibile creare un componente Vue.js che verrà agganciato al controllo in fase di rendering del form. In questo caso il componente va posizionato in Areas/DataWeb/Scripts/Components/Controls.
Il nome del componente è il nome dell'item più "_" più il nome del controllo.
Il componente può infine essere associato al controllo nel campo Control component name dove deve essere inserito il nome del tag di riferimento (quindi non il nome del file ma il tag associato durante la configurazione di Vue.js). Possono inoltre essere aggiunti dei parametri per utilizzare lo stesso componento con diverse configurazioni.
 
Form custom component