Click here to Skip to main content
15,891,864 members
Articles / Web Development / ASP.NET

Win-Form/Web-Form Generic Components using the same Controller

Rate me:
Please Sign up or sign in to vote.
4.00/5 (7 votes)
5 Oct 2008CPOL7 min read 43.1K   1.1K   36  
A framework to develop Win-Form and Web-Form applications using generic components
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using Framework.baInterfaces;
using Framework.Lib;

namespace Framework.UI.baWebControls
{
    /// <summary>
    /// baBindingRelation component
    /// </summary>
    #region baBindingRelation Component
    [ToolboxData("<{0}:baBindingRelation runat=server></{0}:baBindingRelation>")]
    public class baBindingRelation : System.Web.UI.Control, IBindingRelation, IBindable
    {
        private IBindingManager oDetailBindingManager;
        private object oDetailForeignKey;
        private IBindingManager oMasterBindingManager;
        private object oMasterPrimaryKey;
        private RelationKind oRelation;

        /// <summary>
        /// An Instance of this object is being 
        /// created base on the kind of Relation
        /// </summary>
        private baGenericRelation oGenericRelation = null;

        #region Detail Binding Manager methods

        #region IBindingManager DetailBindingManager
        public IBindingManager DetailBindingManager
        {
            get
            {
                return oDetailBindingManager;
            }
            set
            {
                oDetailBindingManager = value;
            }
        }
        #endregion

        #region object DetailForeignKey
        public object DetailForeignKey
        {
            get
            {
                return oDetailForeignKey;
            }
            set
            {
                oDetailForeignKey = value;
            }
        }
        #endregion

        #endregion

        #region Master Binding Manager methods

        #region IBindingManager MasterBindingManager
        public IBindingManager MasterBindingManager
        {
            get
            {
                return oMasterBindingManager;
            }
            set
            {
                oMasterBindingManager = value;
            }
        }
        #endregion

        #region object MasterPrimaryKey
        public object MasterPrimaryKey
        {
            get
            {
                return oMasterPrimaryKey;
            }
            set
            {
                oMasterPrimaryKey = value;
            }
        }
        #endregion

        #endregion

        #region RelationKind Relation
        public RelationKind Relation
        {
            get
            {
                return oRelation;
            }
            set
            {
                try
                {
                    if (oRelation != value)
                    {
                        oRelation = value;
                        OnRelationChanged(this, new EventArgs());
                    }
                }
                catch (Exception baExp)
                {
                    throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
                }
            }
        }
        #endregion

        #region void DataBind()
        /// <summary>
        /// When Web page Bind Data being called this 
        /// event is being called as well.
        /// If component setting where okay, fetch data for
        /// all the binded detail managers
        /// </summary>
        public override void DataBind()
        {
            base.DataBind();
            if (oGenericRelation!=null)
                oGenericRelation.SetRelationTransactionState();
        }
        #endregion

        #region RelationChanged event
        public event EventHandler RelationChanged;
        protected void OnRelationChanged(object sender, EventArgs e)
        {
            if (RelationChanged != null)
                RelationChanged(sender, e);
        }
        #endregion

        #region IBindable  Bind()
        public void Bind()
        {
            switch (Relation)
            {
                case RelationKind.Lookup:
                    {
                        oGenericRelation = new baLookupRelation(this);
                        break;
                    }
                case RelationKind.MasterDetail:
                    {
                        oGenericRelation = new baMasterDetailRelation(this);
                        break;
                    }
            }
            if (oGenericRelation != null)
            {
                oGenericRelation.BindMasterBindingManager();
            }
            // Bind the related Binding Managers
            ((IBindable)MasterBindingManager).Bind();
            ((IBindable)DetailBindingManager).Bind();

            // Fire the Binded Event
            OnBinded(this, new EventArgs());
        }
        #endregion

        #region IBindable  Binded event
        public event EventHandler Binded;
        protected void OnBinded(object sender, EventArgs e)
        {
            if (Binded != null)
                Binded(sender, e);
        }
        #endregion

        protected override void Render(HtmlTextWriter writer)
        {
            if (this.DesignMode)
                writer.Write("<b>Relation:</b>" + this.ID);
            else
                base.Render(writer);
        }
    }
    #endregion

    /// <summary>
    /// An abstract relation class that can be both
    /// Lookup and Master Detail relations base on its instanciation
    /// </summary>
    #region abstract baGenericRelation class
    abstract public class baGenericRelation
    {
        protected baBindingRelation bindingRelation;

        #region baGenericRelation(baBindingRelation bindingRelation)
        public baGenericRelation(baBindingRelation bindingRelation)
        {
            this.bindingRelation = bindingRelation;
        }
        #endregion

        #region void FetchData(IBindingManager bManager)
        /// <summary>
        /// Calls the FetchData method of a binding manager
        /// </summary>
        /// <param name="bManager">The Binding Manager to be used</param>
        public void FetchData(IBindingManager bManager)
        {
            try
            {
                if (bManager != null)
                {
                    bManager.ClearDatasource();
                    bManager.DoFetchData();
                }
            }
            catch (Exception baExp)
            {
                throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
            }
        }
        #endregion

        public virtual void BindMasterBindingManager(){}

        public virtual void SetRelationTransactionState() { }
    }
    #endregion

    /// <summary>
    /// Lookup
    /// </summary>
    #region baLookupRelation class
    public class baLookupRelation : baGenericRelation
    {
        #region Constructor
        public baLookupRelation(baBindingRelation bindingRelation)
            : base(bindingRelation)
        {
        }
        #endregion

        #region void BindMasterBindingManager()
        public override void BindMasterBindingManager()
        {
            try
            {
                if (bindingRelation.MasterBindingManager != null)
                {
                    if (bindingRelation.DetailBindingManager != null)
                    {
                        FetchData(bindingRelation.MasterBindingManager);
                        bindingRelation.DetailBindingManager.Filter = "";
                        FetchData(bindingRelation.DetailBindingManager);
                        bindingRelation.DetailBindingManager.PositionChanged += new EventHandler(DetailBindingManager_PositionChanged);
                        bindingRelation.DetailBindingManager.TransactionStateChange += new TransactionStateChangeEventHandler(DetailBindingManager_TransactionStateChange);
                        if(!bindingRelation.Page.IsPostBack && !bindingRelation.DetailBindingManager.IsEmpty)
                            bindingRelation.DetailBindingManager.MoveFirst();
                    }
                }
            }
            catch (Exception baExp)
            {
                throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
            }
        }
        #endregion

        #region DetailBindingManager_PositionChanged(object sender, EventArgs e)
        void DetailBindingManager_PositionChanged(object sender, EventArgs e)
        {
            try
            {
                /// When detail binding manager position changes
                /// the Forign key of the Detail should have
                /// the primery key of the Master changed value
                if (bindingRelation.MasterBindingManager != null && (bindingRelation.DetailBindingManager != null))
                {
                    bindingRelation.MasterBindingManager.Find(bindingRelation.DetailBindingManager[bindingRelation.DetailForeignKey]);
                    if (bindingRelation.MasterBindingManager.IsEmpty)
                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Null;
                    else
                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.EditOnly;

                    //bindingRelation.DetailBindingManager.TransactionState = TransactionStateKind.Initial;
                    //DetailBindingManager_TransactionStateChange(this, new TransactionStateChangeArgs(TransactionStateKind.Null),
                    //    new TransactionStateChangeArgs(bindingRelation.DetailBindingManager.TransactionState));
                }
            }
            catch (Exception baExp)
            {
                throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
            }
        }
        #endregion

        #region DetailBindingManager_TransactionStateChange(object sender, TransactionStateChangeArgs Was, TransactionStateChangeArgs Will)
        void DetailBindingManager_TransactionStateChange(object sender, TransactionStateChangeArgs Was, TransactionStateChangeArgs Will)
        {
            switch (Was.TransactionState)
            {
                case TransactionStateKind.Delete:
                case TransactionStateKind.Edit:
                case TransactionStateKind.Add:
                    {
                        switch (Will.TransactionState)
                        {
                            case TransactionStateKind.Initial:
                            case TransactionStateKind.Confirm:
                                {
                                    Will.TransactionState = TransactionStateKind.Initial;
                                    if (bindingRelation.MasterBindingManager.IsEmpty)
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Null;
                                    else
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.EditOnly;
                                        //bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.SearchOnly;
                                    break;
                                }
                            case TransactionStateKind.EmptyDataSource:
                                {
                                    bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Null;
                                    break;
                                }
                        }
                        break;
                    }
                case TransactionStateKind.Null:
                case TransactionStateKind.Initial:
                case TransactionStateKind.EmptyDataSource:
                case TransactionStateKind.Confirm:
                    {
                        switch (Will.TransactionState)
                        {
                            case TransactionStateKind.Edit:
                            case TransactionStateKind.Add:
                                {
                                    if(bindingRelation.MasterBindingManager.IsEmpty)
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.EmptyDataSource;
                                    else
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Initial;
                                    break;
                                }
                            case TransactionStateKind.Initial:
                            case TransactionStateKind.Confirm:
                            case TransactionStateKind.EmptyDataSource:
                                {
                                    if(bindingRelation.MasterBindingManager.IsEmpty)
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Null;
                                    else
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.EditOnly;
                                    break;
                                }
                            case TransactionStateKind.Delete:
                                {
                                    bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Null;
                                    break;
                                }
                        }
                        break;
                    }
            }
        }
        #endregion

        #region void SetRelationTransactionState()
        /// <summary>
        /// Base on Master transaction state, set
        /// detail Transaction state
        /// </summary>
        public override void SetRelationTransactionState()
        {
            if (bindingRelation.DetailBindingManager != null)
            {
                switch (bindingRelation.MasterBindingManager.TransactionState)
                {
                    case TransactionStateKind.Edit:
                    case TransactionStateKind.Add:
                    case TransactionStateKind.Delete:
                        {
                            
                            bindingRelation.DetailBindingManager.Enabled = false;
                            break;
                        }
                    case TransactionStateKind.EmptyDataSource:
                    case TransactionStateKind.EditOnly:
                    case TransactionStateKind.AddEditOnly:
                    case TransactionStateKind.SearchOnly:
                        {
                            bindingRelation.DetailBindingManager.Enabled = true;
                            break;
                        }
                    case TransactionStateKind.Confirm:
                    case TransactionStateKind.Initial:
                        {
                            bindingRelation.DetailBindingManager.Enabled = true;
                            switch (bindingRelation.DetailBindingManager.TransactionState)
                            {
                                case TransactionStateKind.Edit:
                                case TransactionStateKind.Add:
                                case TransactionStateKind.Delete:
                                    {
                                        break;
                                    }
                                default:
                                    {
                                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.EditOnly;
                                        break;
                                    }
                            }
                            break;
                        }
                }
            }
            if (!bindingRelation.Page.IsPostBack && !bindingRelation.DetailBindingManager.IsEmpty)
            {
                bindingRelation.MasterBindingManager.Refresh();
                bindingRelation.DetailBindingManager.Refresh();
            }
        }
        #endregion
    }
    #endregion

    /// <summary>
    /// Master-Detail
    /// </summary>
    #region baMasterDetailRelation class
    public class baMasterDetailRelation : baGenericRelation
    {
        #region Constructor
        public baMasterDetailRelation(baBindingRelation bindingRelation)
            : base(bindingRelation)
        {
        }
        #endregion

        #region void BindMasterBindingManager()
        public override void BindMasterBindingManager()
        {
            try
            {
                if (bindingRelation.MasterBindingManager != null)
                {
                    FetchData(bindingRelation.MasterBindingManager);
                    bindingRelation.MasterBindingManager.PositionChanged += new EventHandler(MasterBindingManager_PositionChanged);
                    if (bindingRelation.DetailBindingManager != null)
                    {
                        bindingRelation.DetailBindingManager.TransactionStateChange += new TransactionStateChangeEventHandler(DetailBindingManager_TransactionStateChange);
                    }
                    SetDetailData();
                }
            }
            catch (Exception baExp)
            {
                throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
            }
        }

        #endregion

        #region MasterBindingManager_PositionChanged(object sender, EventArgs e)
        void MasterBindingManager_PositionChanged(object sender, EventArgs e)
        {
            try
            {
                SetDetailData();
            }
            catch (Exception baExp)
            {
                throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
            }
        }
        #endregion

        #region void SetDetailData()
        /// <summary>
        /// When relation is in MasterDetail mode, Set 
        /// call detail fetch method with proper filter
        /// </summary>
        private void SetDetailData()
        {
            try
            {
                if (bindingRelation.MasterBindingManager[bindingRelation.MasterPrimaryKey] != null
                    && (bindingRelation.DetailBindingManager != null))
                    {

                        bindingRelation.DetailBindingManager.Filter = bindingRelation.DetailForeignKey
                            + " = " + bindingRelation.MasterBindingManager[bindingRelation.MasterPrimaryKey];
                        FetchData(bindingRelation.DetailBindingManager);
                        if (bindingRelation.DetailBindingManager.Count > 0 &&
                            !bindingRelation.DetailBindingManager.Exist(bindingRelation.DetailBindingManager["ID"]))
                            if (bindingRelation.DetailBindingManager.TransactionState == TransactionStateKind.Add)
                                /// If New record is being added to Detail list then move 
                                /// to the last row which is the currently added record
                                bindingRelation.DetailBindingManager.MoveLast();
                            else
                                /// Move to first record in detail list because
                                /// the row being pointed is not in the current
                                /// detail list, It should be in previous detail 
                                /// selection list
                                bindingRelation.DetailBindingManager.MoveFirst();
                    }
            }
            catch (Exception baExp)
            {
                throw new baException(baExp, System.Reflection.MethodBase.GetCurrentMethod());
            }
        }
        #endregion

        #region DetailBindingManager_TransactionStateChange(object sender, TransactionStateChangeArgs Was, TransactionStateChangeArgs Will)
        void DetailBindingManager_TransactionStateChange(object sender, TransactionStateChangeArgs Was, TransactionStateChangeArgs Will)
        {
            switch (Will.TransactionState)
            {
                case TransactionStateKind.Initial:
                    {
                        if (bindingRelation.MasterBindingManager.TransactionState == TransactionStateKind.EmptyDataSource)
                            Will.TransactionState = TransactionStateKind.Null;
                        break;
                    }
                case TransactionStateKind.Add:
                case TransactionStateKind.Edit:
                case TransactionStateKind.Delete:
                    {
                        bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Null;
                        break;
                    }
                default:
                    {
                        switch (Was.TransactionState)
                        {
                            case TransactionStateKind.Add:
                            case TransactionStateKind.Edit:
                            case TransactionStateKind.Delete:
                                {
                                    bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Initial;
                                    break;
                                }
                        }
                        break;
                    }
            }
        }
        #endregion

        #region void SetRelationTransactionState()
        /// <summary>
        /// Base on Master transaction state, set
        /// detail Transaction state
        /// </summary>
        public override void SetRelationTransactionState()
        {
            switch (bindingRelation.MasterBindingManager.TransactionState)
            {
                case TransactionStateKind.Edit:
                case TransactionStateKind.Add:
                case TransactionStateKind.Delete:
                case TransactionStateKind.EmptyDataSource:
                    {
                        if (bindingRelation.DetailBindingManager != null)
                            bindingRelation.DetailBindingManager.TransactionState = TransactionStateKind.Null;
                        break;
                    }
                case TransactionStateKind.Confirm:
                case TransactionStateKind.EditOnly:
                case TransactionStateKind.AddEditOnly:
                case TransactionStateKind.SearchOnly:
                case TransactionStateKind.Initial:
                    {
                        if (bindingRelation.DetailBindingManager != null)
                        {
                            switch (bindingRelation.DetailBindingManager.TransactionState)
                            {
                                case TransactionStateKind.EmptyDataSource:
                                case TransactionStateKind.EditOnly:
                                case TransactionStateKind.AddEditOnly:
                                case TransactionStateKind.SearchOnly:
                                case TransactionStateKind.Initial:
                                case TransactionStateKind.Confirm:
                                    {
                                        bindingRelation.DetailBindingManager.TransactionState = TransactionStateKind.Initial;
                                        if (bindingRelation.DetailBindingManager.IsEmpty)
                                        {
                                            bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.Initial;
                                        }
                                        else
                                        {
                                            bindingRelation.MasterBindingManager.TransactionState = TransactionStateKind.AddEditOnly;
                                        }

                                        break;
                                    }
                            }
                        }
                        break;
                    }
            }
        }
        #endregion
    }
    #endregion
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Canada Canada
Software development experience since 1993

Skills
- Programming Languages: C# .NET, Delphi, C++, Java and VB
- Development Methodologies (SDLC): RUP, Scrum and XP
- Database: SQL server, Oracle, Apollo database and MS Access.

Educations & Certificates
- Microsoft® Certified Professional (MCP)
- Sun® Certified Java2 Programmer
- B.S. in computer science

Comments and Discussions