Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
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 egenskaperna för objekt. Varje formulär är kopplat till en specifik klass och visar endast information för instanser av 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. Därför visar incidentformuläret information om incidentobjekt i databasen.
Ett Service Manager-formulär består av WPF-formulärimplementeringen (Windows Presentation Foundation) 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 andra egenskaper.
Viktiga begrepp om formulär
Innan du anpassar formulär bör du känna till följande formulärbegrepp.
Användning av formulär
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-konsoluppgift 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 det 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 standardformulär allmänt för objektet. Det generiska formuläret är ett systemgenererat formulär som räcker för enkel formuläranvändning. Det allmänna formuläret representerar ett snabbt och enkelt sätt att skapa ett formulär för objekt utan några 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. Anpassningar till det allmänna formuläret är begränsade. 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 du ett formulär för att visa information som härleds från mer än en klass. För att göra detta skapar du en kombinationsklass och binder sedan 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 funktionella aspekter:
Initialisering
Storlek och plats
Uppdatera
Skicka ändringar
Dessa aspekter beskrivs i följande avsnitt.
Initialisering
Under initieringen parsas ett formulärs XAML (Extensible Application Markup Language) och alla kontroller i formuläret instansieras och läses in. Formulärets händelse Inläst anger när formuläret och de inneslutna elementen har lästs in. Datainläsningsåtgärder är asynkrona. Därför kanske målinstansen inte är tillgänglig när händelsen Inläst utlöses. I stället måste händelsen DataContextChanged användas för meddelande 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 på egenskapen DataContext för målinstansrelaterad anpassad 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, MinWidthoch MinHeight. Om de här egenskaperna inte har angetts för formuläret beräknas formulärets ursprungliga storlek baserat på dess innehåll.
Vi rekommenderar att du anger följande egenskaper:
Ange egenskaperna Width och Height i formuläret för att uttryckligen ange den ideala storleken. Överväg att ställa in dessa egenskaper på värdet Auto. Detta anger formulärets bredd och höjd baserat på innehållets storlek.
Ange egenskaperna MinWidth och MinHeight för formuläret för att ange det minsta fönster som är acceptabelt för formuläret. Om en användare ändrar storlek på fönstret till en mindre storlek än vad som anges visas rullningslister för rullning till det dolda formulärinnehållet.
När formuläret finns i Service Manager-formulärvärd bevaras den senast använda storleken och platsen vid efterföljande visningar av formuläret av samma användare inom samma körsession.
Uppdatera
Målinstansen av ett formulär kan ändras till följd av att ett Uppdatera-kommando körs i formuläret. Hanteraren för det här kommandot hämtar nya data från databasen. När data tas emot anges formulärets DataContext- egenskapsvärde till den nya målinstansen och händelsen DataContextChanged genereras.
Om du vill skilja mellan DataContextChanged händelse som uppstod när formuläret först lästes in och händelsen som skapades för att hantera ett Uppdatera-kommando, kontrollerar du egenskapen OldValue för de händelseargument som skickas med händelsen. Den här egenskapen är "null" om formuläret just har initierats.
Skicka ändringar
Popup-fönstret för formulärhantering i Service Manager innehåller knappar för att skicka ändringar som görs i formuläret och för att stänga det.
När en användare väljer knappen Använd för ett formulär skickas formulärets målinstans för lagring. Den här åtgärden är synkron. Därför kan användaren inte redigera formuläret förrän sändningsåtgärden har slutförts. Om det uppstår ett fel under formuläröverföringen visas ett felmeddelande. Formuläret förblir öppet för ytterligare ändringar. Vi rekommenderar att användarna använder sina ändringar ofta för att undvika kollisioner om en annan instans av formuläret redigeras samtidigt.
Om användaren väljer knappen OK liknar beteendet Använd, förutom att formuläret och värdfönstret stängs om åtgärden för att skicka formuläret 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.
De allmänna riktlinjerna för att skapa ett nytt formulär är följande.
- Använd standardkontroller.
- Följ allmänna riktlinjer för formulärdesign.
- Undvik att använda code-behind.
- Inkludera undantagshantering.
- Överväg att anpassa och uppgradera formulär.
- Namnge alla anpassningsbara kontroller.
- Binda formuläret till datakällor.
- Använd Service Manager-formulärens verifieringsregler för infrastruktur, värdekonverterare och felmallar.
- Använd formulärinfrastrukturkommandon och -händelser.
Information om dessa riktlinjer finns i följande avsnitt.
Använda standardkontroller
Kontroller som används i ett formulär kan vara:
- Standardkontroller. Detta inkluderar .NET-bibliotekskontroller, till exempel kombinationsruta och listruta.
- Anpassade kontroller. Detta inkluderar ytterligare kontroller som skapas av formulärförfattaren eller av en tredje part.
Tips
När du använder standardkontroller där det är möjligt och undviker att skapa anpassade kontroller främjar du konsekvens när det gäller formulärens användarupplevelse. Om du måste skapa en anpassad kontroll separerar du det visuella utseendet och beteendet och det logiska beteendet med hjälp av kontrollmallar för att definiera kontrollens utseende. Helst 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 Riktlinjer för interaktion med Windows-användare.
Ytterligare:
- Dela upp information mellan flera flikar för att göra formuläret enklare och enklare 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 för att lägga ut kontroller i formuläret. Detta säkerställer att formuläret fungerar korrekt när det storleksändras och lokaliseras.
- Undvik att ange visuella egenskaper för enskilda kontroller och använd formatmallar i stä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 mellan relaterade formulär.
Undvik bakomliggande kod
Code-behind är en term som beskriver koden som är kopplad till markup-definierade 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 du bäddar in koden för ett formulär i själva kontrollen, eftersom det senare är lättare att ändra koden. Använd i stället de deklarativa funktioner som stöds av Service Manager-formulärinfrastrukturen för att definiera värdekonverteringar och verifieringsregler i formuläret.
Som en allmän riktlinje bör du begränsa användningen av code-behind 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 definieras av WPF och formulärinfrastrukturbiblioteket. Även då kan du överväga att flytta de funktioner som implementeras i code-behind 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 till 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 när du utformar formuläret. Formulär kommer sannolikt att utvecklas i framtida versioner och det är viktigt att tänka på hur användarna kan uppgradera till nya versioner av formuläret samtidigt som de bevarar sina anpassningar till det ursprungliga formuläret. Du kan till exempel ange ett uppdaterat formulär när användarna redan har investerat mycket i att anpassa ditt ursprungliga formulär. 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 anpassningar kan tillämpas på kontroller. Formuläranpassningar lagras som en uppsättning åtgärder som är riktade mot en specifik kontroll eller en 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 Redigeraren för formuläranpassning 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. Detta säkerställer att anpassningar för en viss kontroll i en tidigare version kan tillämpas på samma kontroll i en ny version av formuläret.
Undvik om möjligt att flytta kontroller till en annan plats på samma flik när du uppgraderar ett formulär. En vanlig användaranpassning är att flytta kontroller i 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 med namn och på fliken där de finns. Om du flyttar en kontroll från en flik till en annan i en ny version av formuläret kan anpassningar som användaren gör till den kontrollen brytas, eftersom anpassningarna inte identifierar 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 till befintliga flikar och kontroller.
Tänk på hur kontroller är bundna. Skrivskyddade kontroller bör endast använda enkelriktade bindningar.
Namnge alla anpassningsbara kontroller
Kontrollera 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 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).
Viktig
Ändra inte formulärets egenskap DataContext. Formulärens värdmiljö använder den här egenskapen för att identifiera formulärmålinstansen.
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 även 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å hur du binder 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 Source för bindningen eftersom målinstanserna anges som DataContext- i formuläret, som fungerar som standard Source 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. Till exempel är instansväljarens kontroll bunden till datakällan, vilket ger den samling instanser som ska väljas. Det går också att definiera ytterligare datakällor deklarativt med hjälp av ObjectDataProvider och XmlDataProvider klasser.
Formulärinfrastrukturen betraktar målinstansen som den enda läs- och skrivbara datakällan i formuläret. Därför lagrar implementeringen av kommandot Submit endast de ändringar som görs i målinstansen. Andra datakällor för formuläret behandlas som endast läsbara.
Använda Service Manager-formulär för verifieringsregler för infrastruktur, värdekonverterare och felmallar
Vi rekommenderar att du använder verifieringsregler för formulärinfrastruktur i formulär för att ange dataindata som inte är giltiga. WPF-bindningsinfrastrukturen stöder validering av kontrollegenskaper som är bundna till en datakälla med antingen enkelriktade eller dubbelriktade bindningar. 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- objekt för att verifiera värdet.
Formulärinfrastrukturbiblioteket innehåller många valideringsregler som hanterar de vanligaste fallen. Formulärinfrastrukturen använder valideringsreglerna för att avgöra om formulärinnehållet kan skickas för lagring. Ett formulärs knappen Skicka 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 tillhandahålls med formulärinfrastrukturbiblioteket. Om en kontroll har ett verifieringsfel visas den som standard med en röd kantlinje runt sig. WPF gör det möjligt att definiera en anpassad felindikator via egenskapen Validation.ErrorTemplate, som kan ställas in på valfri kontroll. Infrastrukturbiblioteket för Service Manager-formulär innehåller en anpassad felmall som visar en felikon i stället för den röda WPF-kantlinjen. Dessutom, när en muspekare pekar på felikonen, visas ett verktygstips med ett felmeddelande. Felmeddelandet bör ange orsaken till att data i kontrollen misslyckades med 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. Detta gör det möjligt för standard- och anpassad valideringslogik att samexistera inom den gemensamma mekanismen för valideringshantering.
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.
Följande kodexempel innehåller ett exempel på det mönster som du kan använda för att köra 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 formulärets målinstans.
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.
Vart och ett av dessa kommandon är hakparenteserade efter händelser som utlöses före och efter att kommandot körs.
Före kommandot utlöses följande händelser:
Händelsen FormEvents.PreviewSubmit utlöses innan kommandot FormCommand.Submit, och händelsen FormEvents.Submitted utlöses efter kommandot FormCommand.Submit.
Händelsen FormEvents.PreviewRefresh utlöses innan kommandot FormCommands.Refresh och kommandot FormCommand.Refreshed genereras efter kommandot FormCommand.Submit.
Händelsen FormEvents.PreviewCancel utlöses innan kommandot FormCommands.Cancel och händelsen FormCommand.Canceled utlöses efter kommandot FormCommand.Cancel.
Förhandsgranskningshändelserna förmedlar ett PreviewFormCommandEventArgs-objekt. Det här objektet innehåller en föränderlig egenskap Avbryt som förhindrar att motsvarande kommando körs när egenskapen är inställd på true.
Händelserna efter kommandot skickar ett FormCommandExecutedEventArgs-objekt. Det här objektet innehåller egenskapen Result som anger om körningen av kommandot lyckades, avbröts eller orsakade ett fel. I händelse av ett fel refererar Fel egenskapen för FormCommandExecutedEventArgs-objektet 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 gör du det genom att upprätta en CommandBinding- mellan formuläret och det relaterade kommandot.
I det följande exemplet upprättas en kommandobindning mellan formuläret och kommandot Uppdatera , och två hanterare definieras för det här kommandot. Den första hanteraren returnerar om kommandot Refresh 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 Rule-objekt som använder ett RoutedCommandTrigger-. I följande kodexempel visas hur du definierar hanterare 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>