How to create a new Screen

Suppose you already have a migrated application with the following project structure:

  • Back-end

    • App1

      • Form0.cs

      • Form1.cs

  • Front-end

    • app1-angular

      • app1

        • Form0

          • form0.component.ts

          • form0.component.html

          • form0.component.css

        • Form1

          • form1.component.ts

          • form1.component.html

          • form1.component.css

        • index.ts

      • app1.module.ts

      • component_definitions.ts

And you want to implement the following user story:

As a user, I want to be able to navigate to a new screen, in which I can click on a button and then a label shows the text: "Hello World".

Based on the user story described above, the screen should be like the following image:

And after clicking the button, it should be like this:

In order to implement this user story, you will have to do the following things:

  1. Create the screen Form2.cs in back-end code.

  2. Create the screen in front-end code and export the new screen. The new screen consists on the following components:

    • form2.component.html

    • form2.component.ts

    • form2.component.css

1. Back-end: Create the screen Form2.cs

Please follow the following steps: First, we have to create the class Form2.cs, add the ObservableAttribute to the class in order to keep the class within the WebMAP's life cycle. Then make the class extend from Mobilize.Web.Form in order to inherit all the necessary properties and functionalities that is needed in any new screen.

[Observable]
public class Form2 : Mobilize.Web.Form
{
public Form2()
{
}
}

Once we have the class created, we can start adding the functionality that we want for this screen. For this user story, we'll need to use some predefined controls that Mobilize already provides to us such as:

  • Mobilize.Web.Button

  • Mobilize.Web.Label

  • Mobilize.Web.RadioButton

  • Mobilize.Web.CheckBox

  • Mobilize.Web.TextBox

  • Mobilize.Web.TreeView

  • Mobilize.Web.DataGridView

  • Mobilize.Web.PictureBox

  • Mobilize.Web.Panel

For more details of the list of predefined controls, please refer to the section of API.

So, in this screen, lets use a Mobilize.Web.Button and a Mobilize.Web.Label defining them as properties and instantiate them inside the constructor.

[Observable]
public class Form2 : Mobilize.Web.Form
{
public Form2()
{
this.label1 = new Mobilize.Web.Label();
this.button1 = new Mobilize.Web.Button();
this.label1.Name = "label1";
this.label1.Text = "label1";
this.button1.Name = "button1";
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Name = "app.Form2";
this.Text = "Form2";
}
private void button1_Click(object sender, System.EventArgs e)
{
this.label1.Text = "Hello World";
}
[Mobilize.WebMAP.Common.Attributes.Intercepted]
private Mobilize.Web.Label label1 { get; set; }
[Mobilize.WebMAP.Common.Attributes.Intercepted]
private Mobilize.Web.Button button1 { get; set; }
}

Please note the following details:

  1. The properties' accessibility could be private, protected or public based on your needs

  2. The properties must have the InterceptedAttribute if you want the property be kept throughout the requests.

  3. The click event of the button1 is bound to the Click EventHandler, when someone clicks on the button in front-end, it will trigger a request, and it should step into the button1_Click method.

2. Front-end: Create the typescript, html, css and export the new screen.

2.1 Add a new folder

Lets create a new folder for Form2 that will contain the typescript angular component, the html and the css for the form. The folder structure would be as below:

  • Front-end

    • app1-angular

      • Form0

        • ...

      • Form1

        • ...

      • Form2

        • ...

2.2 Create Typescript angular component

Lets create the angular typescript component form2.component.ts :

import { Component, ChangeDetectorRef, ElementRef, Output, Renderer2, ViewEncapsulation } from '@angular/core';
import { EventData, dataTransfer} from '@mobilize/base-components';
import { FormComponent } from '@mobilize/winforms-components';
import { WebMAPService } from '@mobilize/angularclient';
@Component({
selector: 'app-form2',
styleUrls: ['./form2.component.css'],
templateUrl: './form2.component.html',
encapsulation: ViewEncapsulation.None
})
@dataTransfer(['frmapp.Form2'])
export class Form2Component extends FormComponent {
protected webServices: WebMAPService;
constructor( wmservice: WebMAPService, changeDetector: ChangeDetectorRef, render2: Renderer2, elem: ElementRef) {
super(wmservice, changeDetector, render2, elem);
}
}

In the code above, we need to import some core components given by angular, and we also need to import FormComponent to inherit the properties and functionalities of any screen. Besides, we need to import WebMAPService for the basic delta synchronization and sending requests to WebMAP Back-end.

Besides, we just need to create a class Form2Component (this name follows the angular naming conventions), and the dataTransfer attribute is a decorator is used to register the types of the controls that are going to be displayed dynamically.

2.3 Create the html

First, we need to create a html file: form2.component.html In order to bind with the back-end Form2 class, lets insert the following standard for creating any new html screens:

...

The html above is using a wm-window, which is a Mobilize Front-end generic component for supporting the System.Widows.Forms.

Second, we will need to bind with the button1 and label1 that we have previously defined in the back-end code, so lets insert one front-end button html tag and label html tag: wm-button and wm-label.

The wm-button with id button1 has a two-way binding with model.button1 (this property binds automatically with the back-end's button1 property).

The wm-label with id label1 has a two-way binding with model.label1 (this property binds automatically with the back-end's button1 property).

The class attribute we defined like: app_Form2, button1 and label1 will be used in the css to bind with the styles.

NOTE: Please note that you can add any other html tags here for extending other functionalities you want. The most important thing is that you will need to bind it with some angular component.

2.3 Create the css

First, we need to create a html file: form2.component.css Then, we just have to define some styles as below:

.app_Form2 {
/* you can add any other style here */
left: -1px;
top: -1px;
}
.app_Form2 .Form2 {
/* you can add any other style here */
width: 800px;
height: 450px;
overflow: hidden;
}
.app_Form2 .button1 {
/* you can add any other style here */
left: 31px;
top: 23px;
position: absolute;
width: 75px;
height: 23px;
padding: 0px 0px 0px 0px;
display: table-cell;
vertical-align: middle;
display: table-cell;
}
.app_Form2 .label1 {
/* you can add any other style here */
white-space: nowrap;
overflow: hidden;
left: 28px;
top: 61px;
position: absolute;
width: auto;
height: auto;
}

NOTE: Please note that you can add any style that you want to personalize the look and feel for the new screen.

2.4 Exporting the new created component

To export the new component, we need to add some code in the following files ( please refer to the project structure on the start of this guide)

  1. index.ts

  2. app1.module.ts

  3. component_definitions.ts

index.ts

//...
import { Form2Component } from './form2/form2.component';
//...
export { Form2Component };

app1.module.ts

@NgModule({
imports: [
//...
],
exports: [
//...
app.Form2Component,
],
declarations: [
//...
app.Form2Component,
],
entryComponents: [
//...
Definitions.app_Form2Component,
],
//...
})
export class app1Module { }

component_definitions.ts

//...
import { Form2Component as app_Form2Componentfrom './components/app
//...
export { app_Form2Component};

3. Compile and run

When we have both back-end and front-end code created, we just have to compile both back-end and front-end and run it.