Initial Version V0

Let’s implement the first basic feature to start the clock and to show the current time at the UI. Further features will follow later. The following diagram illustrates this feature:

AD4.AlarmClockSample.V0.png

The UI has an output pin (event) called “StartTimerClock” that sends the signal (without any content) to start the clock to the component TimerClock. The TimerClock sends the current time value every second as data type “DateTime” back to the UI. The input pin (method) with name “CurrentTime” receives the value and displays the content at the UI.
To develop this feature we need the AD4.AppDesigner. Download the latest version of the application from http://ad4appdesigner.codeplex.com/ to any desired directory. Start the AD4.AppDesigner.exe from the folder AD4.AppDesigner.bin directly.

Note
No installation of the application is required. It’s only a simple exe file. All settings are stored in AD4.AppDesigner.cfg. No registry settings or any other parts of your operating system are changed. (I like “To-Go” applications ;-)

After starting the AD4.AppDesigner you will see an empty window with some tabs. Initially, only the tab called “TEXT EDITOR” is important. We’ll take a look at the other tabs later.

Note
The visual presentation of your AD4.AppDesigner is probably different than shown in the following screenshots because the development of this tool is still in progress. However, the basic functionalities described here are stable and will not be changed.

First of all we need a flow definition to contain the components shown in the diagram above. Flow definition scopes are specified by the reserved keyword “$Flow”. Furthermore every flow definition needs a unique identifier. For our initial version we use the name “AppFlow”. The start and end of the flow definition scope is marked by curly brackets as in C#, Java and many other programming languages. The following code snippet illustrates this:

$Flow AppFlow {
 	…
}

Next let’s fill the flow definition with content. Data flows are distinctly marked by the keyword “$Wire”. In our sample we have to wire the data flow from the UI using output pin StartTimerClock to the TimerClock. The source and target of a wire are separated by “->”.
To separate the component and the pin the key character “?” is used. The following code snippet shows this data flow using these key symbols:

$Flow AppFlow {
    $Wire UI?StartTimerClock -> TimerClock
}

Note
Only the UI component needs a named pin (StartTimerClock) because the UI will contain many other pins later. TimerClock only contains a single input pin and a single output pin. Therefore, it’s not necessary to specify the pin explicitly by its name. The AD4.AppDesigner is able to find the desired pin by itself. If the AD4.AppDesigner is unable to identify the desired pin, an exception is thrown at the “CODE GENERATION” tab and the source code generation is skipped.

Next we add the data flow containing the current time from the component TimerClock back to the UI. Again we use a named input pin at the UI:

$Flow AppFlow {
    $Wire UI?StartTimerClock -> TimerClock
    $Wire TimerClock -> UI?CurrentTime
}

Note
It’s specific for UI components that named pins are used because most of the UI elements contain more than a single pin. For this reason, I suggest using named pins at UI element even it’s not necessary in the current state. Normally more pins are added later. Additional expenditure would be a consequence if the previous pins needed to be specified again then.

That‘s all you have to specify at the current state. Now it’s time to implement the functional units UI and TimerClock by code. The easiest way to do this is to create a new empty solution by Microsoft Visual Studio (called Blank Solution within Visual Studio). Save the solution in a folder of your choice using the name “AD4.AlarmClockSample”.

Next we add a project containing the UI parts. But this will be a DLL and not an executable file. Therefore, we add a new project of type “WPF User Control Library” with name “AD4.AlarmClockFrontEnd”. Visual Studio automatically creates the item UserControl1. Delete this item and add a new item of type “Window (WPF)” with the name “MainWindow”. Modify the xaml code of the window definition as shown in this snippet:

<Window x:Class="AD4.AlarmClockFrontEnd.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="120" Width="200">
    <Grid>
	<Grid.RowDefinitions>
		<RowDefinition />
		<RowDefinition />
		<RowDefinition />
	</Grid.RowDefinitions>
	<Grid.ColumnDefinitions>
		<ColumnDefinition />
		<ColumnDefinition />
	</Grid.ColumnDefinitions>
	<Button x:Name="StartTimerClockButton" Grid.Column="0" 
 		Grid.Row="0" Content="Start Clock" />
	<TextBlock x:Name="CurrentTimeTextBlock" Grid.Column="1" 
  		 Grid.Row="0" Text="00:00:00" 
 		HorizontalAlignment="Center" VerticalAlignment="Center" />
	</Grid>
</Window>

In the layout window of Visual Studio you will see this:

AD4.AlarmClockSample.MainWindow.V0.png

By doing this, basically the UI is finished for version zero. More visual components will follow later. Next we implement the event handler of the button to send the signal to start the clock. The name of the Action is “StartTimerClock” as defined in the initial flow chart:

public event Action StartTimerClock;

To initialize the pass through of the button click event to the action simply use the constructor of the main window. Arguments of the event are ignored (a, b):

public MainWindow()
{
   InitializeComponent();
   this.StartTimerClockButton.Click += (a, b) => StartTimerClock();
}

To present the current time on the UI we implement the method “CurrentTime” as defined in the initial diagram. The value is generated by a different thread. Therefore, we use the dispatcher object to transfer the value from this thread to the UI thread:

public void CurrentTime(DateTime currentTime)
{
  if (this.CheckAccess())
    this.CurrentTimeTextBlock.Text = currentTime.ToLongTimeString();
  else
    this.Dispatcher.Invoke(new Action<DateTime>(CurrentTime), 
      currentTime);
}

Note
A better way to handle the threading issue will be explained by one of the following chapters of this tutorial.

The UI component is now ready to use so far. Only the default bin folder of the project (output path) should be modified to collect all libraries of the solution in a single directory. I prefer to use a folder composed by the solution name and the extension bin. In this case “.\..\AD4.AlarmClockSample.bin\Debug\”.

Next we implement the timer clock. We create a new project of type „Class Library“ with name “AD4.TimerClockLibrary”.

Note
This is useful to avoid a mix of the frontend and timer clock aspects. It’s recommended to use an explicit library for every aspect to encourage the component based development to improve the usability of the resulting components.

Delete the automatically created class called “Class1” and create a new one called “TimerClock” as defined in the flow chart. This component contains one input pin to start the clock by using a timer and one output pin to send the current time. The following code snippet shows a possible implementation:

using System;
using System.Threading;
 
namespace AD4.TimerClockLibrary
{
  public class TimerClock
  {
    private Timer _Timer;
 
    public void DefaultInputPin()
    {
       _Timer = new Timer(new TimerCallback(TimeElapsed), null, 0, 1000);
    }
 
    private void TimeElapsed(object state)
    {
       this.DefaultOutputPin(DateTime.Now);
    }
 
     public event Action<DateTime> DefaultOutputPin;
  }
}

The initialized timer elapses all 1000 milliseconds eg. every second and calls the “TimeElapsed” method. This method “takes” the current time and sends the value by using the “DefaultOutputPin”.

Note
You can use any name as input or output pin name. The AD4.AppDesigner is able to identify the method and event because these are the only ones.

Of course you can implement your own “style” of code as far as you send a “DateTime” and offer a method to start you clock.

By this code the “TimerClockLibrary” is finished. As shown before at the front end library we modify the output path to ensure that the library will be created in our single bin folder “.\..\AD4.AlarmClockSample.bin\Debug\”.

As last project, we need a startup application to initialize our solution and to contain the source code produced by the AD4.AppDesigner. Let’s add the project of type “WPF Application” and name “AD4.AlarmClock” to our solution. Rename the created “MainWindow” to “StartWindow”.

Note
There’s an issue within Visual Studio because the StartupUri in your “App.xaml” will not be modified automatically. Therefore we have to change this entry manually (See: http://stackoverflow.com/questions/10003760/best-way-to-rename-mainwindow):

<Application x:Class="AD4.AlarmClock.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="StartWindow.xaml">
    <Application.Resources>
    </Application.Resources>
</Application>

Finally modify the output path of this project as done in the other projects too: “.\..\AD4.AlarmClockSample.bin\Debug\”. Afterwards the application runs but nothing happens except the showing of the start window.

Now we switch back to the AD4.AppDesigner to generate the source code by our flow definition and the generated assemblies. Previously, we have to add some settings to the AD4 file that are required by the AD4.AppDesigner. First of all the settings are managed within an explicit section of the AD4 file that is denoted by “$App Settings”. Inside this section the settings for code generation are organized as a sub section marked by the key word “$CodeGeneration”. Inside this scope we have to specify the location of the bin folder, if the sub folders also contain libraries and where the generated code file should be stored. All paths are declared in relation to the location of the AD4 file. In my case the following settings are valid:

$App Settings {
 	$CodeGeneration {
 		BinFolder = "..\..\AD4.AlarmClockSample.bin\Debug\"
 		BinIncludeSubFolder = "True"
 		CodeFolder = "..\..\AD4.AlarmClock\"
         }
}

But with the current flow definition the AD4.AppDesigner is unable to generate the desired source code. If you try to generate the code (by simply pressing the “Code” button) the “CODE GENERATION” tab will be focused and you will see an exception because the AD4.AppDesigner is unable to find the class UI in your assemblies:

AD4.AlarmClockSample.CodeGeneration.Failed.V0.png

In the flow definition we used the name “UI” and in code we implemented the functional unit UI as class “MainWindow”. Therefore, we have to extend the flow definition by declaring the functional unit “MainWindow” with custom name “UI”. To do so simply add the key word “$Step” within your flow definition and declare the custom name. Furthermore, determine that we want to create an instance of this step manually by setting the attribute “PreparedInstance”. Normally, the instances are created by the AD4.AppDesigner generated code automatically. The following text shows the result:

$App Settings {
    $CodeGeneration {
        BinFolder = "..\..\AD4.AlarmClockSample.bin\Debug\"
        BinIncludeSubFolder = "True"
        CodeFolder = "..\..\AD4.AlarmClock\"
    }
}

$Flow AppFlow {
    $Step MainWindow {
    	CustomName = "UI" PreparedInstance = "True" }
    $Wire UI?StartTimerClock -> TimerClock
    $Wire TimerClock -> UI?CurrentTime
}

Note
Currently only “concrete” classes can be used as prepared instances. The “AD4.AppDesigner” should be an extension of the object oriented programming concept. Therefore the support of interfaces and abstract base classes will also be implemented. This will take a while because there are currently many other features to implement that are more important. I will update this document if this feature is finished …

After these modifications the source code is generated successfully. You will find the code file in the “AD4.AlarmClock” folder with the same name as the application description file (but extended by .cs). Let’s switch back to Microsoft Visual Studio to “awake” the application.

First of all we add this code file to the “AD4.AlarmClock” project simply add context menu of the Solution Explorer, using “Add exiting item” and selecting the file.

Second, we have to add the references to the other projects. The following screenshot shows the solution items:

AD4.AlarmClockSample.Solution.V0.png

Third, we customize the startup application to use two screens: the startup window while initializing the application and the MainWindow as the “normal” application window. To achieve this we modify the “App.xaml* file of our application. Instead of “StartupUri” entry (defined previously) an “StartUp” entry with value “Application_Startup” as main startup routine is used:

<Application x:Class="AD4.AlarmClock.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="Application_Startup">
    <Application.Resources>         
    </Application.Resources>
</Application>

Finally, we implement this routine. Switch to “App.xaml.cs” and add this method (Application_Startup).

In the first step we want to show our start window temporarily and switch to our main window after initializing. This isn’t that easy in WPF. The following solution is based on http://www.c-sharpcorner.com/uploadfile/mahesh/show-multiple-windows-at-startup-in-wpf/.

To show the startup window we simply create the instance of “StartWindow” and show this window on screen. Then we create our UI instance, use it to run the AD4.AppDesigner generated code and release the start window. The following code snippet shows this partially:

/// <summary>Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
   private void Application_Startup(object sender, StartupEventArgs e)
   {
      //Based on: http://www.c-sharpcorner.com/uploadfile/mahesh/show-multiple-windows-at-startup-in-wpf/
 
      StartWindow tStartWindow = new StartWindow();
      tStartWindow.Show();
 
      AD4.AlarmClockFrontEnd.MainWindow tMainWindow = new AlarmClockFrontEnd.MainWindow();
 
      //ToDo: Usage of AD4.AppDesigner code
 
      tStartWindow.Close();
      tMainWindow.ShowDialog();
      Shutdown();
   }
}

By now the application runs, but no events are wired. Therefore, a click of button “Start Clock” causes an exception. The reason is simply the unused code of the AD4.AppDesigner. In the code snippet above you can see the place holder, ToDo, where this code needs to be used.

The AD4.AppDesigner generates a main class called “AppBuilder”. That’s the main entry point for all operations with the designer code. Inside this code you find some important sections. For our sample application not all parts are necessary and will be explained later.

If you create an instance of AppBuilder all flow classes are instanced as well. Our sample only contains a single flow called “AppFlow”. The instance of this flow class is called “AppFlowInstance”. The rule is always the same: the flow name plus extension “Instance”. So let’s create an instance of “AppBuilder“ and inject the MainWindow into the “AppFlowInstance”:

AD4.AppDesignerGeneration4Code.AppBuilder tAppBuilder = new AppDesignerGeneration4Code.AppBuilder();

tAppBuilder.AppFlowInstance.UIInstance = tMainWindow;

By this customization the AppBuilder instance is able to build the application. The easiest way is to call the method “BuildApp”. This will process all necessary steps automatically:

tAppBuilder.BuildApp(null, null);

The two parameters will be explained later.

The application is now ready to use. After starting the application you can click the button “Start Clock” and the current time is shown every second. So the initial version zero is finished.

Note
You can download the latest version of the solution here: AD4.TutorialSamples

Update (2014-06-22): Sourcecode of tutorial extended by design attributes:
AD4.AlarmClockSample.V0.22.06.png

Update (2014-08-13): Design attributes extended:
AD4.Tutorial.00.AppFlow.23.27.png
Update (2015-03-30): This page is obsolete. You find the current version of the tutorial as offline documentation included in downloads...

Last edited Mar 30, 2015 at 8:16 AM by InneHo, version 32