Documentation YAML for OpenPetra Forms
Jump to navigation
Jump to search
Inheritance
General
- Most YAML files inherit from each other. That inheritance is specified with the BaseYaml Element. You will find this kind of inheritance in the vast majority of YAML files.
- This allows us to define many things once (e.g. default menu items, default Actions, default Events, StatusBar) in PetraForm.yaml and through that they will be included in all derived forms!
- Example:
BaseYaml: PetraForm.yaml
Special Cases
- Base YAML files (and possibly in some rare instances also other YAML files) can inherit from a Base Class. That is specified with the BaseClass Element.
- This can be a Class that is specified by the .NET Framework's WinForms implementation (such as System.Windows.Forms.Form), or one of our own openPETRA Classes.
- Example:
BaseClass: System.Windows.Forms.Form
- In certain (rare) circumstances a custom Interface might need to be implemented by a Class that is generated from a YAML file. This is achieved by specifiying the InterfaceName Element.
- Example:
InterfaceName: IMySpecialInterface
- It is possible to implement several Interfaces by separating them by comma (see Note below).
- Note: The Interface 'Ict.Petra.Client.CommonForms.IFrmPetra' is automatically implemented by all Classes which are generated from YAML files. If the 'InterfaceName' Element is specified, this is no longer the case. In case you want to implement both your specific Interface and 'Ict.Petra.Client.CommonForms.IFrmPetra' (which is very likely), concatenate them as follows:
InterfaceName: IMySpecialInterface, Ict.Petra.Client.CommonForms.IFrmPetra
.
- Example:
Attributes of the root node
- Template: this refers to the C# (.cs) file that is used for the template. The templates are located in csharp\ICT\PetraTools\Templates\Winforms. A description of templates and the snippets is here: Code Templates and snippets
- window: the default template, sufficient for module main screens etc.
- Examples: Finance Modules Main Menu (FinanceMain.yaml). PetraForm.yaml also points to window.cs.
- windowBasic: a simpler template than 'window', which allows for less dependencies (but also has a lot less functionality!). Currently only used for YAML forms in Project Ict.Petra.Client.App.Core.
- reportwindow: for the reporting screens
- windowEditUIConnector: this is for bigger edit screens, that require stateful sessions on the server; example: PartnerEdit? APEditSupplier?
- windowMaintainTable: maintain the rows of a single table, in a grid, with edit section at the bottom; example: SetupCurrency
- make sure that controls in pnlDetail contain the word "Detail" after the control type (e.g. txtDetailName) as otherwise the method GetDetailsFromControls will not automatically be created, leading to compile errors
- windowMaintainCacheableTable: maintain the rows of a single table, in a grid, with edit section at the bottom; example: GiftMotivationSetup
- the difference to 'windowMaintainTable' is that 'windowMaintainCacheableTable' works with only with 'Cacheable DataTables'. The CacheableTable Attribute of the root node needs to be set to the name of an existing Cacheable DataTable (e.g 'MotivationList').
- For Cacheable DataTables in the Finance Module which need to be filtered on the Ledger Number, the additional Attribute CacheableTableSpecificFilter of the root node needs to be set to 'Ledger'.
- The data that is displayed in the screen is retrieved and saved through the client-side CacheManager, TDataCache (namespace Ict.Petra.Client.App.Core), which in turn use server-side Methods that use the server-side Cache. Because of this, no WebConnectors or other static function calls on server-side methods need to be used for such screens!
- windowEditWebConnectorMasterDetail: edit a master row, and maintain the detail rows; Example: APEditDocument
- windowFind: template for find screens. uses UIConnector for paged search results; example: APMain
- windowTDS: template for complex find and browse screens that allow to change the data; example: GLBatch
- usercontrol: template for UserControls.
- UserControls can be understood as 'sub-forms' or simply parts of a screen whose layout is specified separately from the screen.
- usercontrolUnbound. Same as usercontrol, except for controls that don't host data fields, e.g. container controls.
- window: the default template, sufficient for module main screens etc.
- TemplateParameters: Advanced functionality! C# program code that should be appended at the end of auto-generated code that gets generated for a certain 'placeholder' in the .cs file that exists for the template defined with 'Template'. Several template parameters can be specified on individual lines in the YAML file. Each line needs to be indented by one level from the 'TemplateParameters' Element. Especially used in XML Reports Gui YAML files, but not just there.
- Syntax: PLACEHOLDER: C# code
- Examples:
INITMANUALCODE: InitManualCode();
INITMANUALCODE: InitGridManually();
INITUSERCONTROLS: InitUserControlsManually();
- FormType: Is not so important, because Template already defines a lot; at the moment, only the report type is different from the other types; this might change, and we will only need Template but not FormType
- abstract: if this is just used as a base form for other real forms
- navigation: the main window, the module windows
- edit: edit screens
- crud: CRUD screens (Create, Read, Update, Delete)
- find, browse: find screens
- report: reporting screens
- dialog: Dialog screens (have OK, Cancel, Help Buttons)
- MasterTable: if this is set, you will need to write less DataField attributes for the controls. The name of the controls will be matched to a field in the given table; if such a table field exists, it will be linked to the control.
- DetailTable: similar to MasterTable, but this is for the detail table; controls must have the word Detail after the prefix, eg. txtDetailAmount
- DatatableType: this is used for the DetailTable, if it is derived from a database table, in a dataset; eg UC_GLTransactions:
DatatableType: Ict.Petra.Shared.MFinance.GL.Data.GLBatchTDSATransaction
- Update: better use DatasetType, which allows mapping of tables to their dataset names automatically
- MasterTableType: this is used for the MasterTable, if it is derived from a database table, in a dataset
- Update: better use DatasetType, which allows mapping of tables to their dataset names automatically
- DatasetType: this will make sure that fields get mapped much easier to the appropriate table and datafield. You can use eg a controlname txtPFamilyFirstName, txtNoSolicitation, etc., and the controls will be mapped to the right table. You can even use data fields from custom tables and custom fields. You have to use the full namespace for DatasetType.
- UsingNamespaces: adds one or more reference(s) to Namespace(s) that should be included to the auto-generated C# file. Many of the usual Namespaces are already included automatically by the WinForms Generator, but there are situations where one needs one or more other Namespaces to be added.
- Correct capitalisation of the namespace(s) is important as the WinForms Generator just puts whatever is written in the UsingNamespaces into using ... clauses in the C# file.
- If you need to add more than one namespace, separate the namespaces with commas ( , ).
- Example #1:
UsingNamespaces: [Ict.Petra.Shared.MFinance.Account.Data]
- Example #2:
UsingNamespaces: [Ict.Petra.Shared.MPartner.Partner.Data, Ict.Petra.Client.CommonForms.Logic]
- Namespace: this is the namespace that this screen should belong to. eg.
Ict.Petra.Client.MFinance.Gui.AccountsPayable
- if you want methods to be linked automatically to a web connector, you need to make sure that there is a webconnector in the same namespace (Server instead of Client, without Gui, but WebConnectors at the end), eg.
Ict.Petra.Server.MFinance.AccountsPayable.WebConnectors
.
- if you want methods to be linked automatically to a web connector, you need to make sure that there is a webconnector in the same namespace (Server instead of Client, without Gui, but WebConnectors at the end), eg.
- ClassName: this is only required if the name of the yaml file should not be the same as the name of the class; the naming convention is: TFrmSetupCurrency is the classname, SetupCurrency.cs is the filename; for user controls: TUC_GLJournals is in file UC_GLJournals.cs
- PropertyForSubScreens: this is useful if you use ActionOpenScreen in your actions, because it will assign the property to the new screen (if it has that propery too); eg. in Finance module the ledger number
- ReportParameters: this is needed only in the reports. It will set the available fields that can be used in this report. Those fields automatically appear in the sorting list and in the column list of the report.
- CacheableTable: see definition here
- InitialFocus: the control that will receive the initial focus when the screen loads. You do not need this attribute if the screen has a grdDetails and you want the grid to have the initial focus, which is the standard setting for most screens. But if you want to focus a different control, use this setting.
- GenerateGetSelectedDetailRow: if set to true, the Method '
GetSelectedDetailRow
' will get generated despite the fact that no data fields are used in the Detail section of the Form (which is very uncommon). For templates that have 'FPrevRowChangedRow' defined, another Method, 'GetSelectedRowIndex
', will get generated too. (These Methods would otherwise not get generated!) - DependentChildUserControl: if set to 'true' then the usual calls that integrate UserControls into their hosting Forms get generated. This will work also if the hosting Forms' YAML file has 'MasterTable' or 'DetailTable' Elements. (At the time of writing [January 2015] utilised only in the ContactCategoriesAndTypesSetup.yaml and ContactAttributeSetup.yaml Forms.)
- Comment: an arbitrary text that doesn't get parsed. This can be used as a comment for the YAML file.
- TODO: BaseYaml, FormTitle, WindowWidth, WindowHeight
Events
- Events: here you can link form events to methods in your code
- eg.
Activated: {class=System.EventHandler,method=FTheObject.TFrmPetra_Activated}
- eg.
Actions
- Actions: actions can be used by menuitems, toolbarbuttons, and other controls; this is useful to be able to enable/disable an action on the whole screen, and to only define a certain action once, and refer to it from all controls that trigger the same action
- eg.
actClose: {Label=&Close, ActionId=eClose, Tooltip=Closes this window, Image=Close.ico}
- eg.
actMainMenu: {Label=Petra &Main Menu, ActionClick=FTheObject.OpenMainScreen}
- Enabled: Actions can depend on other Actions, or on 'Conditions' (for the latter, see bullet point 'Conditions' below [an Action will be disabled if the 'Condition' is 'false'; e.g.
Enabled: cndSelectedSupplier
]). - InitiallyEnabled: this is used for disabling an action when the window is opened
- eg.
- special situation: create a detail row: see for example APEditDocument.ManualCode.cs; we do use the generated function CreateAApDocumentDetail, but we need to first calculate some actual parameters
- Actions are linked by menu items, toolbar buttons etc either by using attribute Action, or by convention, ie. the name of the control matches the name of the action (eg. mniSaveSettingsAs matches actSaveSettingsAs)
- Conditions: Conditions are defined under the 'Actions' Element (like Actions). Their name needs to start with 'cnd' (e.g. '
cndSelectedSupplier
'), however.- The value of its 'InitialValue' Attribute can be 'true' or 'false'.
- An Actions' 'Enabled' Element can have a Condition as Attribute:
Enabled: cndSelectedSupplier
. The enabled/disabled state of the Action then depends on the value of the Condition, that is, an Action will be disabled if the condition is 'false'. - A Controls' 'Enabled' Element can have a Condition as Attribute:
txtDiscountPercentage: {Label=Discount, Enabled=cndDiscountEnabled, ...
. The enabled/disabled state of the Control then depends on the value of the Condition,that is, a Control will be disabled if the condition is 'false'. - A Conditions' value can be changed in program code. Example in *.ManualCode.cs file:
ActionEnabledEvent(null, new ActionEventArgs("cndSelectedSupplier", grdResult.TotalPages > 0));
- A Conditions' value can be changed by the NumericUpDown Control:
nudDiscountDays: {Label=Discount &Days, PositiveValueActivates=cndDiscountEnabled, ...
- A Common 'Condition' for 'Edit' Forms that allows the Enabling/Disabling of all Filter/Find-related Menu Items and the 'Filter' Button with one Method call exists.
- WinForms Generator:
- All Forms that derive from PetraEditForm.yaml have got the Actions 'actEditFindNext', 'actEditFindPrevious', 'actEditFilter' and 'actEditFind' specified. Those Actions' 'Enabled' Elements' Attribute is set to a special Condition, 'cndFindFilterAvailable', which is also defined in PetraEditForm.yaml.
- YAML Form Templates
- Templates that support Filter/Find functionality: the special Condition 'cndFindFilterAvailable' enables/disables the 'chkToggleFilter' (Filter) Button.
- Usage
- Enabling of the above mentioned Menu Items and the 'Filter' button: ActionEnabledEvent(null, new ActionEventArgs("cndFindFilterAvailable", true));
- Disabling of the above mentioned Menu Items and the 'Filter' button: ActionEnabledEvent(null, new ActionEventArgs("cndFindFilterAvailable", false));
- WinForms Generator:
- You can read more about the special auto-generated code for the Delete action in Adding Delete Functionality to a Screen or Control.
ManualCode
The following functions can be written in the *.ManualCode.cs file, and the next run of nant generateWinforms will pick them up and call them from the generated code. If the functions don't exist, they will not be called from the generated code: this avoids unnecessary empty functions in the manual code file.
Here are the manual functions:
InitializeManualCode
- called from within the Constructor of the Form/UserControl
- run after loading of data takes place
- run before a Grid is set up
- run before Form Activation takes place
RunOnceOnActivationManual
- runs when the WinForms
Form.Activated
Event is fired - only for Forms, not for UserControls!
RunOnceOnParentActivationManual
- runs when the WinForms
Form.Activated
Event is fired in the parent Form - only for UserControls, not for Forms!
- gets executed after a call to
RunOnceOnActivationManual
(if that is present)
ExitManualCode
- TODO
CanCloseManual
- TODO
NewRowManual
- only works where a Grid Control (grdDetails) is present
- used for supplying (default) values for DataColumns
- e.g. 'NEWVALUE' in many Setup-type Screens
- specifically needed for DataTables that have NOT NULL constraints on at least one DataColumn
StoreManualCode
- TODO
ShowDataManual
- TODO
ShowDetailsManual
- only works where a Details Panel is present
- TODO
BeforeShowDetailsManual
- only works where a Details Panel is present
- TODO
ValidateDataManual
- TODO
ValidateDataDetailsManual
- only works where a Details Panel is present
- TODO
GetDataFromControlsManual
- TODO
GetDataFromControlsExtra
- Extra program code that should be run after (and in addition to) the auto-generated code in Method 'GetDataFromControls'.
GetDetailDataFromControlsManual
- only works where a Details Panel is present
- TODO
GetDetailDataFromControlsExtra
- only works where a Details Panel is present
- Extra program code that should be run after (and in addition to) the auto-generated code in Method 'GetDetailsFromControls'.
GetSelectedDetailRowManual
- only works where a Details Panel is present
- TODO
PreDeleteManual
- only works where a Grid Control (grdDetails) is present
- for Details see here
DeleteRowManual
- only works where a Grid Control (grdDetails) is present
- for Details see here
PostDeleteManual
- only works where a Grid Control (grdDetails) is present
- for Details see here
SelectTabManual
- only works where a Tab Control is present
- TODO
Only for Reports:
ReadControlsManual
- TODO
SetControlsManual
- TODO
Controls
- Controls: see Screen scaffolding: controls
- See here for a description of how to implement the special Filter/Find Controls
Menu & Toolbar
- Menu:
- Structure
- A Menu is introduced with the item 'Menu:' in the yaml file.
- The children under the 'Menu:' entry form the top-level menus, e.g. 'mniFile' represents the 'File' menu.
- The children under such entries form the menu items of the top-level menus, e.g. 'mniFilePrint' represents the 'Print' Menu item of the 'File' Menu. Children of these children form sub-menus. This can go several levels deep.
- Naming conventions
- Menu item names start with 'mni', e.g. mniFilePrint.
- Use 'mniSeparator' for a horizontal Separator Bar between Menu items.
- Inheritance of Menus
- If you are working with a window template derived from PetraForm.yaml, then there is already a mnuMain control with the Close button.
- When deriving forms from each other the menu items are inherited; use attribute Order with values AlwaysLast, or AlwaysFirst. Whoever is higher in the hierarchy will have more weight.
- Example: the Help Menu Item in the root yaml file with Order=AlwaysLast will always be last, even if derived forms will have another item with AlwaysLast, which will be inserted before the help menu item.
- If you use a name for a top-level Menu that already exists in a yaml file that is an ancestor to the yaml file you are working with, Menu items are added to the already existing top level menu.
- Keyboard Shortcuts
- use Attribute ShortcutKeys to assign keyboard shortcuts to Menu Items. The syntax of this Attribute is as in WinForms Designer files.
- e.g.
ShortcutKeys=Keys.A | Keys.Control
for <CTRL>+<A>
- e.g.
- Note: The WinForms Generator automatically creates keyboard shortcuts for some pre-defined and hard-coded Menu Items, such as File->Save and some Edit-> find commands!
- use Attribute ShortcutKeys to assign keyboard shortcuts to Menu Items. The syntax of this Attribute is as in WinForms Designer files.
- TabControls
- If you are working with TabPages (e.g. using template controlMaintainTable, deriving from UserControl), you should add a control with name mnuTabPage; the contents of that menu will be added to the main menu when the TabPage is active.
- Structure
- Toolbar: very similar to Menu, just different names: tbrMain, tbrTabPage
- Structure
- A ToolBar is introduced with the item 'Toolbar:' in the yaml file.
- Currently there is a limit of only one ToolBar for each form.
- Naming conventions
- Toolbar item names start with 'tbb', e.g. tbbNewPartner.
- use 'tbbSeparator' for a vertical Separator Bar between Toolbar items.
- Inheritance of ToolBars
- When deriving forms from each other the ToolBar items are inherited; use attribute Order with values AlwaysLast, or AlwaysFirst. Whoever is higher in the hierarchy will have more weight.
- Example: the 'Save' ToolBar item in the PetraEditForm.yaml file with Order=AlwaysFirst will always be first, even if derived forms will have another item with AlwaysFirst, which will be inserted afer the 'Save' ToolBar item.
- When deriving forms from each other the ToolBar items are inherited; use attribute Order with values AlwaysLast, or AlwaysFirst. Whoever is higher in the hierarchy will have more weight.
- TabControls
- If you are working with TabPages (e.g. using template controlMaintainTable, deriving from UserControl), you should add a control with name tbrTabPage; the contents of ToolBar will be added to the ToolBar when the TabPage is active.
- Structure
Layout
Dialogs (Forms That Have OK, Cancel, Help Buttons)
To create Forms which are Dialogs, specify the value 'PetraFormDialog.yaml
' for the 'BaseYaml
' Element (instead of e.g. 'PetraForm.yaml
').
- When using '
PetraFormDialog.yaml
' as BaseYaml, there is no need to put OK, Cancel or Help Buttons on the Form, as this is already taken care of in 'PetraFormDialog.yaml
'. - Such Forms don't have a Menu or a ToolBar.
- File naming convention: We name YAML files for Dialogs
*Dialog.yaml
to make it easy to identify such Forms in the file system as well as through the Class Names (which then automatically also end in *Dialog!). - Important: all Controls need to be contained in a Panel called '
pnlDialogContent
' and this needs to be the 'Root Control'!- Other than that, there is nothing special about the layout of such Forms, all the usual layout methods and Controls can be used.
- Layout tips
- On some Dialogs the indentation of Controls from the left Form border is too small and Controls don't line up with the 'Help' Buttons' left edge. The same can be true for the right Form border which might not line up well with either the 'OK' or 'Cancel' Buttons's right edge. There is no hard rule when this occurs, it depends how Controls are laid out and which Controls are placed on the Dialog. To fix the indentation, add YAML Element '
Padding: 4,0,4,0
' (values are examples!) to 'pnlDialogContent
'. - Consistent width of several Panels, GroupBoxes, Grids, etc on a single Dialog can be achieved by using 'Stretch: horizontally' or 'Dock' YAML Elements. This also helps to align the 'borders' of such Controls with each other as well as with the 'edges' of the 'Help' and the 'OK' and 'Cancel' Buttons!
- To align input controls across different Panels, set the LabelWidth property of each input control to the same value.
- The width of the 'OK' and 'Cancel' Buttons (and the 'Apply' Button, if it is made visible) is automatically determined: whatever is the widest of those Buttons (also if their Text is altered!) is also applied as Width of the other Button(s). The placement of the Buttons (so that they are right-aligned on the Button Panel) is also done automatically. Both 'automatic' features are achieved in the WinForms Generator by parameterisation in the '
PetraFormDialog.yaml
' file ('AutoButtonMaxWidths: true' and ' AutoButtonMaxWidthsAutoSizesContainerWidth: true' YAML Elements!).
- On some Dialogs the indentation of Controls from the left Form border is too small and Controls don't line up with the 'Help' Buttons' left edge. The same can be true for the right Form border which might not line up well with either the 'OK' or 'Cancel' Buttons's right edge. There is no hard rule when this occurs, it depends how Controls are laid out and which Controls are placed on the Dialog. To fix the indentation, add YAML Element '
- Corresponding *.ManualCode.cs file
- Needs to contain an event-handling Method called '
BtnOK_Click
' - this is wired up by the Generator to get called when the OK Button is clicked by the user. - Dialogs have a hidden 'Apply' Button Control. To make it visible and wire it up to custom program code, create an event-handling Method called '
BtnApply_Click
' and add the following lines of code to the 'InitializeManualCode
' Method (the layout of the Buttons Panel is automatically taken care of!):
- Needs to contain an event-handling Method called '
btnApply.Visible = true; btnApply.Click += new EventHandler(BtnApply_Click);
TODO (Tabbed pages etc)
Other
Another option for layout is the Controls property that can be used for Panels and GroupBoxes: You can use several rows to arrange the controls and they are aligned in a table layout. see also Layout of Controls