+ All Categories
Home > Documents > Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the...

Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the...

Date post: 12-Jul-2020
Category:
Upload: others
View: 0 times
Download: 0 times
Share this document with a friend
111
Working with Symphony Framework V1.3 Page 1 Working with Symphony Framework
Transcript
Page 1: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 1

Working with Symphony Framework

Page 2: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 2

Rev No

Date Name Details

1.0 18/11/16 GI Introduction, description of setup project and some initial theory on objects, classes and MVVM

1.1 22/11/16 GI Product and supplier view projects and printing

1.2 27/12/16 GI Supplier, Product and Product Group Maintenance

Page 3: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 3

Contents Introduction .................................................................................................................................................. 6

About this Document ................................................................................................................................ 6

My Background ......................................................................................................................................... 6

Why Symphony Framework ...................................................................................................................... 7

Symphony Framework Example project ....................................................................................................... 8

Set up Solution and initial projects ............................................................................................................. 11

Files and Data Objects ............................................................................................................................. 12

Other actions with file objects. ............................................................................................................... 15

Referencing Methods and Properties ..................................................................................................... 16

A Little of the Theory .................................................................................................................................. 17

Classes ..................................................................................................................................................... 17

Symphony Framework Application Structure ......................................................................................... 19

First Steps in XAML – Product and Supplier Viewer ................................................................................... 22

Product Viewer ....................................................................................................................................... 22

Supplier Viewer ....................................................................................................................................... 24

XAML window ..................................................................................................................................... 25

SupplierViewer.XAML.DBL .................................................................................................................. 29

APP.XAML ............................................................................................................................................ 30

View Model ......................................................................................................................................... 30

SupplierViewViewModel.dbc .............................................................................................................. 31

Using Symphony Harmony in a Class .......................................................................................................... 37

Printing and Other Utilities ......................................................................................................................... 39

SFEUtilities.SFEPrinting Class .................................................................................................................. 40

Sample Output ........................................................................................................................................ 42

Other Utility Classes ................................................................................................................................ 44

SupplierReport Project ................................................................................................................................ 45

SupplierReportOptions.xaml ................................................................................................................... 45

SupplierReport.xaml.dbl ......................................................................................................................... 48

APP.XAML ................................................................................................................................................ 49

SupplierReportViewModel.dbc ............................................................................................................... 49

SFEBusinessLogic.SupplierReport Class .................................................................................................. 53

Page 4: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 4

File Objects, Symphony Harmony and Record Locking .............................................................................. 57

Record Locking ........................................................................................................................................ 57

File Objects .............................................................................................................................................. 57

Symphony Harmony ................................................................................................................................ 57

Design Considerations ............................................................................................................................ 58

New Applications alongside Older Applications ..................................................................................... 58

SFEAppShell – Menu and File Maintenance Programs ............................................................................... 59

Visual States ............................................................................................................................................ 60

SFEAppShell Project ................................................................................................................................ 60

Project Structure ..................................................................................................................................... 61

SFEAppShell ............................................................................................................................................. 61

AppStyling.XAML ..................................................................................................................................... 62

MainWindow1.XAML .............................................................................................................................. 64

Moving to a visual state for the file maintenance program ................................................................... 67

Defining how the user controls are loaded ............................................................................................ 67

Menu Buttons ......................................................................................................................................... 69

Animations between visual states .......................................................................................................... 70

Supplier File Maintenance .......................................................................................................................... 71

Maintenance.XAML ................................................................................................................................. 72

Creating Styles from Repository ............................................................................................................. 75

OverviewList.XAML ................................................................................................................................. 76

FullInput.xaml ......................................................................................................................................... 78

SupplierMaintenanceViewModel ........................................................................................................... 80

Filtering the list ....................................................................................................................................... 82

Changes to View .................................................................................................................................. 82

Changes to ViewModel ....................................................................................................................... 83

Adding Print Options ............................................................................................................................... 86

Changes to OverviewList.xaml ............................................................................................................ 86

Changes to ViewModel ....................................................................................................................... 87

Changes to Model ............................................................................................................................... 88

Product File Maintenance ........................................................................................................................... 89

Adding Images ......................................................................................................................................... 91

Page 5: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 5

Changes to View .................................................................................................................................. 91

Changes to View Model ...................................................................................................................... 93

Changes to Model ............................................................................................................................... 93

Changes to Report............................................................................................................................... 96

Displaying descriptions for coded fields ................................................................................................. 97

Changes to View .................................................................................................................................. 97

Changes to View Model ...................................................................................................................... 97

Changes to Model ............................................................................................................................... 98

Adding Pop-up Selection Lists ............................................................................................................... 102

Changes to Repository ...................................................................................................................... 102

SFE_UI\Common\SupplierCodeLookup.xaml ................................................................................... 104

SFE_UI\ViewModel\SupplierCodeLookupViewModel.dbc ............................................................... 105

Changes to Maintenance.xaml ......................................................................................................... 106

Changes to View ................................................................................................................................ 107

Changes to View Model .................................................................................................................... 107

Changes to Model ............................................................................................................................. 109

To do list .................................................................................................................................................... 110

Questions .................................................................................................................................................. 111

Page 6: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 6

Introduction

About this Document

This document aims to do 2 things

1. Tell the story of my journey from toolkit and traditional synergy to Symphony framework and

synergy.net development

2. Act as a reference manual for other developers making the same journey.

It is a mix of narrative, theory and instruction.

It does not aim to explain every possible thing about OO design and development, .net, visual studio,

XAML etc, but hopefully it does cover enough of each of these points to allow you to use them to create

robust, production class applications which are easily supported.

This document is an ongoing work in progress which may never be complete. As new things are

learned or better explanations emerge, they will be added.

And as others get involved in the Community Project, their experiences will help shape this document.

My Background

My background was in traditional and toolkit synergy development. I was responsible for a toolkit based

ERP product, and we tried to stay abreast of new technology, and embed it as and when we could.

I had not done any significant coding for 10 years, but would still have reviewed and debugged code.

Even then, most of the low level coding relating to creating, opening, reading and updating files and

records, printing, displaying messages, compiling and linking etc, were all wrapped up in our in-house

utility subroutines and batch files, so my actual pure synergy knowledge was also limited when I moved

to different environments.

My only exposure to OO and .net development was via the Synergy conference sessions and workshops,

which gave me a high level (possibly flawed) idea of what it was all about, but I had no experience of

actually using it.

We had engaged Richard to help with prototyping a few small Symphony Framework projects, but they

were followed through by other developers, and I did not see any of the code involved.

When I set up my own company 18 months ago, my first engagement was taking over a PSG re-

engineering project, which had moved a traditional synergy DBL project from VMS to windows, running

under synergy.net. It used low level windows and programs had been converted to subroutines. The

Page 7: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 7

printing and a few other areas had been written using classes. The client wanted me to make extensive

changes to printing to support print API printing alongside embedded escape sequence printing to dot

matrix printers which couldn’t be added as network printers, so I had to get to grips with how methods

and properties are defined and used in classes, and learning how to code, debug and deploy in a visual

studio environment.

Why Symphony Framework

I knew that Symphony Framework solutions using XAML for the UI were a quantum leap forward from

toolkit based solutions, and there was no point trying to set up a business only offering toolkit and

traditional based solutions. I wanted to offer services which allowed synergy clients to advance their

applications, and indeed, be able to offer modern solutions to companies not using synergy.

Hence I decided that I wanted my business to offer Symphony Framework based solutions and so that

meant learning SF (Symphony Framework) and synergy.net to the point of being able to deliver robust

applications with it, and being able to train developers from a similar background to my own.

As I have immersed myself in learning, a lot of what I have done has based on trust with little

understanding behind it initially, but gradually the murk cleared and little pieces became clear, and then

joined with other pieces to allow the overall picture to build up.

I still have gaps and don’t always understand why I have to do certain things, but I am still learning.

Also, as I master an area, it then sparks off other questions.

This document records my journey and documents the key points I have learned along the way.

Page 8: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 8

Symphony Framework Example project

I decided the best way to learn this was to actually try to get some simple examples working. Just

walking through working code of a completed application would not teach me what I needed to know.

It wasn’t just syntax I needed to learn, but I needed to understand how all the bits of an application

come together.

So Richard and I came up with the idea of putting together a simple application which managed

suppliers, products, product types and purchase orders. The design was kept as simple as possible so

that this could become a template on which more complex, real world applications could be put

together.

This has developed in a number of phases, and each phase added new layers to my knowledge and

understanding.

The application has 3 master files :

Product

Product_group

Page 9: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 9

Supplier

It has a relative parameter file, which is used to assign the next automatic purchase order number.

Parameter

2 files are used for purchase orders :

Order_header

Page 10: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 10

Order_line

The repository defines the files as being held in SFEDATA:, which is defined as a common property in the

VS solution to be :

This allows anyone to install the solution in any folder and create the files without ever having to hard

code directory names or paths.

Page 11: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 11

Set up Solution and initial projects

The solution “SymphonyExampleSolution” was set up as follows :

Solution Items folder contains repository and SF templates used by Orchestrator/codegen Templates are downloaded from the Symphony Framework web site

AppData_server class library project

Contains all the file and data objects created by Orchestrator. This has Symphony Framework and Symphony Harmony installed as Nuget packages The following items were created for each file :

- Data class - File IO class - Table mapper

When we started using styles then additional items had to be generated per file. More on this later

SystemSetup console app project

Contains program to create and populate data files This project needs a reference to the AddData_server project to pick up all the codegen’d file and data classes.

The solution includes a number of other projects, and these will be described in separate chapters as we

come to them.

Page 12: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 12

Files and Data Objects

The starting point was to create the actual files and populate them with initial data.

Step 1. Set up repository, including file type, file and key information.

Step2. Use Orchestrator to codegen File and Data objects

The following entries were created for each file. Note that other entries per file will be required in later

chapters as we start working with styles, selection lists and caching.

Page 13: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 13

In each case the repository needs to be defined on the second tab.

This will create the code generated classes in the AppData_server folder. These files need to be added

to the AppData_server project. These will already be added , but if you add any additional files and

classes they will need to be added.

(to install orchestrator and codegen ………..)

Page 14: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 14

SystemSetup project

I initially wrote this to include records from the repository, used ISAMC to create the file, and then

opened the file on a channel with an open statement and did STORES to the channel to add the records.

This was then changed to use file objects, data objects and structures.

This meant the program does not open or close the file, does not use records or channels, and does not

know where the file is or what it is called.

This was a bit of a culture shock, but was very useful later on.

Take the supplier file as an example.

I created a file object to talk to the file, and a structure to allow me to populate the fields with values.

The structure is then converted to a product object, and passed to the file IO class to be added to the

file.

data supplierIO = new Supplier_FileIO(FileOpenMode.UpdateIndexed)

(this is an object to access the supplier file in update mode)

data supplier ,STRSupplier

(this is a structure defining the fields in the supplier record)

The definitions come from the codegen’d classes in AppData_server.

These are picked up via import statements :

;;imports required to use data objects and file IO classes. import AppData import Symphony.Conductor.DataIO

And by setting a reference from the SystemStartup project to the AppData_server project

I found this concept of defining something to be based on something else very strange. I thought data

statements were A, D or I. However, the data statements allow objects, structures and various

framework elements to be created, based on items defined elsewhere. I found “go to definition” useful

in Visual Studio, and setting debug breakpoints to see what these structures, objects, properties etc

actually contained.

Page 15: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 15

To add a record to the file I do the following :

To

add this to the file, I do :

This creates a new SupplierData object from the structure, then passes this object to the CreateRecord

method of the supplierIO class, and returns a status which can be compared against a success property

of FileAccessResults

When I am finished, I close the file with :

supplierIO.CloseChannel()

Other actions with file objects.

The equivalent of opening the product file, reading the contents and displaying to screen using file

objects would be :

You can see a fairly common structure here, try to read first record, if successful, perform a while loop,

picking up all records on file sequentially by primary key.

Page 16: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 16

Every operation you would normally carry out with read, reads, write and store commands are provided

by IO methods, but the main thing here is to get used to having your data in an object, and using an IO

class to talk to the file.

SystemSetup contains a number of examples of reading and updating files via file and data objects.

Note – to run SystemSetup you need to make it the startup project in VS then run it.

Referencing Methods and Properties

The full reference to a method is NameSpace.ClassName.MethodName(), and similar for properties –

NameSpace.ClassName.PropertyName

If the class is defined in a different project, then your project needs to add reference to that project in

VS.

If you import the namespace which contains the class, then you can omit the namespace.

Hence the SetupSystem project has a reference to the AppData_server project, and imports the

AppData namespace, and so can refer to the Supplier_Data class, without having to reference it as

AppData.Supplier_Data

(Check this is correct)

Page 17: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 17

A Little of the Theory

Classes

Symphony Framework is based on Classes

You have probably heard all of this before, but hopefully the hands on approach will give a better

understanding of it.

Classes only expose properties and methods.

You call Methods and get or set properties.

Although you can pass in/out arguments to methods, generally you pass read only parameters to a

method. A method may or may not return a value. The method definition defines the return type, or

VOID. The return type could be an object or framework element, or a simple data flag or field.

The class may also contain a number of private properties and methods, which it uses for its own

purposes, but which are not exposed to other methods. So we have public methods and properties, and

private methods and properties.

You will find that a class can be an extension of a base class. For example, the SupplierIO class is an

extension of a base FileIO class.

So the extended class is everything in the base class, plus any methods or properties you add to it.

You can also override methods in the base class with your own version of it. I have used this in later

chapters to use my own version of a load method to only load a filtered set of records instead of loading

all records, but we will come to that later.

If a class is declared as static, you can call methods and get and set properties of the class without

having to instantiate it as an object in your code. This is useful for utility classes covering printing, PDF

creation, sending emails etc.

I have used the SFEPrinting class in this way. Methods in static classes can be called, for example to

open the printer, add a field to be printed, close the printer etc. The method has its own properties

such as printer handle, pages printed, position on current page, number of lines left on current page etc,

and these can be exposed as public properties for your method to use. My print methods use the

number of lines left on a page property to decide if it should take a new page.

Otherwise classes are instantiated as objects within your code, and you could have multiple instances of

the same class as different objects within your code. A typical example would be a supplier or a

product class being instantiated as an object in your code.

With the Supplier_Data class in the previous example, you create an instance of the class as an object in

your code, and then you reference the properties and methods of that class via its object reference.

Page 18: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 18

That may sound a little weird at this stage, but it will become clearer, and you do need to understand it.

It is best to stop thinking about records, functions, subroutines, commons etc, and to stop trying to map

everything back to what it was in the olden days. This requires a new approach and a new way of

thinking, and it should click into place as you start using it.

Page 19: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 19

Symphony Framework Application Structure

Symphony Framework is based on an MVVM design pattern, ie Model, View, View-Model.

Unlike traditional programs which will open the screen, display things on it and ask for input, these

applications start with a XAML screen definition. The framework loads, displays and processes this UI

and nothing else.

You could write XAML which displayed your name, showed a picture of you, allowed you to enter your

dog’s name, favourite treat and most recent walk, selecting the walk by clicking on pictures of the park,

the beach or the lake. But nothing would be updated or stored, despite the stunning UI.

So the framework needs to link the UI to the “model”, where the “model” is all the code to read and

update files, and all the business logic to process transactions and produce reports. The link between

the UI (the “view”) and the “model” is a thin class called a “view-model”.

The view-model is a class which inherits most of its functionality from base classes defined in the

framework or other projects in the solution. Thew View Model would typically relate to a specific record

or a collection of records, plus any additional fields you want to add. In this application, the product

maintenance screen shows the supplier name and product group description, which are not held on the

product file. These are added as an extension to the Product_data class, which you will see later.

The UI can only talk to the view-model, and it can only do so by “binding” what is on screen to

properties exposed by the view model.

The UI can be notified that the contents of a field have been changed by your code by the viewmodel,

and the UI can call the set method of a property if data is entered in the UI.

Similarly, button clicks are bound to properties to allow the desired action to be performed – running a

report, for example.

Nothing else happens between the UI and the viewmodel.

The model layer contains all your data and file IO classes, utility classes for printing, creating PDFs,

sending emails etc, and as much business logic as you can. Everything in the model needs to be defined

as a class.

The view model should be kept as small and thin as possible. Because it is just a class, it would be

possible to write a load of business logic methods within it which updated files etc, but that would be

just wrong. If you are going to do this type of development, you need to do it properly ☺

The UI is written in XAML, with a small piece of DBL code behind it which links the XAML to the view

model.

The viewmodel is written in Synergy.net.

Page 20: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 20

The code in the model can be written in any .net language. In this application, all of our code will be

written in synergy.net, but the SynPDF project is a mix of synergy.net code and DLLs written in C#

(confirm)

Page 21: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 21

ViewModel

Much of this is inherited from base classes. This defines local variables, say for

selection criteria. It can carry out validation and executes logic linked to button

commands defined the the XAML (view).

Complex commands, eg, print, email, post etc, will make calls into the model to run

methods define there.

There is no UI or file IO here at all

her

View

This is defined in XAML and defines all the UI, and nothing else

It does not update anything, and does not communicate with the Model.

Fields displayed by XAML need to be bound to a property (normally a field) which

is visible to the ViewModel

Button commands also need to be bound to definitions defined in the View

Model.

Relies on the ViewModel to tell it that a field has changed and needs to be

redisplayed

Ne

Model

This contains your data classes, File IO classes, and methods equivalent to print

programs, posting programs, functions and subroutine.

All file reads and writes are defined here

There is no UI here at all.

Page 22: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 22

First Steps in XAML – Product and Supplier Viewer

By this stage I was keen to get into some UI. My memory of XAML code from conference workshops

was that it was verbose and the syntax was very difficult. I hoped there would be a drag and drop tool

to write it all for me, with checkboxes for colours and other settings.

However, once I started using it I realized it was better to write the XAML code directly, and use the

intellisense to list available options. One key advantage of XAML is that it is readable, and the more you

work with it, the easier it is to understand.

The screens in this application are built around grids and data grids, which is very common in this type of

development.

Instead of referring to screens by row and column, you divide the screen into a grid, or multiple grids.

Each cell can be defined with an absolute size, or a relative size, such as “as big as it needs to be” , and

“whatever space is left”. This means that as you change the size and shape of the application window,

the screen layout adapts to fit the new screen size.

The other key concept is the data grid, which is basically a list. The list can contain data fields, images,

buttons, and you can have rows which expand to show additional lines of information. The data grids fit

within rows or cells of the overall screen grid, so they too will adapt to fit whatever size screen you have.

Product Viewer

To get me started, Richard wrote a simple “Product Viewer” project. I have not changed any of that

code. You can run it by setting this to be startup Project.

It lists the products in a data grid. It allows a particle product code to be entered, for example, to list all

products with codes beginning with “COK”

It does not use any of the symphony styles. It is just out of the box XAML.

Page 23: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 23

The view model exposes a list of Product_data objects, and exposes local “work fields” to accept the key

value and the tick boxes for “full key match” and “Read on group”.

I suggest you walk through the code and use debug to set breakpoints in the view model at various

points to track what happens.

Page 24: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 24

Supplier Viewer

I did not want to simply copy the product viewer and replace “product” with “supplier”

I created a new WPF application, called “SupplierViewer” I wanted to add a key word search and show

details of the currently selected row at the bottom of the screen, and I wanted to add some colour.

This project needs to have Symphony framework and Symphony Harmony installed as Nuget packages.

Right click on the project name in VS and select “Manage Nuget Packages. Browse for Symphony

Framework and Symphony Harmony and install them. Symphony Framework will also install 3 other

packages to give :

Page 25: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 25

Creating the project created a MainWindow.XAML” file, with a “MainWindow.XAML.dbl” file behind it.

I renamed the window to “SupplierViewWindow1.xaml, as I was pretty sure I didn’t want an application

with 100 screens all called “MainWindow.XAML”

XAML window

The first thing I had to change was the top block of the program :

I needed the ‘Loaded=Window_Loaded”’ to get anything to work at all.

X:Class defines my namespace and window name

Page 26: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 26

Because I am not using styles, which would convert the A and D fields defined by the repository into .net

field types, I had to include the following to access the converters used to display the fields

As you can see, these converters are part of Symphony Conductor

Next I divided by screen into 4 grid rows :

Row 0 - search criteria

Row 1 - search button

Row 2 – the data grid

Row 3 – the expanded window to show the currently selected window

This means, set rows 0, 1 and 3 as big as they need to be, and give row 2 whatever space is left

I defined Row 0 as follows :

The key thing to note here is that the text fields requested on screen are bound to public properties

defined within the viewmodel, ie KeyValue and KeyWord.

Page 27: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 27

Row 1 was defined as below. This is similar to row 0, except the fields are checkboxes instead of

textboxes, and we have a Button, which is bound to a “SearchCommand” property exposed by the

ViewModel.

Row 2 contains the data grid

Things to note here :

a) The contents of the data grid is bound to a list of supplier objects called “SupplierList”

b) Each data grid column defines a column heading and is bound to a property (ie, field) within the

supplier object.

c) I had to add SelectedItem="{Binding Path=SelectedSupplier}" so I could link the fields in the bottom section of the screen to the selected item. SelectedSupplier is a property defined in the ViewModel, which contains the supplier object corresponding with the current item in the list of supplier objects.

d) The column widths are fixed, but they could be set to auto or *

e) The fields are not displayed as .net field types and so cannot be sorted (see next section)

Page 28: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 28

Row 3 – expanded field details

First of all I defined a grid within this grid cell/row as follows :

Column 0 is used to display the field prompts or labels

Column 1 is used to display the field contents

I have given the XAML to display supplier code below. All fields are displayed in a similar manner. You

can see the full code in the VS projec

Q – note the wavy blue line under the TextBox Text line. This is highlighted as a potential error, yet

works fine. Why is this ? Is it normal ?

You can see the label is just a text block. The data field is bound to a property of the SelectedSupplier,

which was defined with the DataGrid. You will also see a converter is required to convert the synergy

field type to a .net field type.

Page 29: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 29

SupplierViewer.XAML.DBL

VS creates a DBL file behind the XAML file when it creates a project. This defines the name of the

namespace and links the XAML to the viewmodel.

Note that the specification of “Window_Loaded” in the XAML window is needed to call the

Window_Loaded method in the DBL file.

Page 30: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 30

Points to note :

a) The name space is the project name

b) The class name is the XAML window name

c) The data context is the name of the view model

APP.XAML

When the project is created as a WPF application, VS creates a file called APP.XAML, as below. This

defines the name of the class, and the name of the XAML file to run when the project is started.

I also defined various properties for text boxes and stack panels here, which apply as defaults across the

project.

View Model

In this simple example, the view model does not need to call any methods in the model, apart from the

File and Data classes which were code generated from the repository.

The coding contains 2 alternative methods of reading the data from the Supplier file, controlled by an

IFDEF. The code is currently running using Symphony Harmony, but the same result can also be

achieved using File objects to read the file. Symphony Harmony is more efficient, as it returns only the

records and fields requested by the query, whereas the File Objects will return every field on every

record for you to manually filter, which is less efficient, particularly in an xfserver environment.

However, Symphony Harmony does not yet return the GRFA of the records read via xfserver so if this is

an issue, then File Objects can be used instead.

Page 31: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 31

I would recommend using Symphony Harmony wherever possible. It is a much nicer syntax to work

with.

SupplierViewViewModel.dbc

You need to create a class in the SupplierViewer project.

First of all, you need to add extra import statements to the 3 which VS will add for you

Then you need to define the namespace and class

As you can see, this ViewModel extends a BaseViewModel class and so only things specific to this ViewModel need to be defined here.

Page 32: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 32

Next we define a constructor, which is a method which gets called when the ViewModel object is created in our application. This loads the list with supplier details, using the LoadAllSuppliers method. This is a private method within the class, which cannot be called by other classes.

LoadAllSuppliers method contains code to load the list using Symphony Harmony. The list is contained

in mSupplierList as an observable collection, and then exposed as a public property as SupplierList

(without the ‘m’). You can see that the data grid is bound to “SupplierList” in the XAML code.

SupplierList and mSupplierList are defined as :

We define a private property for the connector to use with Symphony Harmony:

private mConnector ,@DBConnector

Page 33: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 33

The loadAllSuppliers method is as below:

This method populates the list but does not return anything, so is declared with “,void”.

So next we come to the properties (work variables) which control the search. In each case we havea private property, prefixed with an ‘m’, which is used within the class, and a public property declared by the public property property name, property type statement. These should be defined with .net data types, eg string and boolean. The get method of each property simply returns the private property value. The set method sets the private property equal to the value passed, and raises a “property changed” event on that field. The XAML watches for any notifications of properties which clear and so will get and display the latest value of the property if a notification is raised. For example, if a method in the class cleared mKeyWord, nothing would change on the screen. However, if a method in the class cleared KeyWord (ie, the public property) then the set method of the public property would be called, and the property changed notification would be raised, and the field would be cleared on screen

Page 34: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 34

That just leaves the search. This can be written to use Symphony Harmony or to use File Objects. I will give the code using Harmony first, and then give the file objects version. The actual code uses an IFDEF to switch between the 2 approaches, but it is easier to follow if I split this down into 2 versions. In both cases you will see that the command is defined as a property of type “GenericCommand” which returns and executes command. The XAML just binds to this property. It does not set up a command to be processed. It has no knowledge of what actions will be taken. The XAML calls the get method of the command property, and the command returned is then executed. The method defines the command to be executed as an in-line lamda. (Explain what a lamda is ?)

Page 35: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 35

You should see that the code checks if mKeyValue is populated. If so, it executes a Symphony Harmony query. If not it calls the loadAllSuppliers method instead. The alternative version with file objects is :

Page 36: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 36

I suggest you compile and run the code with both options and step though in debug. It is important that you understand the XAML, how it interacts with the ViewModel, and how the ViewModel interacts with the model to get its data. Things get a lot more complicated in later chapters, and it is important you have a clear understanding of this simple example to serve as a reference point.

Page 37: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 37

Using Symphony Harmony in a Class

As you can see above, Symphony Harmony allows you to issue a SQL like statement to an isam file and

have a collection of data objects returned.

The steps involved in using it are :

a) Import the following in the class

import Symphony.Harmony

b) Create a private property to act as a connector to the data

private mConnector ,@DBConnector

mConnector = new DBConnector("SYMLOCAL:richard/morris!AppData.TableMapper.MapTableToFile")

c) If you want to include string comparisons in the query, then the following will switch off case sensivity

mConnector.SetCaseSensitivity(false)

d) Create an object to be populated by each object returned by the query

data item ,@DataObjectBase

The example given uses very generic code. This could alsbe be defined as

data supplierObj ,@Supplier_Data ,new Supplier_Data()

e) Create a Data select object which contains the results of the query data dataSearch ,@DataSelect

The example given names this as “typeOfSearch”

Page 38: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 38

f) Execute the Symphony Query

dataSearch = DataSelect.RunDataSelect(mConnector, "select * from supplier", new Supplier_Data()).Result

g) Navigate through the result set foreach supplierObj in dataSearch

Check the Symphony Framework web site for a more detailed explanation

http://www.symphonyframework.net

Page 39: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 39

Printing and Other Utilities I wanted the SFE project to include examples of all types of program which would occur in a typical application – file maintenance, transaction entry, enquiries and reports. Separately, Richard had suggested I should get to grips with the Synergy Print API, and I was keen to try the synPDF functionality. My experience of using the print API had been a wrapper (XCALL PRINT) that submitted “PLINE” as a complete line of fixed font text to the printer. I wanted to be able to write reports which used different fonts (including proportional), different font sizes and colours, boxes and shading and images. I decided to write a utility printing class which hid all the complexity of working with pixels etc from the calling method, and allowed the calling method to select either a print API report or a PDF, make the same calls to the printing class and achieve the same results. The issue I had with the synPDF row and column approach was that it assumes the same font size throughout, but I wanted to be able to use different font sizes for headings, and so a straight row and column calculation of print position would not work. So my printing utility keeps track of the pixel position (in print API pixels or in PDF DIP pixels) of the last line printed. The calling method “prints” to a line number and column position and leaves all the calculation of where that is on the page to the print utility class. Boxes and images are printed based on top right row and column, and bottom left row and column, relative to the current line number, based on current font size. The class exposes a “number of lines left on page” property based on current font size and the calling method uses this to decide when to take a new page.

Page 40: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 40

SFEUtilities.SFEPrinting Class

This is a static class within the SFEUtilties project and namespace. SFEUtilties is defined as a Class Library, not as a WPF application, and references the synPDF Project. The methods available are :

Method name Parameters Description

PrinterOpen ReportType R / P Landscape t/f Top Margin Bottom Margin Left Margin Right Margin Print Header t/f Print Footer t/f Printer queue/PDF file name

Defines whether report is print API (R) or PDF (P) Creates PDF object or print handle and defines a number of default values Margins are defined in print API pixels and converted to DIP pixels Columns per line is used to work out the number of pixels per column, which is then used to work out the pixel position for each print column passed It prints a fixed header and footer if requested. This is intended to print company name and logo at top of page, and date, page number etc at bottom of page

PrinterClose None Closes the PDF or print meta file and previews contents

SetFont fontName fontSize fontWeight fontColor backColor

Each of these is optional. The fonts currently supported are :

• Consolas (fixed font)

• Cambri

• Calibi

• Arial

• Times New ROman Foreground colours supported are :

• Black

• Red

• Blue

• Green

• Grey Background colours supported are :

• Light grey

• Light blue

Page 41: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 41

• Light yellow

• Light green Other fonts and colours can be added easily

PrintField Row Column Text to be printed

Prints text at the specified row and column.

Box topRow topCol bottomRow bottomCol margin fillColour

Prints a line or box Margin specifies a number of pixels to add as a margin around the rows and columns specified

PrintImage imageFileName topRow topCol bottomRow bottomCol

Scales and prints the image file between the row/col coordinates specified

FormFeed None

Takes a new page

SetLandScapeMode None Does not support PDFs yet

SetPortraitMode None

Does not support PDF yet

It has the following properties

ColumnsPerLine Used to work out the number of pixels per column, allowing for left and right margins.

LinesLeft Gives number of lines left to print to end of page absed on current font size, allowing for top and bottom margins, headers and footers

Any projects which need to use the print utility needs to define a reference to the SFEUtilities project and import SFEUtilities.

Note : Some work required to complete this : - Standardise on fill colours between PDFs and print API - Methods for setting landscape or portrait mode mid- print – cater for PDFs

Page 42: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 42

- Check functionality for bold and italics – does PDF allow these with same font, or does it need to change to a different font which has these qualities ?

Sample Output SupplierReport as report

SupplierReport as PDF

Page 43: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 43

Product Listing as Report (see later chapters)

Product Listing as PDF

Page 44: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 44

Other Utility Classes

The plan is to add other utilities to handle tasks such as exporting data grids to Excel, sending emails and

sending texts (SMS messages).

These do not exist yet.

Page 45: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 45

SupplierReport Project

The SupplierReport project is a WPF application which accepts report type and range of supplier codes

and contains a button which will request a report.

The view model responds to the button press by calling a static class called SupplierReport in a project

called SFEBusinessLogic. This in turn makes calls to the SFEPrinting class in the SFEUtilities namespace.

In later chapters, we will cover better ways to structure projects, but this example uses 3 projects, the

SupplierReport project, the SFEBusinessLogic project, and the SFEUtilities project.

This chapter will explain how each of these elements are put together.

SupplierReportOptions.xaml

I renamed the MainWindow.xaml file created by VS to SupplierReportOptions.xaml

The class name was changed to SupplierReport.SupplierReportOptions

The ‘Loaded=”Window_Loaded”’ clause was added.

Page 46: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 46

Then a grid was defined to :

- Accept starting supplier code on row 0

- Accept ending supplier code on row 1

- Accept report type on row 2

- Leave row 3 blank to space the form out

- Accept buttons to run report and exit

The field prompts are in column 0 and the data fields are in column 1

I tried to make the report type field a selection list. This could have been hand crafted, but the better

option would have been to have defined a repository structure and used styles. However, styles come

in a later chapter.

The “Back to Menu” button is a dummy button which does nothing since this is not called from

anywhere, and so has nowhere to return to.

The ViewModel defines the following public properties, and the XAML binds the fields on screen to

these :

- StartSupp

- EndSupp

- ReportType

- DoReportCommand

Page 47: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 47

The following XAML populates the data grid with the prompts, fields and buttons :

Page 48: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 48

SupplierReport.xaml.dbl

The DBL code behind the XAML was modified as below to define namespace, class name and viewmodel

name :

Note that the “Window_Loaded” clause at the top of the XAML links to the Window_Loaded method

here which defines the name of the ViewModel.

Page 49: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 49

APP.XAML

This is what actually runs the application, and you see it defines the name of the XAML file to run

(StartupUri). This needs to define the class name and the StartupUri.

You will also see that I have defined the foreground colour and font size for text boxes, and the

background colour for stack panels.

SupplierReportViewModel.dbc

This needs to add the following import statements to the 3 which are provided as standard when a class

is created. It needs to import SFEBusinessLogic to allow the Supplier report method defined within it to

be called

Page 50: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 50

This view model is linked to a data object in the model, based on the SELECTIONS structure defined in

the repository, however these fields are not used. See suggestion at end of this section re using styles

derived from the repository structure.

We now define the namespace and the class name for the ViewModel, which extends a BaseViewModelClass. You can right click on this in VS and “go to definition” to see where this is defined and what it contains if you are curious. We define a constructor which creates the object used by the ViewModel. The viewmodel needs an object, even though it is not referenced by this particular application. The constructor sets an initial default value for Report Type. It also adds a handler which checks if the data is valid if it is changed by calling dataChanged_event, which sets a property for the command button which says it can only be executed if the range of supplier codes is valid.

What exactly is the above doing - ? Doesn’t validate the range to decide if button is called ???

Page 51: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 51

Then create an object from the Selections_Data class.

private mSelections ,@Selections_Data

We now define the properties referenced by the XAML. (Note that the fields in the selections object

could have been used instead of defining new fields).

Page 52: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 52

In each case. If the public property is changed, the set method is called, which raises a Property Changed

Event on the field. When the XAML receives this notification it calls the get method for the property,

which returns the private property associated with the public property.

Now for the button command.

The command is set up as a Lamda which sets the range to ALL if both fields are left blank, and sets end

value equal to start value if end value left blank.

It then makes a call to the Print Method of the SupplierReport method in the SFEBusinessLogic

namespace, passing the starting supplier, ending supplier and report type.

Suggestion : Create an alternative version of this application to use styles code generated from a repository structure defining the work fields. Report type should be defined with a selection list of “Report” and “PDF” The Selections structure is defined in the repository to support this

Page 53: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 53

SFEBusinessLogic.SupplierReport Class

This class belongs to the model. In later chapters you will see how this would normally be included

within the “supplier” project. This project takes a different approach of holding all the business logic

classes in a separate class library project called SFEBusinessLogic.

This class has no UI. The view accepts the range and report type, passes this to the ViewModel, and the

ViewModel calls this class.

This is quite a simple class which uses the SFEPrinting class within the SFEUtilities project.

The class accepts starting and ending values as parameters, uses Symphony Harmony to select the

records to be printed, and then makes calls to methods within the SFEPrinting class to open the

printer/PDF, print headings, format records etc.

It would also be possible to do this with file objects, but that would mean reading all records across the

network and filtering out the ones not required in the class. Symphony Harmony is like the select class,

and only returns the required records to the class.

The project has references defined to the SFEUtilities and App_Data_server projects

The supplier report class includes the following imports , loading the standard windows imports,

symphony conductor, symphony harmony, plus the 2 projects we need within our solution – AppData

and SFEUtilities.

Page 54: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 54

The class declares a namespace for the class, the class name, and the methods within it

Because this is a static class is does not have a constructor method

You can see the 3 parameter values being passed in – starting and ending supplier code, and type of report.

Next we set up the connector for Symphony Harmony.

The second line of code makes all string matching case insensitive, which is

useful when carryout out keyword searching.

The commands to retrieve and process a set of records via Symphony Harmony are as follows :

This returns a list of supplier objects and we can then access the properties (ie, fields) within each

supplier object for printing :

Page 55: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 55

In this case we are passing a number of properties to the PrintField method within the SFEPrinting Class,

together with the line number and column position to print the field at.

We defined dataSearch and SuppObj before making the call to Symphony Framework :

Now look at how the methods in the printing class are used alongside Symphony Harmony to extract a

range of suppliers and produce a printed report or PDF :

Page 56: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 56

This produces:

Note that “END OF SUPPLIER” is just to show an example of a different sized font, and hence different

line height, in the middle of the report.

Page 57: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 57

File Objects, Symphony Harmony and Record Locking

Record Locking

In any synergy application, there are two approaches to record locking – optimistic and pessimistic.

Pessimistic record locking was the default approach in older systems, and could result in applications

freezing for long periods of time, causing considerable operational difficulties. This method read and

locked records while users decided whether or not they wanted to update them. Other users were

made to wait until the first user completed their task before records were released to them. The only

way to mitigate against this is to build in some form of logging which can report which users are locking

which records on which files.

Optimistic record locking aims to leave records unlocked until a user has decided what they want to do

with the record. If they want to update it the application will check if the record was changed by

another user since they called it up to vie wor edit, and if not, will then make the change to the file. This

can be coded within the program to store a copy of the original record to be compared against the

latest copy at time of making the update, but the recommended approach would be to update via GRFA,

where the GRFA is compared at time of update, and removes the need for a lot of hand crafted code.

The drawback with optimistic locking is that you have no guarantee your update will be successful, and

you need to trap and report failures to the user.

The Symphony Framework, File Objects and Symphony Harmony are intended to be used with an

optimistic locking approach. For a file maintenance type program it is straightforward to display a

message “Update failed – please try again”, but if you are updating a summary file in a class within the

model (eg, updating the total quantity ordered for a given product code when a purchase order is

saved), you have to take possible failures into account in your design. Note that the failures should

relate to another user updating the same record rather than record locking.

File Objects

The File IO classes used by this application use “update by GRFA” when updating files.

Symphony Harmony

Symphony Harmony is intended to work more like a database, processing commands to select, update,

insert and delete sets of records. Select and update commands are based on columns rather than rows.

The select does not store the GRFA of the record, and so update by GRFA is not possible. Hence you

cannot select via Symphony Harmony and update via File IO classes. The update command will update

Page 58: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 58

the field (ie, column) values specified, for the specified rows (ie, records), regardless of whether oir not

anyone else has updated them in the meantime.

Design Considerations

It is important that your application has a clear design approach to record locking, and how File objects

and/or Symphony Harmony are used.

In this application we are using File Objects with update by GRFA for maintenance programs, and

Symphony Harmony for read only reports and enquiries.

New Applications alongside Older Applications

It is likely that new applications such as this solution will by working alongside existing synergy

applications, and those older applications are likely to use a pessimistic approach to records locking.

File Objects and Symphony Harmony will both fail if they try to update a locked record. File Objects

work with single records and so trapping such failures is more straightforward than a trapping a failure

in a Symphony Harmony command which operates on multiple records, and could fail on any one of

them.

In this application, we will be creating, modifying and deleting purchase orders. We could potentially be

updating the value of orders placed on the supplier record and the number of items orders per product

on the product record.

The existing application may also update the same fields and files as it, say, receives goods against our

purchase orders, and archives the purchase orders when they are invoiced, matched and paid.

There are no right or wrong answers. You need to weigh up the options available and aim for the best

(or least worst) combination of robustness, performance and clean, readable code.

The last thing anyone wants is a cool UI which is unusable in a production environment.

Page 59: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 59

SFEAppShell – Menu and File Maintenance Programs

By this stage we have used Orchestrator to generate our file objects, and worked with file objects to

populate, update and display the contents of our files in a WPF, MVVM environment.

We have written our UI in XAML, and used view models to link this to the file objects and business logic

classes of the model to display and print lists of records.

It would be possible to extend what we have done to date to buttons to cover the basic file maintenance

options of add, change, delete and print, and so write simple applications.

However, all of our screens and reports are separate projects, and we have to set these as the startup

project in Visual Studio to run them.

We have also not used any styles, which are a major part of the Symphony Framework.

Nor have we used Visual States or animations, which are a key part of WPF applications

The next section looks at how a number of file maintenance programs can be written and called from a

“menu”. These programs use styles and a template file maintenance program (or, more accurately, a

base file maintenance class), which is then adapted for each file. They use selection boxes, date picker,

tick boxes, popup selection lists, and images and show additional description fields from other files. This

is intended to cover the majority of normal file maintenance functionality.

We will also see how standard methods in the base class can be overridden with custom methods for

searching and filtering.

Page 60: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 60

Visual States It is worth a few a few comments on visual states at this point to paint a broad picture. Visual states allow a user to move through different parts of a WPF application. In simple terms, a visual state is a ‘screen’ which can appear on top of any other ‘screen’. In our application the user moves from the menu, say to supplier file maintenance, back to the menu, then into product file Maintenance, where they drill on the Product Group field. Each of the items mentioned is a separate visual state. Each is defined as a user control with its own XAML file and view model. Each visual state has a visual state name, and the application uses commands to navigate to the visual state, and to indicate the visual state is completed or cancelled. The application then reverts back to the previous visual state. Examples of this are included in the SFE_Supplier and SFE_Product projects. Moving to and returning from a visual state is similar to entering and exiting from a new environment in a toolkit application (E_ENTER and E_EXIT)

SFEAppShell Project

The SFEAppShell project displays the menu and manages the visual states for each of the 3 file

maintenance ‘programs’ offered for selection.

Each of the maintenance ‘programs’ are defined as separate class library projects :

SFE_Product

SFE_Supplier

SFE_Group

Two other class library projects are used :

SFE_Base this holds the base classes for the file maintenance template program

SFE_UI this holds styles and other UI elements, including pop-up selection lists

Page 61: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 61

Project Structure

Each of the projects in this group is structured with three sub folders :

View XAML screens

ViewModel View Models

Model Classes called by ViewModel

This will be our recommended approach.

SFEAppShell

SFEAppShell is defined as a “”Windows Application”, and references the 5 class libraries listed above. It

does not deal with any of the data files and so does not need a reference to the AppData_Server project.

The menu shows an icon for each file maintenance “program”. This is animated so that it expands as

you hover over each icon, and a 0.5 second delay is built into moving from the menu the maintenance

screen.

Lets start with app.xaml, as below. This defines our XAML window name – MainWindow1.xaml’, which

is the default for a WPF windows application. If we wanted to change the name of the XAML file, we

Page 62: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 62

would need to change it here as well. You will also see that it defines a “Resource Dictionary”, which is

where our application colours and font sizes are defined.

AppStyling.XAML

This is located within the SFE_UI project, in the resources folder.

This was originally set up with a specific colour scheme in mind, which used black, white, blue and

orange.

The XAML is defined as a “resource” within VS, which means it is not executed, just referenced as per

the coding above. (confirm?)

It consists of a number of colour definition lines, which are then applied to each element of the user

interface

Page 63: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 63

It was originally created with the colours listed, but I changed this to the following scheme :

I simply changed the hex colour codes for the colours defined. It would be better to define the colours

by more generic terms, such as “dark background” “light background” “light foreground”.

A few points to note, which will hopefully be addressed.

1. The date picker always shows black on your selected background, so is hard to read with dark

backgrounds

2. Tick box prompts are always shown in black, which is also hard to read

3. Drop down selection lists are shown with a white background, which means you can’t use white

or very light colours as the foreground colour for data fields.

Page 64: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 64

MainWindow1.XAML

This window manages the display of 4 different “windows” as “visual states”.

These are :

Menu buttons

Supplier Maintenance

Product Maintenance

Product Group Maintenance

Each of these is defined as a “user control”, and each has its own XAML file.

These are held as follows :

Menu buttons SFEAppShell\View\MenuSelection.xaml

Supplier Maintenance SFE_Supplier\View\Maintenance.xaml

Product Maintenance SFE_Product\View\Maintenance.xaml

Product Group Maintenance SFE_Group\View\Maintenance.xaml

First of all, it defines :

Consider the following, which is defined for each of the 3 file maintenance projects. Assembly is the

project name, and namespace SFE_Product.View’ is defined within the SFE_Product project.

Page 65: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 65

xmlns:sfeuiProduct="clr-namespace:SFE_Product.View;assembly=SFE_Product"

The main window defines the window size, placement and window title.

The main thing this window does is control the various user controls processed within it as “Visual

States”. The syntax of managing visual states is quite verbose, but it is what it is.

Every Visual State is identified by a name, ie “MenuViewState” and “SupplierMaintState” in the

examples below.

Take the following, which disables the three maintenance views, and enables the launcherview, which is

the menu.

This MenuViewState is the default visual state as it is the first visual state defined (Is this correct?)

Note that in the MenuViewState, an item named “launcherView” is enabled and three other items

relating to the 3 file maintenance visual states are disabled. You will see that these do not refer to the

names of the visual states, but to the following items loaded within a grid :

Page 66: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 66

The border Name needs to correspond with the entry in the visual state definition as highlighted.

The entry for each visual state loads the user control specified by the XAML file indicated in the relevant

project. Ie. In the highlighted section, the user control specified in the Maintenance.XAML file within

sfeuiSupplier: is loaded. sfeuiSupplier is defined at the top of this MainWindow1.XAML file as :

The visual state for Supplier File Maintenance is defined as follows, disabling the launcherView user

control and enabling the supplierMaintView user control :

Page 67: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 67

Moving to a visual state for the file maintenance program

MainWIndow1.xaml defines WHAT happens when we move between visual states, but not HOW we

move between them.

The MenuSelection.XAML user control displays the menu icons and contains the following, which

causes a “Navigate State” to be executed :

Clicking the exit button on the common toolbar exits from the visual state and returns to the

previous visual state :

Defining how the user controls are loaded

MainWIndow1.xaml defines where and how the user controls are loaded in the window, as follows :

<Grid> <Grid.RowDefinitions> <!-- main item --> <RowDefinition Height="*"/> <!-- status bar --> <RowDefinition Height="auto"/> </Grid.RowDefinitions>

The “main item” will be the user control. The status bar at the bottom is used to load a standard

message as below, which is a licensing requirement when using Icons8 icons for free.

Page 68: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 68

The XAML then includes an entry for each of the visual states :

The border name must match the name specified in the visual state definition as mentioned previously.

The localUI defines the user control to load, and this was defined at the top of MainWindow1.xaml :

ie, localUI defines the namespace and the “:MenuSelection” defines the name of the class for the user

control to load. The menu Selection user control is declared as in MenuSelection.xaml.

See next section on Menu Buttons

The file maintenance user controls have slightly more defined for them:

This creates 2 rows within the user control. The first row loads a standard toolbar, which allows the user

controls to exit and return back to the menu. The second row loads the user control.

The details of the user controls for the toolbar and the Supplier Maintenance user control are specified

at the start of MainWindow1.xaml

Page 69: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 69

Menu Buttons

This displays the icons, which are held in SFEAppShell\Icons as menu buttons. The menu buttons are

bound to “Navigate State”, passing the name of the required maintenance option as SupplierMaintState,

ProductMaintState and GroupMaintState.

The menu button style is applied to each button. This causes the menu button to increase in size when

the mouse hovers over it.

Page 70: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 70

Animations between visual states

The Duration setting is the time allowed to move from one visual state to the next, and a variety of

animation effects are available. Try googling “WPF Visual State transition”. Basically, if you can

imagine it, you can probably do it. We have kept thing simple.

Note all XAML is extremely case sensitive, and differences in case or spelling WILL give you problems.

Page 71: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 71

Supplier File Maintenance

The SFE_UI project contains a base user control class, which is used by the file maintenance projects for

suppliers, products and product groups. This is held in SFE_EUI\Common\BaseUserControl.dbc.

You should not modify this, just extend it as required.

The file maintenance programs are structured in 3 parts :

1. A list of records held on the file, which can be sorted by any column

2. A window beneath the list which shows the current record highlighted in the list. The key field is

read only unless adding records. Invalid fields have a red background and a validation failure

message will be displayed if you hover the mouse above the field(s) in question.

3. A set of context sensitive buttons covering add, delete, save and cancel. Save and cancel are

only visible when fields in the input window have been edited, and you have tabbed off the field

or clicked on another one. Save is only visible if all fields are valid.

Three XAML windows are used for this screen, and these are defined within SFE_Supplier\View

Page 72: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 72

Maintenance.XAML

The DBL file behind maintenance.xaml links this XAML to the SupplierMaintenanceViewModel, held in

SFE_Supplier\ViewModel.

The code in Maintenance .xaml manages visual states within the “program”. The two states are

mainView and ErrorState. These are separate from the visual states managed by MainWIndow1.xaml.

ie, we are using visual states within visual states.

The mainView state loads 2 rows within the user control. The top row shows the data grid as defined in

OverViewList.XAML, and the bottom row shows the data entry window, defined within FullInput.XAML.

ErrorState is a standard user control window defined within SFE_UI\Common\ErrorDialogue.XAML

Let’s step through the XAML code.

This defines where the XAML files are found for common elements (ie, the Error Dialogue) and the

overviewlist and full input window.

Next we define some resource dictionaries to be used within the user control :

I seem to have an issue with the SFE_Supplier prtoject. I can’t add a refernce to it from SFEAppSHel;l,

yet the ap[plication works anyway ? Happened since I changed SEF_Supplier to SFE_Supplier

This defines dictionaries for :

Page 73: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 73

Converters - converts between synergy data types and windows data types

AppStyling - general windows stylings – colours and fonts

Supplier_Styles - code generated form repository. Defines styles for each field and field prompt

based on repository entries.

Next we define the visual states :

Page 74: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 74

And we define the display details for each visual state :

The two lines which actually load the OverviewList and FullInput windows are highlighted.

Page 75: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 75

Creating Styles from Repository

The other two XAML files use styles to display the required fields on the screen, and these styles need to

be code generated using Orchestrator.

For each file/record you wish to use styles for, create the following :

This creates SFE_UI\Resources\Supplier_Style.CodeGen.xaml.

Note that everything is created from the repository, including field prompt. The repository defines

whether a field is numeric, character, date, required, and if applicable, whether it should be treated as a

selection list, radio buttons or tick box.

The code generated files should NEVER be manually edited under any circumstances, as manual changes

will be lost the next time the entries are regenerated.

Page 76: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 76

This creates SFE_UI\Resources\Supplier_Content.CodeGen.xaml. This is used to provide drop down

selection lists for styles which require this.

This creates SFE_UI\Content\Supplier_Collection.CodeGen.dbc. Note this is class, and not a XAML file.

All of these code generated items are created in the SFE_UI project so they can be shared across

multiple projects.

OverviewList.XAML

This defines the data grid which allows the user to select records for editing.

The XAML defines a grid with 2 rowes. Row 0 is reserved for the toolbar with the exit button. Row 1 is

used to display the data grid. Ths size of the data grid is defined in maintenance.xaml, as the space

remaining between the full input window at the bottom of the screen, and the menu bar at the top.

This space will change in size if the window is resized.

Page 77: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 77

Question – should these columns be bound to styles rather than field names ?

The data grid is bound to a collection of supplier objects, and the selected item is bound to

SelectedCollectionItem.

Page 78: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 78

FullInput.xaml

This window handles the display and editing of the selected record from the list displayed by

OverviewList.xaml.

We have our standard stuff at the start of the xaml file :

We then define a grid to display the prompts and fields. Note – display prompts in separate grid cells

than data fields. This makes it a lot easier to line things up. The grid is actually placed within a single

row grid. Q – why was it done this way ?

Page 79: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 79

And now we place the fields and prompts on the screen :

As you can see, when using styles, we only need one line for each prompt and one line for each field as

everything else is defined in by the styles. Field placement is by grid row and column number, not by

screen row and column.

Finally we add the buttons. In this case we are using text, but we could easily use icons instead.

The menu button styling will animate each button so that it grows bigger as you hover over it with the

mouse.

Page 80: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 80

SupplierMaintenanceViewModel

Everything so far in this chapter has dealt with the XAML view. As mentioned already, the DBL file

behind the maintenance.xaml window links the view to the view model, which is held in

SFE_Supplier\ViewModel\SupplierMaintenanceViewModel.dbc

This extends a base view model defined in the SFE_Base project, called FileMaintenanceViewModel

First the imports and namespace :

Now the class definition and constructor method :

Page 81: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 81

This creates a private version of the object we are dealing with, and then defines a constructor which is

called when the viewmodel class is instantiated.

The parent line connects the view model to supplier file objects, and gives the name of the window (ie,

visual state) to display if errors are encountered.

This uses two event handlers to call methods as below. The events are defined in the base

FileMaintViewModel.

Event Method Action

ProgramModeChanged doProgramModeChanged() Enables or disables key fields on screen. This is defined in our view model

IsDataModifiedChanged DoIsDataModified This is defined in the base view model

It then loads the collection with supplier data records, using the LoadDetailList method defined in the

base class.

DoProgramModeChanged enables and disables the key fields in the full input window, as shown.

That is all that is required. Everything else is handled by the base classes.

Page 82: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 82

Filtering the list

To filter the list we need to add local fields to the overviewList.xaml file, and write our own override

version of the standard LoadDetailList method.

In this example we are reloading the list when the search button is pressed, but we could also do it by

calling the LoadDetailList method from the set method of the local search criteria fields.

Another approach in LoadDetailList would be to make the records in the list (data objects in the data

collection) visible or invisible according to the search criteria. It depends on what the overhead is in

going back to the data file each time, and whether or not the initial load loaded all records.

(Confirm the above)

Changes to View

OverviewList.xaml was modified to create an extra row in the grid to place the search criteria fields, and

the other elements were all moved down into the next row, ie, row 1 was changed to row 2.

The XAML was changed to display the following :

The line highlighted below was added to add the extra row

This row definition block was added to handle the local variables KeyValue and KeyWord, which are defined within the view model. It also defines a button, which is bound to a search command defined within the view model. Note that this is exactly the same approach as was used in the Supplier Viewer and Product Viewer projects already covered in earlier chapters.

Page 83: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 83

Changes to ViewModel

SupplierMaintenanceViewModel was modified to add 2 new properties for KeyValue and KeyWord

The search command was added as a property :

Page 84: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 84

Note that the lamda (ie, command) calls a private method called LoadBaseItemCollection, which is

defined within the view model as an override method, overriding the standard method defined in the

base class which loads the collection with all records on file. This is so that the same code can be called

when loading the list initially with no filters, and when reloading it with filters.

Page 85: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 85

This uses File Objects to read the file. Initially Symphony Harmony was used, which loaded the list and

displayed the contents, but the application failed trying to update records as Symphony Harmony does

not return a GRFA, so update by GRFA is not possible.

Page 86: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 86

Adding Print Options

Buttons were added to allow the filtered set of records shown in the list to be printed, either previewed

via the synergy Print API, or as a PDF. A version of the Supplier Report class was used for this, with the

print option, KeyValue and KeyWord passed in as parameters. This class is held in the Model folder of

SFE_Supplier.

These print options do not require any further user interface, and hence do not require a new Visual

State. If the print options required selection of printer, number of copies, page range etc, then a new

Visual State would be required.

Changes to OverviewList.xaml

The following was added to the definition for row :

The StaticResource MenuButtonStyle means the image grows in size when the mouse is hovered over it.

This displays as :

Page 87: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 87

Changes to ViewModel

Command properties were added to SupplierMaintenanceViewModel for ‘print’ and ‘PDF’. These call a

print method defined in the SupplierReport class, held in SFE_Supplier\Model, passing different

parameters.

Page 88: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 88

Changes to Model

As mentioned above, the static Print method of the SupplierReport class was based on the

SupplierReport project described in an earlier chapter.

Page 89: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 89

Product File Maintenance

Product File Maintenance is based on the same approach as Supplier File Maintenance, including the

filtering, print and PDF options.

It adds some additional functionality as follows :

- Supplier code and product group code

o Display descriptions of codes in the list

o Display descriptions in the full input window

o Display the new description if the code is changed

o Validate the new codes to check they exist on the supplier code and product group files

o Provide pop-up selection lists

- Product Images

o Display product image in the list

o Display product image in the full input window

o Display a “sale” icon/image if the “on promotion” tick box is checked

o Include images in the printed report and PDF

Page 90: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 90

The Product Data object in AppData_server was extended to hold additional fields in addition to those

generated from the repository entry. These are :

• name of the product image file

• name of the “sale” icon, which is blank if not on promotion

• supplier name

• Product group description

Page 91: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 91

Adding Images

The product images are held as JPG files in the ProductImages folder, where the image name need to be

productcode.jpg. This folder does not need to be part of the VS application. When this is ran as an

application rather than from within VS, the logical SFEImages: should be assigned to the location of the

product images folder.

This folder also contains an image files named sale.jpg which is used to display as a highlight on screen

and product list report.

Changes to View

This ‘worked’ by displaying the image file name on the window, but this generated exceptions each time

the application tried to display a missing file or null file name. A ‘Null Image Converter’ was written to

avoid this problem.

The images appear in the list and on the input window, so both XAML files needed to be changed for

this.

OvervewList.xaml

A reference/link was added at the top of the XAML file to define the null image converter, which is

found in SFE_UI\Converters\NullConverter.dbc, which contains a class called NulImageConverter,

Page 92: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 92

The data grid column definitions were defined as follows for the 2 image fields :

FullInput.xaml

Similar changes were made to this. The same reference to the null image converter was added to the

start of the XAML file.

The grid rows and columns were defined to create a cell to display the product image in. The product

description field was defined to span a number of columns as it would not fit within a cell. It would also

be possible to define the display grid in separate sections with different number of columns for different

rows.

Page 93: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 93

Q – why am I getting a wavy blue line under this ?

The product image was placed in a grid cell and set to span 6 rows :

Changes to View Model

No changes were needed to the ViewModel. Everything relating to the images was defined at the model

level.

Changes to Model

The code generated Product class in AppData_Server was extended to add 2 new properties for the

product image file name and the product on promotion image file name.

The code generated file was not changed – AppData_Server\Product_Data.CodeGen.dbc

A new class called Product_Data was written which expands the code generated Product_Data class

generated from the repository by Orchestrator. This is defined as a partial class with the same name as

Page 94: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 94

the code generated class, so that the properties and methods of this class are added to the code

generated class.

This was also created in AppData_Server as Product_Data.dbc

The constructor defines an event handler for the event ‘SynergyRercordChanged’ – synergychanged()

which are needed to ensure the additional image fields added to the class are populated and updated

correctly. In this case the image file names are set to Null initially and the get method of the public

property then determines the actual name.

Each image has 2 properties, of different types. ProductImage and PromotionImage are of type

ImageSource, and are used in the XAML. ProductImageFile and PromotionImageFile return strings

Page 95: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 95

containing the file name of the image, and these are used in the SupplierReport class to print reports

and PDFs.

public property ProductImageFile, string

method get proc

mreturn AppData.DataLogic.GetImageFileName(product_main.str_prod_code, ImageFileType.JPGFileType) endmethod endproperty public property PromotionImageFile, string method get proc

if (product_main.str_promotion == 1) then mreturn AppData.DataLogic.GetImageFileName("sale", ImageFileType.PNGFileType) else mreturn ^null endmethod endproperty

Note that the above properties do not need a private backing field as they never refer to

mPromotionImageFile or mProductImageFile. These call a method in AppData_server\Data_logic class

to return the image file name as a string.

The next 2 properties provide image sources for the XAML code :

Page 96: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 96

These properties provide the image file names for the report :

These do not require private backing fields, ie fields with an ‘m’ prefix.

Changes to Report

The ProductReport Class defined in SFE_Product\Model\SupplierReport.dbc includes the following to

print the product image and promotion image :

if (productObj.ProductImageFile != ^null) SFEUtilities.SFEPrinting.PrintImage(productObj.ProductImageFile,lineCount+1,20,lineCount +6,40) if (productObj.PromotionImageFile != ^null) SFEUtilities.SFEPrinting.PrintImage(productObj.PromotionImageFile,lineCount+2,50,lineCount +4,60)

This prints the image file based on top left and bottom right row and column co-ordinates, based on

current position on page and current font size.

Page 97: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 97

Displaying descriptions for coded fields

The supplier name and product group description fields were added as additional properties to the

Product_Data class, along with the Product and Promotion image file names.

The challenge with these fields was to make sure the descriptions were displayed correctly on the full

input window and on the OverviewList if the Supplier Code or Product Group Code fields were changed.

Changes to View

Changes to the view are simple. The additional fields are just placed on screen, and all the logic behind

populating and refreshing them is handled by the model.

The styling is controlled by the settings in AppStyling.xaml.

OverviewList.xaml

FullInput.xaml

Note that the foreground coilour needs to be defined as these additional fields do not have code gen’d

styles.

Changes to View Model

No changes are required to the View Model.

Page 98: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 98

Changes to Model

The Product_data class was modified as follows :-

- Define public and private properties for supplier name and group name

- Add private methods to find descriptions and populate the fields

- Calling the find methods when the object is created, and when the supplier code or product

group code is changed

This section will give the coding relating to supplier name. The product group description is handled

in exactly the same manner.

Defining the supplier name property

Note that any time the public property ‘SupplierName’ is set by code in the model, a property changed

event is raised which tells the xaml to display the new value.

Populating the supplier name field

The private method findSupplier populates the SupplierName property and returns a success or failure

status, which is used to set validation properties.

Page 99: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 99

This uses a cached search routine to populate a temporary data object with a supplier object. This is

coded generated and checks a cache of records already found before using file objects to search the file.

Question : What is the template called for the cache so I can add this to my Orchestrator definitions ?

Calling the findSupplier method in the model

The view model uses event handlers to populate and validate the additional fields whenever the

contents of the synergy record changes. These are defined in the constructor method :

Page 100: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 100

Synergychanged()

This is called when the synergy record is populated initially. It calls the findSupplier method to find and

populate the supplier name.

doDataChanged()

This is called each time a field in the view changes. It checks the name of the field which was changed,

and then performs field specific coding to read the new supplier name, and perform validation.

The return result from findSupplier is used to set the validation status and message on the Supplier Code

field. The style on the Supplier Code field causes the xaml to render the supplier code field with a red

background and to display a validation method set in the model when the user hovers the mouse over

the field.

doDataChanged is as follows :

Page 101: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 101

Refreshdata()

This is called when the synergy record changes

Is this needed ? If so, what does it do ?

Page 102: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 102

Adding Pop-up Selection Lists

Pop up selection lists were created for supplier code and for product group code. These were written in

the SFE_UI project so they could be included in any screen, and not just within Product File

Maintenance.

The approach is to define a xaml window for the selection list, with its own view model, and then handle

that within a separate visual state.

This section will describe how the selection list for the Supplier Code field was handled. The selection

list for Product Group is very similar.

The starting point is the repository, which defines the ‘name’ to be used. The code generated style for

the data class uses this ‘name’ and it is recommend that the various elements required to adhere to a

very strict, case sensitive, naming convention.

In this case, the repository defines the ‘name’ as SupplierCode.

The various elements are named as follows :

SupplierCodeLookup.xaml The xaml for the pop-up selection list window

SupplierCodeLookupViewModel.dbc The view model for the selection list window, which must contain a method named LoadList

SupplierCodeDrillState The name of the visual state used to display the selection list This is code generated by Orchestrator Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext.NavigateState}" CommandParameter="SupplierCodeDrillState"

Changes to Repository

The repository was changed to indicate that a drill method called supplierCode was required for the

field.

Page 103: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 103

The long description was set to :

Q – what is the long description used for ?

If the repository is changed then the code generated entries for the file in question need to be

regenerated via Orchestrator.

Page 104: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 104

SFE_UI\Common\SupplierCodeLookup.xaml

Page 105: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 105

Points to note are :

- This is a user control, which is displayed as part of the application’s main window

- The fields displayed per record are defined as data grid columns, bould to properties of the

supplier data object

- The user can sort the columns

- The user can only select a single item from the list

- The double click event selects the current item by binding it to a“selectItem” command

- The selected item is bound to the “selectedItem” property

- The user can move the window by holding the left mouse button down

SFE_UI\ViewModel\SupplierCodeLookupViewModel.dbc

This is a very simple view model which defines a single method to load the selection list with records

from the Supplier file, using Symphony Harmony. This extends the base class SerachViewModel.

Page 106: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 106

Changes to Maintenance.xaml

The visual state for the supplier code lookup is managed within the maintenance.xaml file within the

SFE_Product\View Project.

The main visual state for the maintenance program contains the following to switch the lookup’s visual

state off :

Note that all pop-up drill windows need to be disabled in this main visual state.

A visual state for the lookup was then defined :

The name of the XAML window to load for the visual state is then defined (ie, SupplierCodeLookup) :

The binding path to SuppCodeLookupVM is a property of the ProductMaintenanceView Model, which is

an instance of the SupplierCodeLookupViewModel

Page 107: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 107

Changes to View

No changes were needed for FullInput.xaml as the code generated style for the supplier code field adds

a lookup icon to the screen.

Changes to View Model

Code was added to the constructor method in ProductMaintenanceViewModel.dbc to create an

instance of the supplierCodeLookupViewModel .

A private and public property were created for the Supplier Lookup View Model :

The instance is created by the private method buildSupplierLookup, which is called from the

constructor:

Page 108: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 108

This creates the instance and sets up 2 event handlers to cater for the user either selecting something

from the list, or cancelling out.

These call doSuppCodeItemSelected and doSuppCodeItemCanceled, depending on the action of the

user.

Finally, we have a method to load the contents of the supplier selection list just prior to navigating to

the lookup visual state.

Page 109: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 109

This is called by an event handler defined within the constructor :

Changes to Model

No changes were required at the model level, apart from regenerating the Product_data class via

Orchestrator.

Page 110: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 110

To do list

1. Redo SupplierReport using styles based on fields on the SELECTIONS data structure rather than

additional properties defined in the VM

2. Explain .net types versus synergy data types

Page 111: Working with Symphony Framework · 2017-07-18 · Symphony Framework Example project I decided the best way to learn this was to actually try to get some simple examples working.

Working with Symphony Framework V1.3

Page 111

Questions

1. How do you set it to respond to each key click rather than waiting to move off a field ?

2. How would you make the full input window a tab set ?

3. How would you add additional windows to dock/slide in/out, or place on the screen ?

4. How would you add a third party control to a data grid ?


Recommended