Click here to Skip to main content
Email Password   helpLost your password?

Introduction

This article is the second in a series which sets out to demonstrate the vast benefits to be gained by utilizing the UIPAB to develop your .NET user interfaces. In the first article, I emphasized the importance of viewing the UIPAB within the context of Microsoft Patterns and Practices initiative. I pointed out that one of the corner-stones of PP was the Layered pattern. I spent most of the first article in building the Business and Data layers for a demo, and ended off by building the Presentation Layer by way of a WindowsForm application. The demo UI was build without the UIPAB. In this article, I will concentrate on the conceptual basis for UIPAB and more particularly the MVC pattern and how this pattern is implemented in UIPAB. I will then dwell on the most essential elements of the UIPAB and show how with this basic knowledge the WindowsForm application build in the previous article can be refactored using UIPAB. Finally, I will show how the refactored UI using UIPAB can be reused to create a Web UI as an ASP.NET application. The UIPAB UI�s I will be demonstrating use the bare minimum features of UIPAB. I think that if the essentials are mastered, it is much easier to begin using the more advanced features. The last articles in the series will refactor and extend my demonstration to make use of the rich-feature set provided by UIPAB.

MVC

The UIPAB is a version of the MVC pattern. A comfortable working knowledge of UIPAB is predicated upon an understanding and appreciation of MVC.

Martin Fowler introduces MVC as follows:

�Model View controller (MVC) is one of the most quoted (and most misquoted) patterns around. It started as a framework developed by Trygve Reenskaug for the Smalltalk platform in the late 1970s. Since then it has played an influential role in most UI frameworks and the thinking about UI design.� (Patterns of Enterprise Application Architecture � pg. 330)

Essentially, MVC splits the user interface into three distinct roles: Model, View and Controller � graphically presented as follows:

The dependencies and independencies of the MVC trinity are key to understanding MVC. The View (presentation) is separate from the Model. The View is also separate from the Controller. The model is independent of the View and the Controller. Both the View and the Controller is dependant on the Model. The Model is the dominant component and also the component that can be reused in changing UI scenarios. If a new UI is required, MVC mandates that we rebuild the Controller and most importantly the View. This being the case, it is imperative that both the View and the Controller be as light-weight as possible and contain as little UI logic as possible. Within the context of the Layered pattern is should be the Model and only the Model that interacts with the Business Layer.

Fowler summarizes the major advantage of MVC thus: �A key point in this separation is the direction of the dependencies: the presentation depends on the model but the model doesn�t depend on the presentation. People programming in the model should be entirely unaware of what presentation is being used, which both simplifies their task and makes it easier to add new presentations later on. It also means that presentation changes can be made freely without altering the model.� [Fowler � 331]

Fowler recommends that MVC be used in almost every UI scenario, saying that the only time it should not be used is in very simple systems where the model would have no real behaviour in it in any case. Whenever there is even a small amount of UI logic, MVC should be used. The clearest case I can think of when not to use MVC � is in a static HTML page which will never change i.e. the content is embedded into the page and the page does nothing but display a static image or text. In all other cases, MVC should be used.

MVC & PP

Predictably, MVC is at the heart of all UI patterns in .NET Enterprise Solution Patterns (ESP). There is extensive discussion of MVC in the PP literature.

In Enterprise Solution Patterns Using Microsoft .NET, MVC is introduced in Chapter 3 on Web Presentation Patterns (see especially pages 34 to 50). In Design and Implementation Guidelines for Web Clients MVC is discussed throughout; if you do not have time to read the entire guideline, read pages 22-25.

ESP defines the problem MVC is meant to address as: �How to modularize the user interface functionality of a Web application so that you can easily modify the individual parts?� ESP identifies two variations of MVC: a passive model and an active model. The passive model is when there is only one controller manipulating the model i.e. the controller modifies the model and then informs the view of the modification. In the passive scenario the model is completely independent of the view and thus the model cannot report changes of its state to be reflected in the view. In a Web situation � the browser (View) must be refreshed so as to retrieve the data from the Model. In the active scenario, the Model changes state independently of the Controller; here the Model notifies the View of any changes of state � a connected, real-time stock-ticker is an example of an active MVC scenario. The active MVC is a UI version of the Gang of 4 Observer Pattern.

ESP lists two important benefits of MVC: support for multiple views and easy accommodation of changes. The also two liabilities in using MVC: complexity and the problem of frequent updates. If done correctly (as in UIPAB) the latter liability is eliminated. Also, I don�t think MVC is complex; it is an entirely different way of doing UI�s and it is this paradigm shift, more than anything else, which makes it seem complex. But once the coin drops � you will have an epiphany � you will have made the paradigm shift, and I don�t think you will ever go back to developing UI�s without using MVC.

MVC & UIPAB

The documentation states the UIPAB objectives as follows:

Although it is not clearly stated in the documentation, UIPAB is a type of MVC. I find it easy to understand UIPAB if I map the three MVC components to appropriate UIPAB elements. Reducing a .NET MVC UI to its barest bones would go something like this:

From a UIPAB perspective the essential elements in �everything else� in the Model are:

Before dealing with the UIPAB architecture, I want to briefly elaborate on UIPAB Views, State and Workflow Management and Persistence.

TASK

A Task is best defined as a specific Use-Case. UIPAB Tasks constitute a number of forms participating in a navigation sharing the same task and the same controller. The demo application in the first article in this series is an application fulfilling a single task. Applications normally carry out a number of tasks in sequence. When designing a UI therefore it is important that you first conceptualize in a very clearly defined manner the various Tasks your UI must perform. The PP documentation recommends modeling these tasks in flow diagrams. UIPAB allows for the linking of tasks. Furthermore, UIPAB allows you to persist your tasks. Practically, a Task is more or less congruent to a single Workflow. UIPAB assigns a unique ID to each Task in the UI application � this ID is used for persistence. (I will not be covering persistence in this article.)

VIEWS

UIPAB V2 supports only ASP.NET and Windows UI applications. All UI forms participating in UIPAB must implement the IView interface. Each IView implementation has the following properties:

The App Block supplies three UIPAB IView implementations:

Developers can build custom IView implementations. For almost all scenarios, it is recommended to use the provided IView implementations. What this means is that your WebForms inherit from WebFormView and not Page and your Windows Forms inherit from WindowsFormView and not System.Windows.Form.

NAVIGATION

Navigation is a work-flow. Essentially, it is the map of Views as they are activated in a determined order for a specific Task. (Using the WindowsFormControlView the elements on the map can be controls on the same view and the workflow is from control to constituent control which are also called �nodes�.) The UIPAB has a Navigator class which co-ordinates the navigation between the views in the task. The UIPAB provides 4 different types of navigational modes. The point is, no matter the type of navigation used, each Task must be associated with a Navigator and each Task can only begin when it launches its navigator. In fact, the first act of any task in run-time is launching the appropriate navigator.

In this article I will only be examining one type of navigator (the principle is the same for the other navigators). At this stage, suffice to know what the navigator types are and how they can be initiated:

The four UIPAB navigators are:

STATE

State is important from a UI perspective in two ways. Firstly � there is some form of state that is derived from the Business Layer (or Data Layer) which must be maintained on the UI � this is true for both Windows and Web environments. Secondly, inevitably state must be maintained between views in the UI � in most cases each form is transferring state to the form that follows it in the navigational sequence.

In the traditional way of doing UIs (an example of which I gave in the first article of this series) � the UI state management process is awkward and cumbersome to say the least. State is either embedded into the UI views (the crude mode) or some sort of Mediator is used where state management is coordinated.

UIPAB manages state as it does navigation i.e. on per Task basis. Which is to say: the views that participate in the Task, share the same Navigator, Controller and state-management. In the old approach, each view more or less is responsible for managing its own State. With UIPAB State management is centralized.

The UIPAB has a generic State class which should fulfill most UI State management requirements. This class implements ISerializable and supports the StateChanged event which provides Observer type functionality to the UI using .NET delegates. The State class hosts an internal hash table into which most data types can be added. Essentially, these data-types are your state. All data types added to the State class�s inner hash-table must be marked as Serializable or implement ISerializable. The important State class methods are intuitive, given that the class contains a hash-table. The important methods are:

PERSISTENCE

The idea behind UI persistence is best explained by the �snapshot� metaphor. As the UI progresses through the Task there might be occasions where the User wishes to persist the current state. This might be required because the user has not the relevant information to complete the UI task, or he might want an audit of UI processes for later analysis. The point is � at the moment in time of persistence � a �snapshot� almost like a photograph is taken of the current UI sate and persisted.

The coding of UI state persistence can be a cumbersome and sometimes thankless task. This is all the more true when you want to build a flexible persistence architecture that can cater for a variety of persistence providers. Also, it might be necessary to retrieve persistence in one mode which was saved in another mode. For example: you might begin an online purchase scenario on the Web and resume it using an in-house windows intranet application.

Fortunately, UIPAB has a sophisticated, feature-rich, centralized and easy to use persistence management element. I will not be dealing with persistence in this article. Suffice to say at this stage that UIPAB supports six persistence out-of-the-box providers.

UIPAB ARCHTECTURE

The glue that holds the UIPAB together is the UIPMananger class. The UIPManager has been designed so as to have a simple, easy to learn API which consists of static methods that launch a particular navigator. It is the UIPManager that acts behind the scene to co-ordinate the various UIPAB elements and their association with the your front-end application.

Configuration is vital to setting up your UIPAB application. I have found that configuration is difficult to grasp in the abstract and makes more sense when applied to a specific example. Also, you will find that if there are errors or exceptions in your UIPAB applications, it is invariably because you have done something wrong in your UIPAB configuration. I will thus deal with configuration when I examine the UIPAB example.

HOW TO BUILD UIPAB UIs

At first glance the UIPAB might seem daunting in its complexity and its many layers and classes. In actual fact, the work required to build a UIPAB UI is minimal � the real hard work is the understanding.

Below is the UIPAB architectural diagram supplied with documentation. Basically, the only work you as a developer have to do is:

  1. Create your UI Forms.
  2. Create your UIPAB controller.
  3. Hook up the UI Form events with the controller.
  4. Configure your applications config file for UIPAB.

All the rest is taken care of for you by the Application Block.

REFACTORING THE WINDOWS EXAMPLE

I will now begin refactoring the Windows application I presented in the first article. Recall, that the application consisted of a single Task which was a person management console. I retrieved the list of person, disconnected, manipulated the list off line, and finally reconnected to the back-end making the necessary persistence changes.

The first thing I do is create a WindowsFroms project in the UI sub-layer of the Presentation Layer. This project appears in the source code as UIPABWin4.proj. In effect � the project should look exactly like the original Windows Application we used i.e. UIPABWin1.proj � which consisted of five forms and stub code: Form1, frmList, frmPerson, frmAddress, frmContact and their constituent controls and relevant event handlers. (Refer to article 1 for the set up instructions.) The project must reference the UIPAB Version 2 and CMAB (Config Management App Block). I will leave UIPABWin4 for now and will be returning to it after I have coded the UIPAB controller for this application.

UI PROCESS LAYER

Create a new class library in the UI Process layer of the Presentation Layer. I have called the project UIPABController.proj. (Note: despite the name controller, this controller is really the Model for your UI). I reference the UIPAB v2 Application Block and the EMAB (Exception Management Block) in my project. Also, my UI will interact with the Presentation and Data Layers through the intermediary of UI Process. I therefore reference UIPABBE (the Business Layer) and UIPABData (the Presentation Layer) (Article 1 in this series explained how to set up those layers).

I am now going to code a single class which I have called UIController. This class inherits from the UIPAB ControllerBase class. It is this class which is at the heart of my UIPAB UI. I have created the class in a layer all of its own. The class is independent of my UI (the UIPABWin4 project). As you will shortly see, my UIController, because it is independent, will allow for its reuse.

I want my UIController to take care of:

Because the UIPAB does all the plumbing for workflow and state, all my UIController will do in these arenas are:

I find it convenient to divide my ControllerBase classes such as UIController into three main regions:

I will now step through the UIController code in detail �as this the most important code block in the UIPAB example.

The class inherits from BaseController and uses the UIPAB, the EMAB, UIPABBE and UIPABData.

using System;
using System.Collections;

using Microsoft.ApplicationBlocks.UIProcess;
using Microsoft.ApplicationBlocks.ExceptionManagement;

using UIPABBE;
using UIPABData;

namespace UIPABController
{

  public class UIController: ControllerBase
}

The contractor takes a Navigator object or name as its parameter:

public UIController(Navigator nav):base(nav){}

The Controller API consists of a number of public methods and properties. I divide my Controller API into two regions: State (which consist of property getters only) and Navigation (which are public methods).

UIController has four properties corresponding to the four entities in my application (which also correspond to the four forms in my UI).

The state property code looks like this (note the use of the UIPAB State class).

#region STATE

public ArrayList UIList
{
  get
  {
    if(State["PersonList"] == null)
    State["PersonList"] = PersonData.getPersonsList();
    return State["PersonList"] as ArrayList;
  }        
}
public Person UIPerson
{get{return State["Person"] as Person;}}

public Address UIAddress
{get{return State["Address"] as Address;}}

public Contact UIContact
{get{return State["Contact"] as Contact;}}

#endregion

The navigation methods correspond to UI actions. I prefer a granular approach. That is to say: one navigational method for each UI navigational trigger. In large navigational schemas this might mean a plethora of navigational methods, but the methods remain small, clean and easy to maintain. Also, when a navigational event is triggered, the Controller class must be informed of the navigational value. I have seen this value passed from the UI to the Controller (indeed this is what the supplied examples do). This approach makes the controller dependent on the UI and so is something we have to avoid. What I do is associate navigational values with methods in the Controller itself � thereby guaranteeing complete independence to my Controller.

The following is a map of UI events to UIController Navigational methods (keep in mind the workflow diagram in Article 1 for reference):

VIEW CONTROL EVENT CONTROLLER NAV METHOD
frmList btnNew_Click toNewPerson()
lb_DoubleClick toExistingPerson(string id)
btnEnd_Click updateList()
frmPerson btnAddress_Click toNewAddress()
lbAddress_DoubleClick toExistingAddress(string id)
btnContact_Click toNewContact()
lbContact_DoubleClick toExistingContact(string id)
btnDone_Click updatePerson()
frmAddress btnDone_Click updateAddress()
frmContact btnDone_Click updateContact()

The navigational methods follow a pattern. There are three types of methods for each entity or view i.e. toNew, toExisting and update. Each navigational method calls a private domain logic method and then makes a call to the Nav method, which call the Navigate method of the base class and passes the navigation value.

public void Nav(string navValue){this.Navigate(navValue);}

I give the Person navigational methods here by way of example:

public void toNewPerson()
{
   newPerson();
   Nav("toPerson");
}
public void toExitingPerson(object obj)
{
  if(obj is Person)
    getPerson(((BaseBE)obj).ID);
  else
    getPerson(obj.ToString());
  Nav("toPerson");
}

public void upddatePerson()
{
  State["PersonList"] = this.UIList;
  State.Remove("Person");
  Nav("toList");
}

Pay attention to the following:

The remainder of the class consists of UI Process Domain logic. These are private methods which are basically helper methods to the UIController API methods and properties. In this particular application the UI Process Domain logic is divided into two distinct types:

That is basically all there is to Controller. Compile it and return to the UI layer and UIPABWin4 project.

FINAL REFACTOR OF UI PROJECT

Back to UIPABWin4 and what remains to do is the following:

Firstly, reference the UIPABController project. Our views need a handle to UIController. The way I propose to do this is different from the way demonstrated in the examples with the UIPAB � however I think this way is more elegant.

I create a new WindowsForm and call its baseForm which will inherit from WindowsFormView and will use the UIPAB and UIPABController:

using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;

using Microsoft.ApplicationBlocks.UIProcess;
using UIPABController;

namespace UIPABWin4
{
     public class baseForm : WindowsFormView
     {}
}

All implementations of the UIPAB IView interface had a Controller property which returns the controller associated with the View. I will modify the Controller property and cast it as UIController in a protected property called TaskController.

protected UIController TaskController{get{return 
  (UIController)Controller;}}

I now go to each view (WindowsForm) participating in the UIPAB task and make each WindowsForm inherit from baseForm. This way, my forms all inherit from WindowsFormView and have access to the TaskController property. In the UIPABWin4 � this is done to the following forms: frmList, frmPerson, frmAddress and frmPerson.

public class frmPerson : baseForm
{ �}

Each view has a form load event handler where the other event handlers are hooked up. The form load event handler also binds the necessary state to the controls in the form.

private void frmPerson_Load(object sender, EventArgs e)
{
  TaskController.State.StateChanged +=
    new Microsoft.ApplicationBlocks.UIProcess.State.
      StateChangedEventHandler(State_StateChanged);
  btnAddress.Click +=new EventHandler(btnAddress_Click);
  btnContact.Click +=new EventHandler(btnContact_Click);
  btnDone.Click +=new EventHandler(btnDone_Click);
  lbAddress.DoubleClick +=new EventHandler(lbAddress_DoubleClick);
  lbContact.DoubleClick +=new EventHandler(lbContact_DoubleClick);

  txtFirst.Text = TaskController.UIPerson.Firstname;
  txtLast.Text = TaskController.UIPerson.Lastname;
  lbAddress.DataSource = TaskController.UIPerson.Addresses;
  lbContact.DataSource = TaskController.UIPerson.Contacts;
}

Pay attention to the following:

Now all that remains is to code the event handlers in each form. The code here is simple, short and intuitive. I give the frmPerson event handlers as an example:

private void btnAddress_Click(object sender, EventArgs e)
{
   TaskController.toNewAddress();
}
private void btnContact_Click(object sender, EventArgs e)
{
  TaskController.toNewContact();
}
private void btnDone_Click(object sender, EventArgs e)
{
  TaskController.UIPerson.Firstname = txtFirst.Text;
  TaskController.UIPerson.Lastname = txtLast.Text;
  TaskController.upddatePerson();
  this.Close();
}
private void lbAddress_DoubleClick(object sender, EventArgs e)
{
  if(lbAddress.SelectedItems.Count == 0)return;
  TaskController.toExistingAddress(lbAddress.SelectedItems[0]);
}
private void lbContact_DoubleClick(object sender, EventArgs e)
{
  if(lbContact.SelectedItems.Count == 0)return;
  TaskController.toExistingContact(lbContact.SelectedItems[0]);
}

Pay attention to the following:

The last event handler handles the state changed event of the State object. This handler updates my various bound list-boxes when the appropriate state changes i.e. when I change or add a new address or contact in this example. What we have here is a type of Observer pattern implementation using delegates.

private void State_StateChanged(object sender, 
   StateChangedEventArgs e)
{
    if(TaskController.UIPerson != null)
    {
    CurrencyManager man1 = BindingContext[
        TaskController.UIPerson.Addresses] as CurrencyManager;
    if(man1!=null)man1.Refresh();
    CurrencyManager man2 = BindingContext[
        TaskController.UIPerson.Contacts] as CurrencyManager;
    if(man2!=null)man2.Refresh();
    }
}

Pay attention to the following:

This is to guarantee that the state changed event is triggered.

What is left is to launch the UIPAB and I do this in the btn_Click event handler of Form1. Note that Form1 does not participate in the Task and when you see the configuration, you will notice it is also not configured. Because I am using the Graph navigator the UIPAB initialization is as follows:

UIPManager.StartNavigationTask("Nav");

CONFIGURING THE APP.CONFIG FOR UIPAB

All I have to do now is configure the App.config file of UIPABWin4.proj. A word of warning, and I say this from bitter experience: if something is not working in your UIPAB app, it is probably because you have incorrectly configured the UIPAB app.config.

I will take this opportunity to issue a challenge to all of my readers (and to Microsoft): the App Blocks rely heavily on configurations to the app.config. The more App Blocks you use, the more your app.config will become unwieldy, the more you are guaranteed to make a mistake which sometimes takes hours to detect. The App Block configurations follow a fixed schemas with pre-defined lists of possible attributes and elements. The challenge is to write an application that will allow you � wizard like � to create app.config files for each App Block. (I am working on this at the moment � just to help me from continually mistyping or forgetting a quotation mark or an attribute template in my App Block app.configs.)

The first configuration is authoring a <section> element in the app.config�s <configSections> element. This <section> element is mandatory and is standard � you can cut paste it in every UIPAB configuration you ever author. The name of the section is �uipConfiguration�.

<configuration>
   <configSections>
     <section name="uipConfiguration"                 
      type="Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler,
      Microsoft.ApplicationBlocks.UIProcess,
      Version=1.0.1.0,Culture=neutral,PublicKeyToken=null"/>
    </configuration>
</configSections>
        

The rest of the configuration occurs in the <uipConfiguration> element which is a child element of <configuration>. <uipConfiguration> in its simplest form has three elements: <objectTypes>. <views>, <navigationGraph>.

<configuration>
   <configSections>
   <section name="uipConfiguration"                
 type="Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler,
Microsoft.ApplicationBlocks.UIProcess,
 Version=1.0.1.0,Culture=neutral,PublicKeyToken=null"/>
   </configuration>

  <uipConfiguration>        
      <objectTypes>
            
      </objectTypes>

      <views>
        
      </views>

      <navigationGraph>

      </navigationGraph>
  </uipConfiguration>

</configSections>

        

<objectTypes> must define four types each with a name and a type attribute:

The <views> element list each view in the Task within its own <view> element. Each view is assigned a name; the type is the full-namespace and assembly of the actual windows form. Also, each <view> must be associated with a controller as defined in <objectTypes>. Notice that on my List <view> and Person <view> I have used the optional �stayOpen� attribute which I have set to true. (This is not the time to get into the details � but the UIPAB behaves unpredictably when StateChanged event is called in forms which do not have �stayOpen� set as true. (I admit � it might a misunderstanding on my part � and I would welcome assistance.)

The <navigationGraph> consists of a number of attributes and a number of <node> elements. These <nodes> are navigational nodes and essentially map the workflow scenarios for each view. The <navigationGraph> must be assigned a name; it is this name that is referenced when the application launches the UIPAB for this specific Task. The other <navigationGraph> attributes are:

Each <node> is associated with a <view> as defined in <views>. Each navigational route in the view (corresponds to the event handlers in my example) must have a value - �navigateValue� - which is called in my UIController navigational methods; and a destination (�view�) � signifying which view must be activated when the navigational method is called.

REUSING CONTROL FOR ASP.NET APP

I will very quickly show you how to reuse your UI Process Layer i.e. the UIController in a Web version of the my UIPABWin4. The source code for the web version is in the download as UIPABWeb.proj which is an ASP.NET application.

I am not going to dwell on the code of the web application because it is exactly the same as the code for the windows application � with a slight modification to cater for the Web controls. Indeed, this is an extreme example where not only is the UI Process code reused, but the actual UI code is the same.

UIPABWeb has the same references: UIPAB, MCAB and UIPABController.

UIPABWeb has the exact same number of views and I have even named them same: Form1, frmList, frmPerson, frmAddress and frmContact. There is also a baseForm which here inherits from WebFormView and not WindowsFormView. frmList, frmPerson, frmAddress and frmContact all inherit for baseForm and all have the same event handlers as the windows application. In fact, if you examine the code in the event handlers, even the code is the same as in the windows application with slight variations to cater for the web controls. The frmPerson is given here as an example:

private void Page_Load(object sender, System.EventArgs e)
{
   btnContact.Click +=new EventHandler(btnContact_Click);
   btnAddress.Click +=new EventHandler(btnAddress_Click);
   btnDone.Click += new EventHandler(btnDone_Click);
   grdContact.ItemCommand +=new DataGridCommandEventHandler(
     grdContact_ItemCommand);
   grdAddress.ItemCommand +=new DataGridCommandEventHandler(
     grdAddress_ItemCommand);

    if(!Page.IsPostBack)
    {
      txtFirst.Text = TaskController.UIPerson.Firstname;
      txtLast.Text = TaskController.UIPerson.Lastname;
      grdContact.DataSource = TaskController.UIPerson.Contacts;
      grdAddress.DataSource = TaskController.UIPerson.Addresses;
      this.DataBind();
    }
}
private void btnContact_Click(object sender, EventArgs e)
{
   TaskController.toNewContact();
}
private void btnAddress_Click(object sender, EventArgs e)
{
  TaskController.toNewAddress();
}
private void btnDone_Click(object sender, EventArgs e)
{
  TaskController.UIPerson.Firstname = txtFirst.Text;
  TaskController.UIPerson.Lastname = txtLast.Text;
  TaskController.upddatePerson();
}
private void grdContact_ItemCommand(object sender, 
  DataGridCommandEventArgs e)
{
  DataGridItem item = (DataGridItem)e.Item;
  TaskController.toExistingContact((item.Cells[0].Text));    
}
private void grdAddress_ItemCommand(object sender, 
  DataGridCommandEventArgs e)
{
  DataGridItem item = (DataGridItem)e.Item;
  TaskController.toExistingAddress((item.Cells[0].Text));    
}

Form1 initiates the UIPAB the same way as the corresponding form in the windows application. Certain modification must be made to the configuration:

Now I dare you to tell me that that is not code-reuse in the truest sense of the term.

CONCLUSION & WHAT�S NEXT

In this article I have shown how the UIPAB is a type of MVC pattern and why the MVC should be the standard architecture for all UIs. I then took you through a whirlwind tour of UIPAB, highlighting the essential elements and general architecture, trying to show how UIPAB corresponds to MVC. (The App Block comes with a detailed under-the-hood documentation which is not necessary to begin using UIPAB but should, nevertheless, be studied to get a full understanding of the mechanics and the features.)

Using the Presentation and Data Layers, and general UI elements and work flows I designed in the first article, I then refactored that application to use UIPAB. I tried to demonstrate a structured approach to designing UIPAB. Admittedly, the example was simple � using only a single Task and no State persistence. However, I believe the example supplies you with the conceptual and practical understanding which will make mastering the advanced features easy. The hard part is getting the fundamentals right.

Lastly, I showed you how easy it is to reuse UIPAB code in a completely different environment, converting my Windows Application to an ASP.NET application, reusing or duplicating most of the code.

In the last and final article in this series, I will expand on our example by including more tasks, transitions, persistence and different navigational scenarios. I will also briefly touch on UIPAB customization.

Reference

I am have tried to upload my new credentials to CodeProject but am battling. If you want to contact me - have a look at my website www.pdev.co.za or email me at ayal@pdev.co.za>

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionSystem.Xml.Schema.XmlSchemaException was unhandled by user code
sjpjs
21:37 20 Nov '07  
I opened a new solution in VS2005 and added all projects. I am getting below error message when

UIPManager.StartNavigationTask("Nav");

line is executed in Form1. Please let mw know what corrective action I need to take to run the demo successfully.

The route is as below:
StartNavigationTask -> public static UIPConfigSettings Config -> public object Create(object parent, object input, XmlNode section) -> private void ValidateSchema( XmlNode section )

Finally I am getting below error message at
validatingReader.Schemas.Add( XmlSchema.Read( new XmlTextReader( streamReader ), null ) );

--- Error message ---
System.Xml.Schema.XmlSchemaException was unhandled by user code
Message="Wildcard '##any' allows element 'statePersistenceProvider', and causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence."
Source="System.Xml"
LineNumber=67
LinePosition=9
SourceUri=""
StackTrace:
at System.Xml.Schema.BaseProcessor.SendValidationEvent(XmlSchemaException e, XmlSeverityType severity)
at System.Xml.Schema.SchemaCollectionCompiler.CompileElement(XmlSchemaElement xe)
at System.Xml.Schema.SchemaCollectionCompiler.CompileParticleElements(XmlSchemaComplexType complexType, XmlSchemaParticle particle)
at System.Xml.Schema.SchemaCollectionCompiler.CompileParticleElements(XmlSchemaComplexType complexType, XmlSchemaParticle particle)
at System.Xml.Schema.SchemaCollectionCompiler.CompileCompexTypeElements(XmlSchemaComplexType complexType)
at System.Xml.Schema.SchemaCollectionCompiler.Compile()
at System.Xml.Schema.SchemaCollectionCompiler.Execute(XmlSchema schema, SchemaInfo schemaInfo, Boolean compileContentModel)
at System.Xml.Schema.XmlSchema.CompileSchema(XmlSchemaCollection xsc, XmlResolver resolver, SchemaInfo schemaInfo, String ns, ValidationEventHandler validationEventHandler, XmlNameTable nameTable, Boolean CompileContentModel)
at System.Xml.Schema.XmlSchemaCollection.Add(String ns, SchemaInfo schemaInfo, XmlSchema schema, Boolean compile, XmlResolver resolver)
at System.Xml.Schema.XmlSchemaCollection.Add(XmlSchema schema, XmlResolver resolver)
at System.Xml.Schema.XmlSchemaCollection.Add(XmlSchema schema)
at Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler.ValidateSchema(XmlNode section) in C:\Program Files\Microsoft Application Blocks For .Net\User Interface Process 2.0\Code\Microsoft.ApplicationBlocks.UIProcess\Configuration\UIPConfigHandler.cs:line 82
at Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler.Create(Object parent, Object input, XmlNode section, IFormatProvider formatProvider) in C:\Program Files\Microsoft Application Blocks For .Net\User Interface Process 2.0\Code\Microsoft.ApplicationBlocks.UIProcess\Configuration\UIPConfigHandler.cs:line 63
at Microsoft.ApplicationBlocks.UIProcess.UIPConfigHandler.Create(Object parent, Object input, XmlNode section) in C:\Program Files\Microsoft Application Blocks For .Net\User Interface Process 2.0\Code\Microsoft.ApplicationBlocks.UIProcess\Configuration\UIPConfigHandler.cs:line 50
at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionImpl(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
at System.Configuration.RuntimeConfigurationRecord.RuntimeConfigurationFactory.CreateSectionWithRestrictedPermissions(RuntimeConfigurationRecord configRecord, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
at System.Configuration.RuntimeConfigurationRecord.CreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader)
at System.Configuration.BaseConfigurationRecord.CallCreateSection(Boolean inputIsTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentConfig, ConfigXmlReader reader, String filename, Int32 line)


Thanks,
sjpjs
GeneralOpen Navigator
SudheendraKurudumale
4:47 15 Mar '06  
Hi, I am using UIP application block 2.0 with MemoryPersistState.I am
starting the screen by using Startopennavigationtask(Navname
,Firstviewname). After this screen gets loaded action on the screen
,action on this screen opens one more screen . The Problem I am facing
is the first screen does not close though I have mentioned IsStayopen as
false in config file. How to get the task id created by firstscreen so
that I can open second screen with same task id .(CUrrently I am opening
second screen with Startopennavigationtask (Navname ,Firstviewname).
this may be creating this problem).

Main feature I need Always only one screen should be visible .
Any help is appreciated

Thanks
Sudheendra


Sudheendra
GeneralWinForms all over the place
JimBoone
8:13 22 Feb '06  
I'm working on my first project with UIP. I have the forms displaying and the navigation working. The problem is that every time I navigate to a new view the form opens in a different spot, usually 20 or so pixels down and to the right of the old form. I cannot seem to set the location in the constructor of the form. I also cannot close the launcher form from the navigated forms/views.

Jim
Generalcontroller is model??
m-i-k-e
7:37 12 Feb '06  
Hi,
I have enjoyed your articles very much. Thanks a bunch.
Would you elaborate on the following comment.

"Controller is an unfortunate nomenclature because the Controller in actual fact is the Model and not the Controller in the MVC trinity"

Thanks again.
Mike
GeneralWhere is the script for UIPState
jchsiung2
19:07 28 Sep '05  
The Data.sql just create DATABASE UIPAB. Does any one know where is the script to create UIPState?

Most of the people runs OK. But I have trouble with this.

Thanks ahead

GeneralRe: Where is the script for UIPState
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
13:37 25 Oct '05  
The script to create UIPState (and UIPstore) and are part of the UIPAB install and can be run from there.
GeneralGraph & User control Navigator.
ramrex
23:19 11 Aug '05  
Hi,

I'm stuck. I have a graph navigator(GN) which is being used by most of my forms (eg. form1, form2, form3). Now I have a summary form which is also being navigated thru th GN.

Once in the summary form user is able to see a snapshot of the complete data entered in the all the forms(form1, form2, form3). Here i need to provide a mechanism wherein the user can double click some entry in the summry page and this would take him to an appropriate form where the data is entered (user should be taken to form1->tab11 or tab12 depending on what lin khe has entered)

To make this happen I would have to use a user control navigator. Meaning I would have all the tabs in the forms defined as usercontrol and make entries in the config file, so that I can easily navigate from one form to the other. This would work well only if my form (form1->tab12 or tab11) is not dependend on the state present in GN. If its dependent on state then I would not be able to access any state related info as I would be in the Usercontrol Navigator (UN) domain.

How do i get around this ?? I have to use state to store some info which would be used in the form.
GeneralWork with Framework 2.0?
dekar
7:31 28 Jul '05  
Does the UIPAB works with the Framework 2.0 and if so do you have an example? I tried using it but getting config errors.

Any help.
GeneralRe: Work with Framework 2.0?
SDP
8:08 10 Nov '05  
Yes it works, just convert the block's project in VS2005, recompile, and you can start using it !


steph
GeneralRe: Work with Framework 2.0?
keefb
5:36 26 May '06  
You have to watch out though, there are two problems I've come across so far, resolutions for these were found in the forum at:

http://forums.asp.net/713774/ShowPost.aspx[^]

The entry in the forum poted on 10-13-2005, 4:01 AM by tannerel, deals with a problem I had when I wanted to use the web session to persit the UIPAB state as .NET 2.0 xsd validation has changed since 1.1

The entry immediately after that deals with the second problem I had: controller code needs to go into separate assemblies to allow referencing of the controllers in the web.config UIPAB section as it takes an assembly name.

GeneralUsing Configuration AB in UIPAB
MayureeD
0:09 6 May '05  

Hello,

Can we use MS Configuration Application Block to set UIP configurations(views, navigationgraph etc.). If we set configurations through Enterprise Library Configuration interface, the configuration block creates a separate configuration file for each Application Block configuration settings(Ex: it creates 'dataconfiguration.config' for Data Access AB). Can we use this block to set(create) configurations for UIPAB through Enterprise Library Configuration interface? OR do we need to create separate configuration file for UIP configurations manually?

Alos how to using Configuration Block in UIP block to read or write UP configurations? what methods do we need to call for this?

Please can you give some sample code for this?

Thank you.

GeneralSessionStatePersistence using UIPAB
IISPL
23:50 5 May '05  
Hello,

Can you tell me what steps i need to follow to implement SessionStatePersistence in a web application. i have referenced UIP block in my application. We have one task : 'customer creation' with 4 steps wizard. We are navigating using NavigationGraph method. I want to know how to assign taskid to this task and how to implement state persistence with ASP.NET session object (SessionStatePersistence) for the task(process) started. What methods do i need to call for this and from where i need to call them?

Can you give any sample code with simple SesstionStatePersistence implementations for web application.

Please help ASAP.

Thank you
GeneralWinforms UIP AB
sanjay_work
6:35 6 Apr '05  
Confused I am trying to use the layoutManager for a winforms project and stuck up. I have tried fathoming the mystery but have got 2 or 3 different errors which are not very helpful.

The documentation seems to be pretty cryptic around this feature.

I would really appreciate some help in a sample layoutManager class that works. Specifically how is the LayoutControls method to be implemented and what argument should it accept.

The documentation from UIP AB is pasted below:

"
To lay out controls on your views in a customized manner, you need to create a class that implements the ILayoutManager interface and defines the LayoutControls method. The ILayoutManager interface has one public method called LayoutControls. For more information about the ILayoutManager, see ILayoutManager Interface.

You also need to specify each of your custom layout managers in the <objectTypes> section of the configuration file, and specify the layout manager attribute for each view that uses the custom layout manager in the section of the configuration file.

When the view is activated, if you have defined a layout manager and have specified the view to use the layout manager in the configuration file, the view manager calls the LayoutControls method on your layout manager and places the controls in the correct order. This method positions each control on the parent control that is passed as a parameter to this method (which is the form being activated).
"
GeneralRe: Winforms UIP AB
V-I-C-K-Y
4:58 16 Jan '07  
Hi,
Confused Was there any reply for this Message??


Vicky (())

GeneralStatless Middle Tier Using UIPAB
ragaramm
23:48 18 Jan '05  
Hi,
I have a requirement for not using state persistence feature of UIPAB, ne help on how can I proceed? What configuration needs to be changed in web.config??

GeneralTemplate Location
Dave Moyle
14:34 18 Jan '05  
http://gotdotnet.com/team/architecture/patterns/templates.aspx
GeneralPart 3, Third Article
dpdesi
12:26 9 Nov '04  
Where is third article we were promised ???
GeneralExplaination of how to implement?
Oppedal
4:56 6 Sep '04  
Hi
I have tried to implement all the downloaded code for this in a solutions file and "Add Existing project".
This do not work, because of the "UseProperties" tag in the csproj files for alle the projects. When I remove this tag, and save it, I succeed open them, but not building the solutions. It ask for a file AssemblyInfo.cs which is missing.

Any details for helping would be grately appriciated. Thanks.

AIO
GeneralRe: Explaination of how to implement?
sushmita _kumari
0:19 25 Feb '05  
The Assemblyinfo.cs is missing, Right ?? Do one thing, Create one new project with the same name eg. UIPABBE, UIPABData or UIPABController. And Add existing items i.e all the .cs files from the Download project. Remember do not add the Assemblyinfo.cs file.

rgds
Sonu Chauhan
AG Technologies,
Mumbai.
GeneralBug in UIPABData?
Mark Farmiloe
1:41 17 Aug '04  
I got the example application up and running, but it wasn't saving the data to the database. On investigation I found that there is a problem in the calls to the SqlHelper.ExecuteScaler, for example in insPerson. An array of SqlParameter's are passed as the third argument, when it should be just an array of object's - the actual parameter values.

On a second point, I'm using SQL Server v7 so I've replaced 'SCOPE_IDENTITY()' with '@@IDENTITY' which I think should be fine. I've also had to remove the 'ON DELETE CASCADE ON UPDATE CASCADE' bits. Can I simulate this be amending the triggers? (I'm definitely not an SQL Server guru).

BTW - Great set of articles to help get into a daunting area.

GeneralUIPAB with Oracle Database
aravala
11:07 13 Aug '04  
1. I am developing a mission critical application with multiple User Interfaces
(Windows,Web, PDA)

2. This application should support both SQL Server and Oracle databases

3. I know I have to change the Data Access Application Block to support Oracle, will
there be any other issues for using the UIPAB in my application ????..Unsure



Any suggestions on this will be greatly appreciated !!
GeneralRe: UIPAB with Oracle Database
SleeC
11:27 20 Nov '04  
Haven't done it ... but look at GotDotNet for the database independent version of Data Access AB used by UIPAB

http://www.gotdotnet.com/workspaces/workspace.aspx?id=c20d12b0-af52-402b-9b7c-aaeb21d1f431

Chris
GeneralError in App.Config code
Nilcrabab
17:35 5 Jul '04  
Hi having a read through your code and it looks like there is an error in your App.Config code.





Shouldn't the Configuration node close off before the configsections node??
GeneralThird Article
Ben Reierson
12:10 2 Jun '04  
Not to get on your back about this, but I'm really looking forward to seeing the third article in this series soon. I am working on a large project right now and I managed to convince them to use .NET and allow me to design the presentation pattern. I'm convinced the UIPAB2 is going to save us a lot of time, but I need to get my head around it and come up with a implementation strategy asap.

This client is going to need nearly all of the more advanced features in the UIPAB2, including wizards and user control navigation; but I have yet to find well-documented examples of these patterns in action.

Thanks for what you've done so far.


GeneralRe: Third Article
raop03
11:31 3 Nov '04  
when can I expect third article.


Last Updated 4 May 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010