Introduction
The objective of this article is to introduce a framework to create Windows and Web applications with almost the same look and feel using maximum code reuse.
The sample codes have UI components that are common to various kinds of User Interfaces. That means: having generic UI Components that can be accessed using common Interfaces. For example: A Generic
TextBox
with a common
Text
property in
ITextBox
interface that can be used in both Web and Windows applications. Obviously, there are some limitations to this approach, but depending on business needs, those limitations can also be mitigated. All the generic components are bindable, for example the Windows and Web components implementing
ITreeView
interface can be bonded to a table with recursive relation.
Following are a few generic components used in the sample codes provided:
- Framework.UI.baWebControls
- class
AddEditDelete
: System.Web.UI.WebControls.WebControl
, IAddEditDelete
- class
baButton
: System.Web.UI.WebControls.Button
, IButton
- class
baComboBox
: System.Web.UI.WebControls.DropDownList
, IComboBox
- class
baGrid
: System.Web.UI.WebControls.GridView
, IGrid
- class
baTextBox
: System.Web.UI.WebControls.TextBox
, ITextBox
- class
baTreeView
: System.Web.UI.WebControls.TreeView
, ITreeView
- class
baBindingManager
: ObjectDataSource
, IBindingManager
- Framework.UI.baWinControls
- class
AddEditDelete
: System.Windows.Forms.UserControl
, IAddEditDelete
- class
baButton
: System.Windows.Forms.Button
, IButton
- class
baComboBox
: System.Windows.Forms.ComboBox
, IComboBox
- class
baGrid
: System.Windows.Forms.DataGridView
, IGrid
, IState
- class
baTextBox
: System.Windows.Forms.TextBox
, ITextBox
, IState
- class
baTreeView
: Framework.UI.baWinControls.TreeViewStrategy
, ITreeView
- class
baBindingManager
: System.Windows.Forms.BindingSource
, IBindingManager
Using the Code
Developing an application is divided into the following two solutions:
- App.Development.sln: develop interfaces based on business needs. Identified as yellow color in the following figure.
- Framework.Development.sln: develop components for both UI kinds. Identified as white color in following figure.
Windows Form UI
(App.WinForm)
| Web Form UI
(App.WebForm)
| Unit Tests
(App.Test)
| Data Transfer Object
(App.DataSets)
| Framework Common
(Framework.Lib)
(Framework. baInterfaces)
(Framework.UI. baController)
(Framework.UI. baResources)
|
(Framework.UI. baWinControls)
| (Framework.UI. baWebControls)
| (Framework.UI. baWinControls)
|
UI Controller
(App.Controller)
|
Business
(App.BusinessController)
|
Data Access Layer (DAL)
(Framework.DAL)
| | |
Refer to the sample code: We have a Form (GeoForm
that implements IGeoForm
interface) with a bunch of Components in it (GeoTblGrid
implements IGrid
, GeoTblTreeView
implements ITreeView
and EntityCombo
implements IComboBox
all inside IGeoForm
). Each form has a Controller
object that implements an interface (IGeoForm
) to hold and use generic components that are being used in both Windows and Web. In the Controller; developer can implement UI behaviors and use Business Logic Layer and other services from the Framework common to all User Interfaces. The layering architect is as follows:
- Presentation Layer: A form/page that implements
IForm
interface holding a reference to a Controller
object that the form is being passed to it. - Controller Layer: Each form/page has a
Controller
object that works with generic components provided from the form interface to the controller.
Note: GeoCtrl Controller
object has a reference to the form that implements IGeoForm
interface to work with its generic Components.
In both Windows and Web solutions; we create a User Interface folder (UI Folder) such as GeoFrm Form
in BaseFrm folder and in both we identify the Generic Components we want to include in these pages using an interface called IGeoForm
.
public interface IGeoForm
{
string Caption{ get; set; }
ITextBox GeoTblName{ get; }
IGrid GeoTblGrid{ get; }
IGrid EntityTableGrid{ get; }
IComboBox GeoTblKind{ get; }
IAddEditDelete AddEditDel{ get; }
IBindingManager BindingManager{ get; }
IBindingManager DetailBindingManager{ get; }
IBindingRelation BindingRelation{ get; }
ITreeView GeoTblTreeView{ get; }
IComboBox EntityCombo{ get; }
ITextBox EntityTextBox{ get; }
IAddEditDelete addEditDelDetail{ get; }
}
For Windows Forms:
public partial class LookupForm : Form, IGeoForm
{
public LookupForm()
{
GeoCtrl ctrl = new GeoCtrl(this, RelationKind.Lookup);
}
}
And for Web-Forms:
public partial class LookupForm : WebPageBase, IGeoForm
{
protected void Page_Load(object sender, System.EventArgs e)
{
GeoCtrl ctrl = new GeoCtrl(this, RelationKind.Lookup);
}
}
For both of them, we create an instance of a Controller implementing IGeoForm
as stated in the above code (new GeoCtrl(this, RelationKind.Lookup)
). The controller is responsible for using the interfaces provided by generic components.
public class GeoCtrl
{
public IGeoForm theForm;
public GeoCtrl(IGeoForm theForm, RelationKind kind)
{
this.theForm = theForm;
}
}
In order to bind the generic TreeView
component (ITreeView
) to a data source (IBindingManager
):
- Drop a
baBindingManager
on the form - Set
Datasource
and DataMember
properties of the above BindingManager
- Drop a
baTreeView
on the same form - Set the following properties for the
TreeView
:
-
TreeViewComponent.BindingManager = theForm.BindingManager;
-
TreeViewComponent.TextField = "Name";
-
TreeViewComponent.ValueField = "ID";
-
TreeViewComponent.ValueParentField = "ParentID";
Points of Interest
- Almost all the interactions between Presentation layer (Including components and the hosting forms) and underneath layers are through predefined Interfaces. To create applications using this solution, one should provide interfaces for each user interaction component such as Web/Win components (
IGrid
, ITextBox
, ITextBox
,…) and forms/pages (IGeoForm
). The user interface components can contain other generic components (IGeoForm
contains IGrid
, ITextBox
, ITextBox
,…). A controller object can work with interfaces provided to implement business functionalities. - Using generic Components has its own limitations that can be mitigated based on business needs.
- Creating Interface for each Form and defining its Generic components and events can be done using proper Code Generator applications.
History
- 24th July, 2008: Initial post