Condividi tramite


Moduli: Indicazioni generali e procedure consigliate

 

Data di pubblicazione: luglio 2016

Si applica a: System Center 2012 SP1 - Service Manager, System Center 2012 R2 Service Manager, System Center 2012 - Service Manager

È possibile estendere le funzionalità di System Center 2012 - Service Manager aggiungendo o modificando i moduli. In questo argomento vengono forniti alcuni consigli sulle migliori procedure da seguire per la creazione e l'utilizzo dei moduli in Service Manager , con l'impiego diretto di vari strumenti e definizioni di script per i moduli.

Questo argomento è indirizzato prevalentemente ai partner e ai clienti esperti nella creazione di propri moduli personalizzati mediante Windows Presentation Foundation (WPF) e Microsoft Visual Studio Team System o Microsoft Expression Blend.

Di seguito sono riportate le linee guida generali per la creazione e la modifica di un nuovo modulo.

  • Utilizzare i controlli standard.

  • Seguire le indicazioni generali per la progettazione del modulo.

  • Evitare i code-behind.

  • Includere la gestione delle eccezioni.

  • Considerare la personalizzazione e gli aggiornamenti dei moduli.

  • Nominare tutti i controlli personalizzabili.

  • Associare il modulo a origini dati.

  • Utilizzare in Service Manager regole di convalida per l'infrastruttura dei moduli, convertitori di valore e modelli di errore.

  • Utilizzare i comandi ed eventi dell'infrastruttura dei moduli.

Per informazioni su queste linee guida, vedere le sezioni riportate di seguito.

Utilizzare i controlli standard

I controlli utilizzati in un modulo possono essere come segue:

  • Controlli standard. Sono inclusi i controlli di libreria .NET, come caselle combinate e caselle di riepilogo.

  • Controlli personalizzati. Sono inclusi i controlli aggiuntivi che vengono creati dall'autore del modulo o da terzi.

System_CAPS_ICON_tip.jpg Suggerimento


Quando si utilizzano controlli standard, evitare se possibile la creazione di controlli personalizzati, al fine di promuovere la coerenza nell'esperienza utente con i moduli. Qualora fosse necessario creare un controllo personalizzato, separare l'aspetto visivo, il comportamento e il comportamento logico utilizzando i modelli di controllo per definire l'aspetto del controllo. Preferibilmente, dovrebbe esserci un modello di controllo separato per ogni tema di Windows.

Seguire le indicazioni generali per la progettazione del modulo

Quando si progetta un modulo, utilizzare le linee guida pubbliche di progettazione al fine di creare un modulo semplice e intuitivo e che aderisca ai comuni paradigmi di interazione dell'utente.

Per ulteriori informazioni sulla progettazione generale in Windows, vedere Windows User Experience Interaction Guidelines (Linee guide sull'interazione per l'esperienza utente in Windows).

Inoltre:

  • Suddividere le informazioni in più schede per rendere il modulo più semplice e più facile da leggere. Includere nella prima scheda le informazioni utilizzate più di frequente e nelle schede successive le informazioni di minore importanza.

  • Utilizzare i pannelli di layout per disporre controlli nel modulo. In questo modo si è certi che il modulo si comporti correttamente quando viene ridimensionato e localizzato.

  • Evitare di impostare singole proprietà visive del controllo e utilizzare invece gli stili. Ciò permette di modificare l'aspetto di tutti i controlli in una serie di moduli modificandone lo stile e quindi di promuovere un aspetto coerente in tutti i moduli correlati.

Evitare i code-behind

Il termineCode-behind descrive il codice collegato agli oggetti definiti da commenti quando una pagina XAML viene compilata con i commenti. Limitare il più possibile l'utilizzo di code-behind in un modulo. È preferibile incorporare il codice del modulo nel controllo stesso, in modo da poterlo modificare con facilità successivamente. Utilizzare invece funzionalità dichiarative che siano supportate dall'infrastruttura dei moduli in Service Manager per definire nel modulo le conversioni di valori e le regole di convalida.

Come indicazione generale, limitare l'utilizzo di code-behind nelle situazioni in cui non è possibile fornire la funzionalità richiesta utilizzando le funzionalità dichiarative di XAML, con classi definite in WPF e nella libreria dell'infrastruttura dei moduli. Anche in questo caso, si consiglia di spostare in una libreria helper la funzionalità implementata nel code-behind, quindi di farvi riferimento da XAML.

Includere la gestione delle eccezioni

Assicurarsi che il codice presente nel modulo contenga la gestione delle eccezioni. Ciò permette di caricare il modulo sia durante la fase di progettazione nello Strumento di creazione che nella fase di esecuzione nella Console di Service Manager .

Considerare la personalizzazione e gli aggiornamenti dei moduli

Quando si progetta un nuovo modulo, è necessario considerare le personalizzazioni e gli aggiornamenti futuri di tale modulo. Per essere certi che sia possibile personalizzare e aggiornare un modulo preservando le personalizzazioni, seguire le linee guida e i suggerimenti forniti nella sezione precedente, nonché le indicazioni riportate di seguito:

  • Considerare già all'inizio della progettazione del modulo le personalizzazioni e gli aggiornamenti futuri. È probabile che i moduli si evolvano in future versioni e pertanto è importante considerare come gli utenti saranno in grado di aggiornare le nuove versioni del modulo, pur preservando le proprie personalizzazioni del modulo originale. Ad esempio, è possibile fornire un modulo aggiornato dopo che gli utenti hanno già investito molto tempo nella personalizzazione del modulo originale. Gli utenti si aspettano che le personalizzazioni vengano conservate con l'aggiornamento della versione.

  • Specificare un nome univoco per ogni controllo del modulo in modo da consentire di applicare le personalizzazioni ai controlli. Le personalizzazioni dei moduli vengono archiviate come una serie di azioni destinate a un controllo specifico o a un insieme di controlli. Il controllo di destinazione viene referenziato per nome, perciò è importante conservare i nomi dei controlli in tutte le versioni del modulo. Se il controllo non ha un nome, l'Editor personalizzazione moduli ne genera uno, ma il nome generato non verrà preservato in tutte le diverse versioni del modulo.

  • Accertarsi che i nomi dei controlli restino immutati nelle diverse versioni del modulo. In questo modo si garantisce che le personalizzazioni di un determinato controllo in una precedente versione possano essere applicate allo stesso controllo in una nuova versione del modulo.

  • Se possibile, quando si aggiorna un modulo, evitare di spostare i controlli in una posizione diversa nella stessa scheda. Una personalizzazione frequente applicata dagli utenti è lo spostamento in una posizione diversa dei controlli nel modulo. Se in una nuova versione del modulo si cambia la posizione di un controllo, c'è il rischio che la posizione del nuovo controllo si sovrapponga con un controllo riposizionato dall'utente.

  • Se possibile, evitare di spostare i controlli tra le schede durante la progettazione di un aggiornamento di un modulo esistente. I controlli sono identificati sia dal nome che dalla scheda in cui si trovano. Lo spostamento di un controllo da una scheda a un'altra in una nuova versione del modulo può interrompere le personalizzazioni applicate dall'utente a tale controllo in quanto le personalizzazioni non saranno in grado di identificare il controllo di destinazione.

  • Quando l'aggiornamento di un modulo include nuovi controlli, è possibile aggiungere nuovi controlli per una nuova scheda. Questo è il metodo più sicuro per evitare interferenze tra le eventuali personalizzazioni dell'utente e le schede e i controlli esistenti.

  • Tenere presente le associazioni dei controlli. I controlli di sola lettura devono utilizzare solo associazioni unidirezionali.

Nominare tutti i controlli personalizzabili

Assicurarsi che i nomi dei controlli descrivano i dati ai quali è associato il controllo o l'azione eseguita da tale controllo.

Associare il modulo a origini dati

Lo scopo principale di un modulo è di visualizzare un singolo oggetto dal database di Service Manager . L'oggetto viene detto target instanceed è sempre specificato dalla proprietà DataContext di un modulo (che viene ereditata dalla classe FrameworkElement ).

System_CAPS_ICON_important.jpg Importante


Non modificare la proprietà del modulo DataContext . L'ambiente che ospita i moduli utilizza questa proprietà per identificare l'istanza di destinazione del modulo.

Nel modello di dati di Service Manager , un'istanza di destinazione è rappresentata come un oggetto BindableDataItem . Questa classe aggrega l'oggetto SDK sottostante e ne espone le proprietà tramite un indicizzatore, che assume un nome di proprietà come parametro.

La classe BindableDataItem implementa anche ICustomTypeDescriptor, che consente di utilizzare la classe BindableDataItem come origine dati per l'associazione WPF. Di seguito è riportato un esempio di associazione di una proprietà dell'istanza di destinazione alla proprietà Text di un controllo TextBox :

  
<TextBox Name="textBoxDescription" Text="{Binding Path=Summary}"/>  
  

Non è necessario specificare l' Source dell'associazione poiché le istanze di destinazione sono impostate come DataContext del modulo, che serve come Source predefinita per tutti i controlli presenti nel modulo.

I controlli presenti nel modulo possono essere associati a origini dati diverse dall'istanza di destinazione e la libreria dell'infrastruttura dei moduli contiene un numero di controlli che esegue implicitamente l'associazione. Ad esempio, il controllo di selezione istanza è associato all'origine dati, che fornisce l'insieme di istanze da scegliere. Inoltre, è possibile definire in modo dichiarativo origini dati aggiuntive utilizzando le classi ObjectDataProvider e XmlDataProvider .

L'infrastruttura dei moduli considera l'istanza di destinazione come l'unica origine dati di lettura/scrittura nel modulo. Pertanto, con l'implementazione del comando Submit verranno archiviate solo le modifiche effettuate all'istanza di destinazione. Le altre origini dati del modulo vengono considerate come di sola lettura.

Utilizzare regole di convalida per l'infrastruttura dei moduli, convertitori di valore e modelli di errore di Service Manager

Si consiglia di utilizzare le regole di convalida dell'infrastruttura nei moduli per designare gli input di dati non validi. L'infrastruttura di associazione WPF supporta la convalida per le proprietà del controllo associate a un'origine dati con associazioni unidirezionali o bidirezionali. L'oggetto di associazione ha una raccolta di ValidationRules che può contenere un numero qualsiasi di oggetti ValidationRule . Ogni volta che i dati vengono inseriti dal controllo nell'origine dati, gli oggetti ValidationRule vengono richiamati per convalidare il valore.

La libreria dell'infrastruttura dei moduli contiene un numero di regole di convalida che gestiscono i casi più comuni. L'infrastruttura dei moduli sfrutta le regole di convalida per determinare se sia possibile inviare il contenuto del modulo per l'archiviazione. Ad esempio, un pulsante Invia di un modulo può essere disattivato se un controllo presenta un errore di convalida nel modulo.

Si consiglia di utilizzare il modello di errore personalizzato che viene fornito con la libreria dell'infrastruttura dei moduli. Se un controllo presenta un errore di convalida, esso viene visualizzato con un bordo rosso per impostazione predefinita. WPF permette di definire un indicatore di errore personalizzato tramite la proprietà Validation.ErrorTemplate , la quale può essere impostata per qualsiasi controllo. La libreria dell'infrastruttura dei moduli in Service Manager contiene un modello di errore personalizzato nel quale è visualizzata un'icona di errore anziché il bordo rosso di WPF. Inoltre, quando si posiziona il mouse sull'icona di errore, viene visualizzata una descrizione del comando con un messaggio di errore. Il messaggio di errore dovrebbe indicare il motivo per cui non è riuscita la convalida dei dati nel controllo.

Nell'esempio riportato di seguito viene illustrato come fare riferimento al modello di errore nel codice XAML:

  
<TextBox Text="{Binding SomeProperty}"  
         scwpf:Validation.ValueRequired="True"   
         Validation.ErrorTemplate="{DynamicResource {ComponentResourceKey {x:Type scwpf:Validation}, InvalidDataErrorTemplate}}"/>  
  

Se le regole di convalida incorporate non forniscono la logica di convalida richiesta, si consiglia di creare regole di convalida personalizzate per rappresentare tale logica. Ciò consentirà alla logica di convalida standard e personalizzata di coesistere all'interno del meccanismo comune di gestione della convalida.

Se il meccanismo delle regole di convalida non è adatto a un particolare scenario, si consiglia di gestire FormEvents.PreviewSubmitEvent e di eseguire la convalida da qui.

Nell'esempio di codice riportato di seguito viene fornito un esempio di modello che è possibile utilizzare per eseguire la convalida personalizzata:

  
void MyForm_Loaded(object sender, RoutedEventArgs e)  
{  
    // hook to handle form events  
    this.AddHandler(  
        FormEvents.PreviewSubmitEvent,  
        new EventHandler<PreviewFormCommandEventArgs>(this.OnPreviewSubmit));  
}  
private void OnPreviewSubmit(object sender, PreviewFormCommandEventArgs e)  
{  
    string errorMessage;  
    bool result = this.DoVerify(out errorMessage);  
    if (!result)  
    {  
        // cancel Submit operation  
        e.Cancel = true;  
        // display error message  
        MessageBox.Show(errorMessage);  
    }  
}  
internal bool DoVerify(out string errorMessage)  
{  
    // Do custom verification and return true to indicate that  
    // validation check has passed; otherwise return false and  
    // populate errorMessage argument  
}  
  

Utilizzare comandi ed eventi dell'infrastruttura dei moduli

L'infrastruttura dei moduli espone un numero di comandi eseguibili in un modulo. Tra questi comandi vi sono:

  • FormsCommand.Submit, che consente di salvare l'istanza di destinazione del modulo.

  • FormsCommand.SubmitAndClose, che consente di salvare l'istanza di destinazione del modulo e chiude il modulo.

  • FormsCommand.Refresh, che ripete la query per l'istanza di destinazione del modulo.

  • FormCommands.Cancel, che elimina tutte le modifiche e chiude il modulo.

Ciascuno di questi comandi è racchiuso tra eventi che vengono generati prima e dopo l'esecuzione del comando.

Prima del comando, vengono generati i seguenti eventi:

  • L'evento FormEvents.PreviewSubmit viene generato prima del comando FormCommand.Submit , mentre l'evento FormEvents.Submitted viene generato dopo il comando FormCommand.Submit .

  • L'evento FormEvents.PreviewRefresh viene generato prima del comando FormCommands.Refresh , mentre il comando FormCommand.Refreshed viene generato dopo il comando FormCommand.Submit .

  • L'evento FormEvents.PreviewCancel viene generato prima del comando FormCommands.Cancel , mentre l'evento FormCommand.Canceled viene generato dopo il comando FormCommand.Cancel .

Gli eventi di anteprima consentono di passare un oggetto PreviewFormCommandEventArgs . L'oggetto contiene una proprietà mutevole Cancel che impedisce l'esecuzione del comando corrispondente quando la proprietà è impostata su true.

Gli eventi post-comando passano un oggetto FormCommandExecutedEventArgs . Questo oggetto contiene una proprietà Result che indica se l'esecuzione del comando è avvenuta, è stata annullata o ha causato un errore. In caso di errore, la proprietà Error dell'oggetto FormCommandExecutedEventArgs farà riferimento all'eccezione che fornisce informazioni sull'errore.

È possibile attivare, disattivare ed eseguire i comandi del modulo sia a livello di programmazione che in modo dichiarativo.

Per attivare i comandi di un modulo a livello di codice, stabilire una CommandBinding tra il modulo e il comando correlato.

Nell'esempio riportato di seguito viene instaurata un'associazione del comando tra il modulo e un comando Refresh e vengono definiti due gestori per questo comando. Il primo gestore restituisce l'indicazione se il comando Refresh possa essere o meno eseguito, mentre il secondo gestore contiene effettivamente l'implementazione del comando Refresh :

  
    public class MyForm : UserControl  
    {  
        public MyForm()  
        {  
            // do standard initialization  
            // establish CommandBinding for Refresh command  
            this.CommandBindings.Add(  
                new CommandBinding(FormCommands.Refresh, this.ExecuteRefresh, this.CanExecuteRefresh));  
        }  
        private void CanExecuteRefresh(  
              object sender,  
              CanExecuteRoutedEventArgs e)  
        {  
            // put your logic that determines whether Refresh   
// can be executed here  
            bool canExecute = true;  
            BindableDataItem dataItem = this.DataContext as BindableDataItem;  
            if (dataItem)  
            {  
                canExecute = dataItem["Status"] != "New";  
            }  
            e.CanExecute = canExecute;  
        }  
        private void ExecuteRefresh(  
            object sender,  
            ExecutedRoutedEventArgs e)  
        {  
            // here is placeholder for the code that has do be   
// executed upon running Refresh command  
        }  
    }  
  

È inoltre possibile definire in modo dichiarativo i gestori per i comandi del modulo. A questo scopo, è necessario distribuire un oggetto Regola che utilizzi un RoutedCommandTrigger. Nell'esempio di codice riportato di seguito viene illustrato come definire i gestori in modo dichiarativo:

  
    <scwpf:BusinessLogic.Rules>  
        <scwpf:RuleCollection>  
            <scwpf:Rule>  
                <scwpf:Rule.Triggers>  
                    <scwpf:RoutedCommandTrigger   
RoutedCommand="{x:Static scwpf:FormCommands.Refresh}"/>  
                </scwpf:Rule.Triggers>  
                <scwpf:Rule.Conditions>  
                    <scwpf:PropertyMatchCondition   
                        Binding="{Binding Status}"   
                        Value="New"   
                        Operation="NotEquals" />  
                </scwpf:Rule.Conditions>  
                <!-- Use RuleAction objects to define the logic that executed   
                upon running Refresh command; this can be left empty -->  
            </scwpf:Rule>  
        </scwpf:RuleCollection>  
    </scwpf:BusinessLogic.Rules>  
  

Vedere anche

Sito Web di Windows Presentation Foundation (WPF) (WindowsClient.NET)
Moduli: Personalizzazione e creazione