使用 Service Manager Authoring Tool 來自訂和撰寫表單的總覽Overview of customizing and authoring forms with the Service Manager Authoring Tool

重要

此版本的 Service Manager 已達到終止支援,建議您 升級至 Service Manager 2019This version of Service Manager has reached the end of support, we recommend you to upgrade to Service Manager 2019.

表單是讓使用者能與來自資料庫之物件互動的視窗。A form is a window that makes it possible for users to interact with objects from the database. 使用者可使用表單來檢視和編輯物件的內容。Users can use a form to view and edit the properties of objects. 每個表單都與特定的類別連結,它只會顯示目標類別之執行個體的資訊。Each form is tied to a specific class, and it displays information only for instances of the targeted class. 表單包含多個欄位。A form contains fields. 一般而言,每個欄位都會系結至表單之目標類別的特定屬性。Typically, each field is bound to a specific property of the form's targeted class. 例如,事件表單與事件物件繫結。The incident form, for example, is tied to the incident object. 因此,事件表單會顯示資料庫中事件物件的相關資訊。Therefore, the incident form displays information about incident objects in the database.

Service Manager 表單是由 ( ) Microsoft .net Framework 元件中的 Windows Presentation Foundation WPF 表單執行   ,以及 Service Manager 管理元件中的表單定義所組成。A Service Manager form consists of the Windows Presentation Foundation (WPF) form implementation in a Microsoft .NET Framework assembly and a form definition in a Service Manager management pack. 表單定義可指定表單呈現的類別,以及表單的其他內容。The form definition specifies the class that the form represents, along with the other properties of the form.

關於表單的重要概念Key concepts about forms

在自訂表單之前,您應該要熟悉下列表單概念。Before customizing forms, you should be familiar with the following form concepts.

表單的使用方式How forms are used

將包含表單定義的管理元件匯入 Service Manager 時,表單定義會儲存在資料庫中。When the management pack that contains the form definitions is imported into Service Manager, the form definitions are stored in the database. 之後,當使用者啟動需要顯示物件的 Service Manager 主控台工作時,Service Manager 必須尋找表單來顯示要求的物件。Later, when the user initiates a Service Manager console task that requires the display of an object, Service Manager must find a form to display the requested object. Service Manager 存取資料庫,並搜尋已針對該物件定義的表單。Service Manager accesses the database and searches for a form that has been defined for that object. 如果未定義物件的表單,Service Manager 會搜尋針對物件之父物件定義的表單。If no form is defined for the object, Service Manager searches for a form that is defined for the object's parent object. Service Manager 會繼續搜尋整個物件的繼承階層,直到找到定義的表單為止。Service Manager continues to search the entire object's inheritance hierarchy until it finds a defined form.

一般表單Generic forms

如果 Service Manager 找不到物件或其父物件的任何表單,Service Manager 會以動態方式為該物件建立預設的 一般格式If Service Manager cannot find any form for the object or for any of its parent objects, Service Manager dynamically builds a default generic form for that object. 一般表單是系統 - 產生的表單,足以供簡單的表單使用。The generic form is a system-generated form that is sufficient for simple form use. 一般表單代表在不使用表單定義的情況下建立物件之表單的快速、簡易方法。The generic form represents a quick and easy way to create a form for objects without any form definitions.

依預設,一般表單會以簡單但無法變更的版面配置顯示所有表單內容。By default, the generic form displays all the properties of the form in a simple layout that you cannot change. 一般表單會在表單的繼承階層中顯示所有父物件的內容,且您無法變更該行為。The generic form displays the properties of all the parent objects in the inheritance hierarchy of the form, and you cannot change that behavior. 一般表單的自訂是有限的。Customizations to the generic form are limited. 例如,您可以指定要一般表單顯示的內容,不過無法將一般表單當作自訂的基礎。For example, you can specify the properties that you want the generic form to display; however, the generic form cannot be used as a basis for customization. 如果您之後定義該物件的自訂表單,您的自訂表單會覆寫物件的一般格式。If you later define a custom form for that object, your custom form overwrites the object's generic form.

如需隱藏一般表單之內容,以及一般表單之其他自訂方法的相關資訊,請參閱部落格文章 Overview of the Forms Infrastructure and the Generic Form (表單基礎結構和一般表單概觀)For information about hiding properties in a generic form and other ways that you can customize a generic form, see the blog post Overview of the Forms Infrastructure and the Generic Form.

表單中的組合類別Combination classes in forms

在某些情況下,您需要表單顯示由多個類別衍生而來的資訊。Sometimes, you need a form to display information that is derived from more than one class. 若要這樣做,您需要建立「 組合類別 」,然後再使表單中的欄位與組合類別繫結。To do this, you create a combination class and then bind a field on the form to the combination class. 如需組合類別的詳細資訊,請參閱 System Center 一般架構的變更For more information about combination classes, see Changes to the System Center Common Schema.

表單的功能層面Functional aspects of a form

表單的功能層面可分為以下幾種:A form has the following functional aspects:

  1. 初始化Initialization

  2. 大小和位置Size and location

  3. 重新整理Refresh

  4. 提交變更Submit changes

以下小節含有這些層面的描述。These aspects are described in the following sections.

初始化Initialization

在初始化期間,會剖析表單的 Extensible Application Markup Language ( XAML ) ,並將表單上的所有控制項具現化並載入。During initialization, a form's Extensible Application Markup Language (XAML) is parsed and all controls on the form are instantiated and loaded. 表單的 載入 事件會指出表單和所有包含的元素載入的時間。The form's Loaded event indicates when the form and all contained elements have been loaded. 資料 - 載入作業是非同步。Data-loading operations are asynchronous. 因此當 Loaded 事件發生時,目標執行個體可能會無法使用。Therefore, the target instance may not be available when the Loaded event is raised. 反之,如果表單的目標執行個體已設定,必須使用 DataContextChanged 事件來進行通知。Instead, the DataContextChanged event must be used for notification when the target instance is set for the form. PropertyChanged 內容的 DataContext 事件可用來取代 DataContextChanged 事件。The PropertyChanged event for the DataContext property can be used in place of the DataContextChanged event.

我們建議您將載入的事件用於控制項 - 相關的自訂初始化,然後針對目標實例相關的自訂初始化,在DataCoNtext屬性上使用 >datacoNtextchangedPropertyChanged事件 - 。We recommend that you use the Loaded event for control-related custom initialization and then use the DataContextChanged or PropertyChanged events on the DataContext property for target instance-related custom initialization.

大小和位置Size and location

當表單顯示在快顯視窗中時 - ,它的初始大小是根據表單的 WidthHeightMinWidthMinHeight 屬性來決定。When a form is displayed in a pop-up window, its initial size is determined based on the form's Width, Height, MinWidth, and MinHeight properties. 如果未針對表單設定這些屬性,則會根據表單的內容計算表單的初始大小。If these properties are not set for the form, the form's initial size is calculated based on its content.

我們建議您依照下文所述的方式設定這些內容:We recommend that you set these properties as follows:

  • 設定表單的 WidthHeight 等內容,以明確地指定適當大小。Set the Width and Height properties of the form to explicitly specify the ideal size. 請考慮將上述內容設定為 Auto 值。Consider setting these properties to the Auto value. 如此能根據內容的大小設定表單的寬度和高度。This sets the width and height of the form based on the size of the content.

  • 設定表單的 MinWidthMinHeight 等內容,以指定可接收的最小表單視窗。Set the MinWidth and MinHeight properties of the form to specify the smallest window acceptable for the form. 如果使用者將視窗大小調整為比指定值還小,畫面中會出現捲軸以供捲動至隱藏的表單內容。If a user resizes the window to a smaller size than specified, scrollbars appear for scrolling to the hidden form content.

當表單裝載于 Service Manager forms 主機內時, - 會保留上次使用的大小和位置,以供同一位使用者在相同的執行會話內後續顯示該表單。When the form is hosted inside the Service Manager forms host, the last-used size and location is preserved for subsequent display of that form by the same user within the same run session.

重新整理Refresh

表單的目標執行個體可能會由於您針對表單執行 Refresh 命令而變更。The target instance of a form can change as a result of executing a Refresh command on the form. 此命令的處理常式會從資料庫擷取新資料。The handler for this command fetches new data from the database. 當資料抵達時,表單的 DataCoNtext 屬性值會設定為新的目標實例,並引發 >datacoNtextchanged 事件。When the data arrives, the form's DataContext property value is set to the new target instance and the DataContextChanged event is raised.

若要區分首次載入表單時產生的 DataContextChanged 事件和為了處理 Refresh 命令而產生的事件,請查看隨事件傳入之事件引數的 OldValue 內容。To differentiate between the DataContextChanged event that was raised when the form was first loaded and the event that was raised to handle a Refresh command, check the OldValue property of the event arguments that are passed in with the event. 對於剛初始化的表單,此內容會是 Null。This property is null if the form has just been initialized.

提交變更Submit changes

Service Manager 中的表單主機彈出 - 視窗會提供按鈕來提交表單中所做的變更,以及關閉彈出 - 視窗。The form host pop-up window in Service Manager provides buttons for submitting changes that are made in the form and for closing the pop-up window.

當使用者按一下表單 的 [套用 ] 按鈕時,會提交表單的目標實例以供儲存之用。When a user clicks the Apply button for a form, the form's target instance is submitted for storage. 這項作業是同步的,因此使用者必須等到提交作業完成後才能編輯表單。This operation is synchronous; therefore, the user cannot edit the form until the submission operation is complete. 如果在表單提交期間發生失敗,錯誤訊息會出現。If failure occurs during the form submission, an error message appears. 此時表單將維持開啟狀態,以便您做出進一步的變更。The form remains open for further changes. 我們建議使用者經常套用變更,以避免因其他使用者同時編輯表單的其他執行個體而發生衝突。We recommend that users apply their changes frequently to avoid collisions if another instance of the form is being edited at the same time.

當使用者按一下 [ 確定 ] 時,如果表單提交作業成功,表單和主機視窗將會關閉;除此之外,其他行為與 [ 套用] 相似。If the user clicks the OK button, the behavior is similar to Apply, except that, if the form submission operation is successful, the form and its host window are closed.

當使用者按一下 [ 取消 ] 按鈕時,對話方塊會出現並要求使用者確認該項作業。If the user clicks the Cancel button, a dialog box appears that asks the user to confirm the operation. 使用者能按一下 [ ] 以放棄變更,或按一下 [ ] 以返回表單。The user can click Yes and lose changes, or click No and return to the form.

表單的一般指導方針和最佳作法General guidelines and best practices for forms

您可以藉由新增或修改表單來擴充 Service Manager 的功能。You can extend features of Service Manager by adding or modifying forms. 本主題說明使用各種工具和腳本表單定義,建立和使用 Service Manager 表單的最佳作法建議。This topic describes some best practice recommendations for creating and using Service Manager forms, using various tools and scripting form definitions directly.

本主題主要適用物件是合作夥伴和客戶,這些合作夥伴和客戶在使用 Windows Presentation Foundation ( WPF ) 和 microsoft Visual   Studio Team System 或 microsoft Expression Blend 建立自己的自訂表單時,都有豐富的目標。This topic is primarily targeted at partners and customers who are experienced in building their own custom forms by using Windows Presentation Foundation (WPF) and Microsoft Visual Studio Team System or Microsoft Expression Blend.

撰寫新表單的一般指導方針如下:The general guidelines for authoring a new form are as follows.

  • 使用標準控制項。Use standard controls.
  • 遵循一般表單設計指導方針。Follow general form design guidelines.
  • 避免程式碼 - 後置於。Avoid code-behind.
  • 包含例外狀況處理。Include exception handling.
  • 考量表單自訂與升級。Consider forms customization and upgrades.
  • 命名所有可自訂控制項。Name all customizable controls.
  • 將表單繫結至資料來源。Bind the form to data sources.
  • 使用 Service Manager 表單基礎結構驗證規則、值轉換器和錯誤範本。Use Service Manager forms infrastructure validation rules, value convertors, and error templates.
  • 使用表單基礎結構命令和事件。Use forms infrastructure commands and events.

如需這些指導方針的詳細資訊,請參閱下列各節。For information about these guidelines, see the following sections.

使用標準控制項Use standard controls

表單上使用的控制項可以是:Controls that are used on a form can be:

  • 標準控制項Standard controls. 這包括 .NET 程式庫控制項,例如下拉式方塊和清單方塊。This includes .NET library controls, such as combo box and list box.
  • 自訂控制項Custom controls. 這包括表單作者或協力廠商建立的其他控制項。This includes additional controls that are created by the form author or by a third party.

提示

在可能的情況下使用標準控制項並避免建立自訂控制項,即可提升與表單使用體驗相關的一致性。When you use standard controls wherever possible and avoid creating custom controls, you promote consistency with regard to the user experience of forms. 如果您必須建立自訂控制項,請使用控制項範本定義控制項的外觀,將視覺外觀與行為以及邏輯行為分開。If you must create a custom control, separate the visual appearance and behavior and the logical behavior by using control templates to define the appearance of the control. 最好是每個 Windows 佈景主題都有個別的控制項範本。Preferably, there should be a separate control template for each Windows Theme.

遵循一般表單設計指導方針Follow general form design guidelines

當您設計表單時,請使用公開的設計指導方針,以確保表單可供使用者使用,且符合一般使用者 - 互動範例。When you design a form, use public design guidelines to ensure that the form is user friendly and that it adheres to common user-interaction paradigms.

如需一般 Windows 設計的詳細資訊,請參閱 Windows User Experience Interaction Guidelines (Windows 使用者經驗指導方針)For more information about general Windows design, see Windows User Experience Interaction Guidelines.

此外:In addition:

  • 在多個實驗室之間分割資訊,讓表單變得更簡單也更方便閱讀。Divide information across multiple tabs to make the form simpler and easier to read. 請將最常用的資訊包含在第一個索引標籤中,並將較不重要的資訊放在後面的索引標籤上。Include the most commonly used information on the first tab and information of lesser importance on subsequent tabs.
  • 使用版面配置面板來編排表單上的控制項。Use layout panels to lay out controls on the form. 這可確保表單在調整大小與當地語系化時會有正確的行為表現。This ensures that the form behaves correctly when it is resized and localized.
  • 避免設定個別控制項視覺內容,並改用樣式。Avoid setting individual control visual properties, and use styles instead. 如此,您便可透過修改樣式來變更一系列表單中所有控制項的外觀,並讓相關的表單具有更一致的外觀。This makes it possible for you to change the appearance of all controls across a series of forms by modifying the style, and it promotes a consistent appearance across related forms.

避免程式碼後端Avoid code-behind

程式代碼 - 後向是一個詞彙,其描述 - 當 XAML 頁面進行標記編譯時,與標記定義物件聯結的程式碼。Code-behind is a term that describes the code that is joined with markup-defined objects when an XAML page is markup compiled. 盡可能限制在 - 表單中使用程式碼後後方。Limit the use of code-behind in a form as much as possible. 最理想的作法是將表單的程式碼內嵌在控制項本身,因為後續變更該程式碼的工作會變得較容易。It is preferable that you embed the code for a form in the control itself, because later it is easier to change that code. 相反地,請使用 Service Manager forms 基礎結構支援的宣告功能,在表單中定義值轉換和驗證規則。Instead, use the declarative capabilities that are supported by the Service Manager forms infrastructure to define value conversions and validation rules in the form.

一般來說,您應該將程式碼的使用限制在 - 無法使用 XAML 的宣告式功能提供必要功能的情況下,以及 WPF 和表單基礎結構程式庫中所定義的類別。As a general guideline, you should limit the use of code-behind to situations in which it is not possible to provide the required functionality by using the declarative capabilities of XAML, with classes defined in the WPF and the forms infrastructure library. 就算如此,也請考慮將程式碼後置於的功能移 - 至 helper 程式庫,然後從 XAML 參考它。Even then, consider moving the functionality that is implemented in code-behind into a helper library, and then reference it from the XAML.

包含例外狀況處理Include exception handling

請確認表單中的程式碼包含例外狀況處理,如此一來,就可以在 Authoring Tool 的設計階段和執行時間的 Service Manager 主控台中載入表單。Ensure that the code in the form contains exception handling so that the form can be loaded both during the design phase in the Authoring Tool and in the Service Manager console at run time.

考慮表單自訂與升級Consider forms customization and upgrades

在設計新表單時,您應考量未來對該表單進行的自訂及升級。When you are designing a new form, you should consider future customizations and upgrades to that form. 為確保您可以自訂表單,也可升級表單同時保留自訂內容,請遵守本節前面提供的指導方針和秘訣,以及下列指導方針:To ensure that it is possible to customize and to upgrade a form while preserving customizations, follow the guidelines and tips that are provided previously in this section, along with the following guidelines:

  • 在設計表單時及早考量未來的自訂與升級。Consider future customizations and upgrades early while you are designing the form. 表單在未來的版本中可能會進行改良,因此請務必考量使用者應如何升級至新版表單,同時保留其對原始表單所進行的自訂設定。Forms are likely to evolve in future versions, and it is important to consider how users will be able to upgrade to new versions of your form while preserving their customizations to the original form. 例如,在使用者已投入大量資源自訂原始表單之後,您可能會提供更新的表單。For example, you might provide an updated form after users have already invested heavily in customizing your original form. 使用者希望在版本升級後,仍可保留他們的自訂內容。Users expect their customizations to survive the version upgrade.

  • 為表單上的每個控制項提供唯一的名稱,讓您可將自訂套用到控制項。Provide a unique name for each control on the form to make it possible for customizations to be applied to controls. 表單自訂會儲存成以特定控制項或一組控制項作為目標的一組動作。Form customizations are stored as a set of actions that are targeted at a specific control or a set of controls. 目標控制項以名稱參照,因此請務必在所有版本的表單之間保留控制項名稱。The target control is referenced by name, which is why it is important to preserve control names across versions of the form. 如果控制項沒有名稱,表單自訂編輯器會產生名稱,但是產生的名稱不會在不同版本的表單間保留。If a control does not have a name, the Form Customization Editor generates a name, but the generated name is not preserved across different versions of the form.

  • 確認控制項名稱在不同版本的表單之間仍維持不變。Ensure that control names remain immutable across different versions of the form. 這可確保先前版本中特定控制項的自訂可以套用到新版表單中的相同控制項。This ensures that customizations for a given control in a previous version can be applied to the same control in a new version of the form.

  • 如果可能,在升級表單時,請避免將控制項移到相同索引標籤的不同位置。If possible, avoid moving controls to a different location on the same tab when you upgrade a form. 常見的使用者自訂是在表單上將控制項移到不同的位置。A common user customization is moving controls on the form to a different location. 如果您在新版表單上變更控制項的位置,新的控制項位置可能會與使用者已變更位置的控制項重疊。If you change the location of a control in a new version of the form, there is a risk that the new control location could overlap with a control that the user has relocated.

  • 如果可能,請在設計現有表單的更新時,避免在索引標籤之間移動控制項。If possible, avoid moving controls between tabs when you are designing an update to an existing form. 控制項是以名稱與其所在位置索引標籤兩者來識別。Controls are identified both by name and by the tab on which they are located. 在新版表單中將控制項從某個索引標籤移到另一個,可能會破壞使用者對該控制項進行的自訂,因為這些自訂將無法識別目標控制項。Moving a control from one tab to another in a new version of the form can break customizations that the user makes to that control, because the customizations will fail to identify the target control.

  • 當表單的更新包含新的控制項時,請考慮將新的控制項新增至新的索引標籤。這是避免干擾現有索引標籤和控制項之任何使用者自訂的最安全方式。When the update to a form includes new controls, consider adding the new controls to a new tab. That is the safest way to avoid interfering with any user customizations to the existing tabs and controls.

  • 請注意控制項的繫結方式。Be aware of how controls are bound. 唯讀 - 控制項只能使用單向系結 - 。Read-only controls should use only one-way bindings.

命名所有可自訂控制項Name all customizable controls

請確認控制項名稱係描述控制項所繫結的資料,或是描述控制項的功能。Ensure that the control names describe what data the control is bound to, or describe what the control does.

將表單系結至資料來源Bind the form to data sources

表單的主要用途是將 Service Manager 資料庫中的單一物件視覺化。The main purpose of a form is to visualize a single object from the Service Manager database. 這個物件稱為目標實例,一律由DataContext ( 繼承自FrameworkElement類別之表單的 DataCoNtext 屬性指定 ) 。This object is called a target instance, which is always specified by the DataContext property of a form (which is inherited from the FrameworkElement class).

重要

請勿修改表單的 DataCoNtext 屬性。Do not modify the form's DataContext property. 表單裝載環境使用這個內容來識別表單目標執行個體。The forms hosting environment uses this property to identify the form target instance.

在 Service Manager 資料模型中,目標實例是以 BindableDataItem 物件表示。In the Service Manager data model, a target instance is represented as a BindableDataItem object. 此類別會匯總基礎軟體發展工具組 ( SDK ) 物件,並透過索引子公開其屬性,其會採用屬性名稱做為參數。This class aggregates the underlying software development kit (SDK) object, and it exposes its properties through an indexer, which takes a property name as a parameter.

BindableDataItem 類別也會實作 ICustomTypeDescriptor,使您能夠使用 BindableDataItem 類別作為 WPF 繫結的資料來源。The BindableDataItem class also implements ICustomTypeDescriptor, which makes it possible to use the BindableDataItem class as a data source for WPF binding. 下列範例顯示將目標執行個體內容繫結至 Text 控制項的 TextBox 內容:The following is an example of binding a target instance property to the Text property of a TextBox control:


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

您不需要指定繫結的 Source ,因為目標執行個體已設定為表單的 DataContext ,作為表單上所有控制項的預設 SourceIt is not necessary to specify the Source of the binding because the target instances are set as the DataContext of the form, which serves as the default Source for all controls on the form.

表單上的控制項可以繫結到目標執行個體以外的資料來源,而表單基礎結構程式庫則包含幾個以隱含方式執行繫結的控制項。Controls on the form can be bound to data sources other than the target instance, and the forms infrastructure library contains a number of controls that perform the binding implicitly. 例如,執行個體選擇器控制項會繫結到資料來源,由資料來源提供可供選擇的執行個體集合。For example, the instance picker control is bound to the data source, which provides the collection of instances to choose. 您也可以使用 ObjectDataProviderXmlDataProvider 類別,以宣告方式定義其他資料來源。It is also possible to define additional data sources declaratively using the ObjectDataProvider and XmlDataProvider classes.

表單基礎結構會將目標實例視為 / 表單上的唯一讀寫資料來源。The forms infrastructure considers the target instance as the only read/write data source on the form. 因此, Submit 命令的實作只會儲存對目標執行個體所做的變更。Therefore, the implementation of the Submit command will only store the changes that are made to the target instance. 表單的其他資料來源都被視為唯讀。Other data sources for the form are treated as read only.

使用 Service Manager 表單基礎結構驗證規則、值轉換器和錯誤範本Use Service Manager forms infrastructure validation Rules, value convertors, and error templates

建議您在表單中使用表單基礎結構驗證規則來指定無效的資料輸入。We recommend that you use forms infrastructure validation rules in forms to designate data input that is not valid. WPF 系結基礎結構支援以單向或雙向系結系結至資料來源的控制項屬性驗證 - - 。The WPF binding infrastructure supports validation for control properties that are bound to a data source with either one-way or two-way bindings. 繫結物件具有 ValidationRules 集合,而此集合可以包含任何數目的 ValidationRule 物件。The binding object has a ValidationRules collection that can contain any number of ValidationRule objects. 每當資料從控制項推播到資料來源時,系統都會呼叫 ValidationRule 物件來驗證值。Whenever data is pushed from the control to the data source, the ValidationRule objects are called to validate the value.

表單基礎結構程式庫包含幾項驗證規則,可處理最常見的狀況。The forms infrastructure library contains a number of validation rules that handle the most common cases. 表單基礎結構利用這些驗證規則來判斷表單內容是否可提交以供儲存。The forms infrastructure takes advantage of the validation rules to determine whether the form contents can be submitted for storing. 例如,如果表單上有控制項發生驗證錯誤,則可以停用表單的 [ 提交 ] 按鈕。For example, a form's Submit button can be disabled if there is a control that has a validation error on the form.

建議您使用表單基礎結構程式庫所提供的自訂錯誤範本。We recommend that you use the custom error template that is provided with the forms infrastructure library. 如果控制項發生驗證錯誤,依預設其周圍會出現紅色框線。If a control has a validation error, it appears by default with a red border around it. WPF 可讓您透過 Validation.ErrorTemplate 內容 (可在任何控制項上設定) 定義自訂錯誤指標。The WPF makes it possible to define a custom error indicator through the Validation.ErrorTemplate property, which can be set on any control. Service Manager 表單基礎結構程式庫包含自訂錯誤範本,它會顯示錯誤圖示,而不是 WPF 紅色框線。The Service Manager forms infrastructure library contains a custom error template, which displays an error icon instead of the WPF red border. 此外,當滑鼠指向錯誤圖示時,將會出現內含錯誤訊息的工具提示。In addition, when a mouse points to the error icon, a tooltip pops up with an error message. 錯誤訊息應該會指出控制項中資料驗證失敗的原因。The error message should indicate the reason why the data in the control failed validation.

下列範例顯示如何在 XAML 中參照此錯誤範本:The following example shows how to reference the error template in XAML:


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

如果 - 內建驗證規則未提供必要的驗證邏輯,建議您建立自訂驗證規則來代表該邏輯。If built-in validation rules do not provide the required validation logic, we recommend that you build custom validation rules to represent that logic. 如此便可讓標準和自訂驗證邏輯共存在一般驗證處理機制內。This will make it possible for standard and custom validation logic to coexist within the common validation handling mechanism.

如果驗證規則機制不足以應付特定案例,您應該改為處理 FormEvents.PreviewSubmitEvent 並從該處執行驗證。If the validation rules mechanism is not adequate for a particular scenario, you should instead handle FormEvents.PreviewSubmitEvent and run the validation from there.

下列程式碼範例提供可用來執行自訂驗證的模式範例:The following code example provides an example of the pattern that you can use to run custom validation:


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
}

使用表單基礎結構命令和事件Use form infrastructure commands and events

表單基礎結構提供幾個可在表單上執行的命令。The form infrastructure exposes a number of commands that can be run on a form. 這些命令包括:These commands include:

  • FormsCommand.Submit,用於儲存表單的目標執行個體。FormsCommand.Submit, which saves the target instance of the form.

  • FormsCommand.SubmitAndClose,用於儲存表單的目標執行個體並關閉表單。FormsCommand.SubmitAndClose, which saves the target instance of the form and closes the form.

  • FormsCommand.Refresh,用於重複查詢表單的目標執行個體。FormsCommand.Refresh, which repeats the query for the target instance of the form.

  • FormCommands.Cancel,用於捨棄所有變更並關閉表單。FormCommands.Cancel, which discards all changes and closes the form.

這些命令前後都以事件包圍,在命令執行之前和之後都會產生事件。Each of these commands is bracketed by events, which are raised before and after the command runs.

執行命令之前會產生下列事件:Before the command, the following events are raised:

  • FormEvents.PreviewSubmit 事件在 FormCommand.Submit 命令之前產生,而 FormEvents.Submitted 事件則在 FormCommand.Submit 命令之後產生。The FormEvents.PreviewSubmit event is raised before the FormCommand.Submit command, and the FormEvents.Submitted event is raised after the FormCommand.Submit command.

  • FormEvents.PreviewRefresh 事件在 FormCommands.Refresh 命令之前產生,而 FormCommand.Refreshed 命令則在 FormCommand.Submit 命令之後產生。The FormEvents.PreviewRefresh event is raised before the FormCommands.Refresh command, and the FormCommand.Refreshed command is raised after the FormCommand.Submit command.

  • FormEvents.PreviewCancel 事件在 FormCommands.Cancel 命令之前產生,而 FormCommand.Canceled 事件則在 FormCommand.Cancel 命令之後產生。The FormEvents.PreviewCancel event is raised before the FormCommands.Cancel command, and the FormCommand.Canceled event is raised after the FormCommand.Cancel command.

預覽事件可傳遞 PreviewFormCommandEventArgs 物件。The preview events pass along a PreviewFormCommandEventArgs object. 這個物件包含可變動的 Cancel 內容,當此內容設定為 true時,即可讓對應的命令無法執行。This object contains a mutable Cancel property that will prevent the corresponding command from running when the property is set to true.

Post - 命令事件會傳遞 FormCommandExecutedEventArgs 物件。The post-command events pass a FormCommandExecutedEventArgs object. 此物件包含 Result 內容,指出命令是否執行成功、已取消或造成錯誤。This object contains a Result property that indicates whether the running of the command succeeded, was canceled, or caused an error. 若發生錯誤, FormCommandExecutedEventArgs 物件的 Error 內容便會參照例外狀況,提供錯誤相關資訊。In case of an error, the Error property of the FormCommandExecutedEventArgs object references the exception that provides information about the error.

您可以透過程式和宣告方式啟用、停用及執行表單命令。It is possible to enable, disable, and run form commands both programmatically and declaratively.

若要以程式啟用表單命令,請在表單和相關命令之間建立 CommandBindingTo enable form commands programmatically, establish a CommandBinding between the form and the related command.

下列範例在表單和 Refresh 命令之間建立了命令繫結,並針對此命令定義了兩個處理常式。In the following example, a command binding is established between the form and a Refresh command, and two handlers are defined for this command. 第一個處理常式傳回 Refresh 命令是否可執行,而第二個處理常式實際包含了 Refresh 命令的實作:The first handler returns whether or not the Refresh command can run, and the second handler actually contains the implementation of the Refresh command:


    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
        }
    }

您也可以宣告方式定義表單的處理常式。You can also define handlers for form commands declaratively. 您可以採用使用 RoutedCommandTriggerRule物件來執行此作業。You can do this by employing a Rule object that uses a RoutedCommandTrigger. 下列程式碼範例顯示如何以宣告方式定義處理常式:The following code example shows how to define handlers declaratively:


    <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>

後續步驟Next steps