Översikt över anpassning och redigering av formulär med redigeringsverktyget för Service Manager
Viktigt
Den här versionen av Service Manager har nått slutet av supporten. Vi rekommenderar att du uppgraderar till Service Manager 2022.
Ett formulär är ett fönster som gör det möjligt för användare att interagera med objekt från databasen. Användare kan använda ett formulär för att visa och redigera egenskaper för objekt. Varje formulär är kopplat till en viss klass, och det visar bara information om instanser i den målklassen. Ett formulär innehåller fält. Vanligtvis är varje fält bundet till en specifik egenskap för formulärets målklass. Incidentformuläret är till exempel kopplat till incidentobjektet. Incidentformuläret visar därför information om incidentobjekt i databasen.
Ett Service Manager formulär består av Windows Presentation Foundation(WPF)-formulärimplementeringen i en Microsoft .NET Framework-sammansättning och en formulärdefinition i ett Service Manager-hanteringspaket. Formulärdefinitionen anger den klass som formuläret representerar, tillsammans med formulärets övriga egenskaper.
Viktiga begrepp om formulär
Det här är en beskrivning av vad du bör veta innan du börjar anpassa formulär.
Hur formulär används
När hanteringspaketet som innehåller formulärdefinitionerna importeras till Service Manager lagras formulärdefinitionerna i databasen. Senare, när användaren initierar en Service Manager-konsolaktivitet som kräver visning av ett objekt, måste Service Manager hitta ett formulär för att visa det begärda objektet. Service Manager öppnar databasen och söker efter ett formulär som har definierats för objektet. Om inget formulär har definierats för objektet söker Service Manager efter ett formulär som har definierats för objektets överordnade objekt. Service Manager fortsätter att söka i hela objektets arvshierarki tills den hittar ett definierat formulär.
Allmänna formulär
Om Service Manager inte kan hitta något formulär för objektet eller för något av dess överordnade objekt, skapar Service Manager dynamiskt ett allmänt standardformulär för objektet. Det allmänna formuläret är ett systemgenererat formulär som räcker för enkel formuläranvändning. Det är ett snabbt och enkelt sätt att skapa ett formulär för objekt som saknar formulärdefinitioner.
Som standard visar det allmänna formuläret alla egenskaper för formuläret i en enkel layout som du inte kan ändra. Det allmänna formuläret visar egenskaperna för alla överordnade objekt i arvshierarkin i formuläret och du kan inte ändra det beteendet. Det går att göra vissa anpassningar av ett allmänt formulär, Du kan till exempel ange de egenskaper som du vill att det allmänna formuläret ska visa. Det allmänna formuläret kan dock inte användas som grund för anpassning. Om du senare definierar ett anpassat formulär för objektet skriver ditt anpassade formulär över objektets allmänna formulär.
Information om hur du döljer egenskaper i ett allmänt format och andra sätt som du kan anpassa ett allmänt formulär på finns i blogginlägget Översikt över formulärinfrastrukturen och det allmänna formuläret.
Kombinationsklasser i formulär
Ibland behöver man kunna visa information från flera klasser i ett formulär. Det gör du genom att skapa en kombinationsklass och sedan binda ett fält i formuläret till kombinationsklassen. Mer information om kombinationsklasser finns i Ändringar i System Center Common Schema.
Funktionella aspekter av ett formulär
Ett formulär har följande funktioner:
Initiering
Storlek och plats
Uppdatera
Skicka ändringar
Funktionerna beskrivs i avsnitten nedan.
Initiering
Under initieringen parsas ett formulärs XAML (Extensible Application Markup Language) och alla kontroller i formuläret instansieras och läses in. Formulärets inlästa händelse anger när formuläret och alla inneslutna element har lästs in. Datainläsningsåtgärder är asynkrona. Därför är målinstansen kanske inte tillgänglig när händelsen Loaded aktiveras . I stället måste händelsen DataContextChanged användas för meddelanden när målinstansen har angetts för formuläret. Händelsen PropertyChanged för egenskapen DataContext kan användas i stället för händelsen DataContextChanged .
Vi rekommenderar att du använder händelsen Inläst för kontrollrelaterad anpassad initiering och sedan använder händelserna DataContextChanged eller PropertyChanged i egenskapen DataContext för anpassad instansrelaterad initiering.
Storlek och plats
När ett formulär visas i ett popup-fönster bestäms dess ursprungliga storlek baserat på formulärets egenskaper Width, Height, MinWidth och MinHeight . Om dessa egenskaper inte anges för formuläret beräknas formulärets ursprungliga storlek baserat på dess innehåll.
Vi rekommenderar att du gör följande inställningar för egenskaperna:
Ange bredd- ochhöjdegenskaperna för formuläret för att uttryckligen ange den ideala storleken. Överväg att ange de här egenskaperna till värdet Automatiskt . Då beräknas formulärets bredd och höjd efter innehållet.
Ange egenskaperna MinWidth och MinHeight för formuläret för att ange det minsta fönstret som accepteras för formuläret. Om användaren sedan gör fönstret mindre än vad som specificerats här, visas rullningslister i formulärfönstret.
När formuläret finns i Service Manager formulärvärd bevaras den senast använda storleken och platsen för efterföljande visning av formuläret av samma användare i samma körningssession.
Uppdatera
Målinstansen av ett formulär kan ändras till följd av att kommandot Uppdatera körs i formuläret. Hanteraren för detta kommando hämtar nya data ur databasen. När data tas emot anges formulärets egenskapsvärde För DataContext till den nya målinstansen och händelsen DataContextChanged aktiveras .
Om du vill skilja mellan den DataContextChanged-händelse som skapades när formuläret först lästes in och händelsen som skapades för att hantera ett Uppdateringskommando , kontrollerar du egenskapen OldValue för de händelseargument som skickas med händelsen. Egenskapen har ett nollvärde om formuläret bara har initierats.
Skicka ändringar
Popup-fönstret formulärvärd i Service Manager innehåller knappar för att skicka in ändringar som görs i formuläret och för att stänga popup-fönstret.
När en användare väljer knappen Tillämpa för ett formulär skickas formulärets målinstans för lagring. Den här åtgärden är synkron. Användaren kan därför inte redigera formuläret förrän sändningsåtgärden har slutförts. Ett felmeddelande visas om åtgärden inte kan slutföras. Formuläret är då fortfarande öppet och ändringar kan göras. Användarna bör verkställa sina ändringar ofta, så att de inte hamnar i konflikt med andra instanser av formuläret som kanske redigeras samtidigt.
Om användaren väljer knappen OK liknar beteendet Tillämpa, förutom att formuläret och dess värdfönster stängs om åtgärden för att skicka formulär lyckas.
Om användaren väljer knappen Avbryt visas en dialogruta där användaren uppmanas att bekräfta åtgärden. Användaren kan välja Ja och förlora ändringar eller välja Nej och återgå till formuläret.
Allmänna riktlinjer och metodtips för formulär
Du kan utöka funktionerna i Service Manager genom att lägga till eller ändra formulär. I det här avsnittet beskrivs några rekommenderade rekommendationer för att skapa och använda Service Manager formulär, med hjälp av olika verktyg och skriptformulärdefinitioner direkt.
Det här avsnittet riktar sig främst till partner och kunder som har erfarenhet av att skapa egna anpassade formulär med hjälp av Windows Presentation Foundation (WPF) och Microsoft Visual Studio Team System eller Microsoft Expression Blend.
Nedan beskrivs de generella riktlinjerna för redigering av ett nytt formulär.
- Använd standardkontroller.
- Följ de generella riktlinjerna för formulärdesign.
- Undvik bakomliggande kod.
- Inkludera undantagshantering.
- Överväg om formulären ska anpassas och uppgraderas.
- Namnge alla anpassningsbara kontroller.
- Bind formuläret till datakällor.
- Använd Service Manager formulär för verifiering av infrastruktur, värdekonverterare och felmallar.
- Använd formulärinfrastrukturskommandon och händelser.
Information om dessa riktlinjer finns i följande avsnitt.
Använda standardkontroller
Följande kontroller kan användas i ett formulär:
- Standardkontroller. Här ingår .NET-bibliotekskontroller, till exempel kombinationsrutor och listrutor.
- Anpassade kontroller. Det omfattar ytterligare kontroller som skapats av formulärförfattaren eller av en tredje part.
Tips
Om du använder standardkontroller så långt möjligt och undviker att skapa anpassade kontroller, främjar du också en enhetlig användarupplevelse av formulären. Om du måste skapa en anpassad kontroll ska du separera det visuella utseendet och beteendet från det logiska beteendet genom att använda kontrollmallar när du definierar kontrollens utseende. Företrädesvis bör det finnas en separat kontrollmall för varje Windows-tema.
Följ allmänna riktlinjer för formulärdesign
När du utformar ett formulär använder du riktlinjer för offentlig design för att säkerställa att formuläret är användarvänligt och att det följer vanliga användarinteraktionsparadigm.
Mer information om allmän Windows-design finns i Interaktionsriktlinjer för Användarupplevelse i Windows.
Dessutom gäller följande:
- Dela upp informationen på flera flikar så att formuläret blir lättare att läsa. Ta med den vanligaste informationen på den första fliken och information av mindre betydelse på efterföljande flikar.
- Använd layoutpaneler när du placerar kontrollerna på formuläret. Detta säkerställer att formuläret fungerar korrekt när det ändras och lokaliseras.
- Undvik att ställa in visuella egenskaper för enstaka kontroller. Använd stilar istället. Detta gör det möjligt för dig att ändra utseendet på alla kontroller i en serie formulär genom att ändra formatet, och det främjar ett konsekvent utseende över relaterade formulär.
Undvik bakomliggande kod
Bakomliggande kod är en term som beskriver koden som är kopplad till markeringsdefinierade objekt när en XAML-sida kompileras. Begränsa användningen av bakomliggande kod i ett formulär så mycket som möjligt. Det är bättre att bädda in koden för ett formulär i själva kontrollen, eftersom det senare är enklare att ändra koden. Använd i stället de deklarativa funktioner som stöds av infrastrukturen för Service Manager formulär för att definiera värdekonverteringar och valideringsregler i formuläret.
Som en allmän riktlinje bör du begränsa användningen av bakomliggande kod till situationer där det inte går att tillhandahålla de nödvändiga funktionerna med hjälp av deklarativa funktioner i XAML, med klasser som definierats i WPF och formulärinfrastrukturbiblioteket. Överväg även att flytta funktionerna som implementeras i bakomliggande kod till ett hjälpbibliotek och sedan referera till den från XAML.
Inkludera undantagshantering
Kontrollera att koden i formuläret innehåller undantagshantering så att formuläret kan läsas in både under designfasen i redigeringsverktyget och i Service Manager-konsolen vid körning.
Överväg anpassning och uppgraderingar av formulär
När du utformar ett nytt formulär bör du överväga framtida anpassningar och uppgraderingar av formuläret. För att säkerställa att det är möjligt att anpassa och uppgradera ett formulär samtidigt som anpassningar bevaras följer du riktlinjerna och tipsen som angavs tidigare i det här avsnittet, tillsammans med följande riktlinjer:
Överväg framtida anpassningar och uppgraderingar tidigt medan du utformar formuläret. Formulär kommer sannolikt att utvecklas i framtida versioner och det är viktigt att tänka på hur användarna kommer att kunna uppgradera till nya versioner av formuläret samtidigt som de bevarar sina anpassningar till det ursprungliga formuläret. Ibland kanske du vill erbjuda ett uppdaterat formulär trots att användarna redan har gjort omfattande anpassningar av det ursprungliga formuläret. Användarna förväntar sig att deras anpassningar ska överleva versionsuppgraderingen.
Ange ett unikt namn för varje kontroll i formuläret så att det blir möjligt att tillämpa anpassningarna på kontrollerna. Formuläranpassningar lagras som en uppsättning åtgärder som riktas mot en specifik kontroll eller uppsättning kontroller. Målkontrollen refereras till med namn, vilket är anledningen till att det är viktigt att bevara kontrollnamn mellan versioner av formuläret. Om en kontroll inte har något namn genererar Editor ett namn, men det genererade namnet bevaras inte i olika versioner av formuläret.
Kontrollera att kontrollnamnen förblir oföränderliga i olika versioner av formuläret. Då kan du också vara säker på att anpassningarna för en viss kontroll i en tidigare version kan tillämpas på samma kontroll i en ny version av formuläret.
Om möjligt bör du undvika att flytta kontroller till en annan plats på samma flik när du uppgraderar ett formulär. En vanlig användaranpassning består i att flytta kontroller på formuläret till en annan plats. Om du ändrar platsen för en kontroll i en ny version av formuläret finns det en risk att den nya kontrollplatsen överlappar en kontroll som användaren har flyttat.
Undvik om möjligt att flytta kontroller mellan flikar när du utformar en uppdatering av ett befintligt formulär. Kontroller identifieras både efter namn och på fliken där de finns. Om du flyttar en kontroll från en flik till en annan i den nya versionen av formuläret, kan anpassningar som användaren har gjort på den kontrollen förstöras, eftersom anpassningarna inte kan identifiera målkontrollen.
När uppdateringen av ett formulär innehåller nya kontroller bör du överväga att lägga till de nya kontrollerna på en ny flik. Det är det säkraste sättet att undvika att störa eventuella användaranpassningar av befintliga flikar och kontroller.
Var noggrann med bindningen för kontrollerna. Skrivskyddade kontroller bör endast använda enkelriktade bindningar.
Namnge alla anpassningsbara kontroller
Säkerställ att kontrollnamnen beskriver vilka data som kontrollen är bunden till, eller beskriv vad kontrollen gör.
Binda formuläret till datakällor
Huvudsyftet med ett formulär är att visualisera ett enskilt objekt från den Service Manager databasen. Det här objektet kallas för en målinstans som alltid anges av egenskapen DataContext för ett formulär (som ärvs från klassen FrameworkElement ).
Viktigt
Ändra inte formulärets DataContext-egenskap . Värdmiljön för formulären använder den här egenskapen för att identifiera formulärets målinstans.
I Service Manager-datamodellen representeras en målinstans som ett BindableDataItem-objekt. Den här klassen aggregerar det underliggande SDK-objektet (Software Development Kit) och exponerar dess egenskaper via en indexerare, som tar ett egenskapsnamn som en parameter.
Klassen BindableDataItem implementerar också ICustomTypeDescriptor, vilket gör det möjligt att använda klassen BindableDataItem som datakälla för WPF-bindning. Följande är ett exempel på bindning av en målinstansegenskap till egenskapen Text för en TextBox-kontroll :
<TextBox Name="textBoxDescription" Text="{Binding Path=Summary}"/>
Det är inte nödvändigt att ange källan för bindningen eftersom målinstanserna anges som DataContext för formuläret, som fungerar som standardkälla för alla kontroller i formuläret.
Kontroller i formuläret kan bindas till andra datakällor än målinstansen, och formulärinfrastrukturbiblioteket innehåller många kontroller som utför bindningen implicit. Kontrollen för inställning av instans är till exempel bunden till datakällan, vilket innebär att det finns en samling med instanser att välja mellan. Det går också att definiera ytterligare datakällor deklarativt med hjälp av klasserna ObjectDataProvider och XmlDataProvider .
Formulärinfrastrukturen betraktar målinstansen som den enda skrivskyddade datakällan i formuläret. Därför lagrar implementeringen av kommandot Submit endast de ändringar som görs i målinstansen. Övriga datakällor för formuläret behandlas som skrivskyddade.
Använda Service Manager formulär för verifiering av infrastrukturregler, värdekonverterare och felmallar
Vi rekommenderar att du använder valideringsregler för formulärinfrastruktur i formulär för att ange indata som inte är giltiga. WPF-bindningsinfrastrukturen stöder validering av kontrollegenskaper som är bundna till en datakälla med antingen enkelriktade eller tvåvägsbindningar. Bindningsobjektet har en ValidationRules-samling som kan innehålla valfritt antal ValidationRule-objekt . När data skickas från kontrollen till datakällan anropas ValidationRule-objekten för att verifiera värdet.
Formulärinfrastrukturbiblioteket innehåller många valideringsregler som hanterar de vanligaste fallen. Formulärinfrastrukturen utnyttjar valideringsreglerna för att avgöra huruvida formulärinnehållet kan skickas för lagring. Ett formulärs skicka-knapp kan till exempel inaktiveras om det finns en kontroll som har ett verifieringsfel i formuläret.
Vi rekommenderar att du använder den anpassade felmallen som finns i formulärinfrastrukturbiblioteket. Om en kontroll har ett valideringsfel visas den som standard med en röd omgivande kant. WPF gör det möjligt att definiera en anpassad felindikator via egenskapen Validation.ErrorTemplate , som kan anges för alla kontroller. Infrastrukturbiblioteket Service Manager formulär innehåller en anpassad felmall som visar en felikon i stället för den röda WPF-kantlinjen. Dessutom visas en knappbeskrivning tillsammans med ett felmeddelande när en användare pekar med musen på felikonen. Felmeddelandet ska ange skälet till att data i kontrollen inte godkändes vid valideringen.
I följande exempel visas hur du refererar till felmallen i XAML:
<TextBox Text="{Binding SomeProperty}"
scwpf:Validation.ValueRequired="True"
Validation.ErrorTemplate="{DynamicResource {ComponentResourceKey {x:Type scwpf:Validation}, InvalidDataErrorTemplate}}"/>
Om inbyggda valideringsregler inte tillhandahåller den valideringslogik som krävs rekommenderar vi att du skapar anpassade verifieringsregler som representerar den logiken. Det gör det möjligt för standardenlig och anpassad valideringslogik att samexistera med den gemensamma hanteringsmekanismen för validering.
Om mekanismen för valideringsregler inte är tillräcklig för ett visst scenario bör du i stället hantera FormEvents.PreviewSubmitEvent och köra valideringen därifrån.
I följande kodexempel visas ett exempel på mönstret som du kan använda när du kör en anpassad validering:
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
}
Använda kommandon och händelser för formulärinfrastruktur
Formulärinfrastrukturen exponerar många kommandon som kan köras i ett formulär. Dessa kommandon omfattar:
FormsCommand.Submit, som sparar målinstansen av formuläret.
FormsCommand.SubmitAndClose, som sparar målinstansen av formuläret och stänger formuläret.
FormsCommand.Refresh, som upprepar frågan för målinstansen av formuläret.
FormCommands.Cancel, som tar bort alla ändringar och stänger formuläret.
Varje enskilt kommando omges av händelser, som aktiveras före och efter att kommandot körs.
Före kommandot aktiveras följande händelser:
Händelsen FormEvents.PreviewSubmit utlöses före kommandot FormCommand.Submit och händelsen FormEvents.Submitted utlöses efter kommandot FormCommand.Submit .
Händelsen FormEvents.PreviewRefresh aktiveras före kommandot FormCommands.Refresh och kommandot FormCommand.Refreshed aktiveras efter kommandot FormCommand.Submit .
Händelsen FormEvents.PreviewCancel aktiveras före kommandot FormCommands.Cancel och händelsen FormCommand.Canceled aktiveras efter kommandot FormCommand.Cancel .
Förhandsgranskningshändelserna skickas med ett PreviewFormCommandEventArgs-objekt . Det här objektet innehåller en föränderlig Cancel-egenskap som förhindrar att motsvarande kommando körs när egenskapen är inställd på true.
Postkommandohändelserna skickar ett FormCommandExecutedEventArgs-objekt . Det här objektet innehåller en result-egenskap som anger om körningen av kommandot lyckades, avbröts eller orsakade ett fel. Om det uppstår ett fel refererar egenskapen Error för objektet FormCommandExecutedEventArgs till undantaget som innehåller information om felet.
Du kan aktivera, inaktivera och köra formulärkommandon både programmatiskt och deklarativt.
Om du vill aktivera formulärkommandon programmatiskt upprättar du ett CommandBinding mellan formuläret och det relaterade kommandot.
I följande exempel upprättas en kommandobindning mellan formuläret och ett uppdateringskommando , och två hanterare definieras för det här kommandot. Den första hanteraren returnerar om kommandot Uppdatera kan köras eller inte, och den andra hanteraren innehåller faktiskt implementeringen av kommandot Uppdatera :
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
}
}
Du kan också definiera hanterare för formulärkommandon deklarativt. Du kan göra detta genom att använda ett regelobjekt som använder en RoutedCommandTrigger. I följande kodexempel visas hur hanterare definieras deklarativt:
<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>