Skip Navigation Links.

Northwind\WebControls\GridBase.cs

D:\NorthwindForWeb\Northwind\CS\DotNet\ADO.Net\Northwind\WebControls\GridBase.cs
/*
 * This file was generated by ProCG version 2.0
 *
 * File name:	Northwind\WebControls\GridBase.cs
 * Language:	C# - ADO.Net 
 * Database:	My Sql
 *
 * Copyright (c) 2002-2019 iGenXSoft.
 * For more information visit http://www.igenxsoft.com
 */



using System;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using log4net;
using Northwind.General;
using Northwind.Data;

namespace Northwind.WebControls
{
	/// <summary>
	/// Summary description for NorthwindGridBase.
	/// </summary>


	[ParseChildren(true)]
	[PersistChildren(false)]
	[Designer(typeof(Northwind.WebControls.NorthwindWebGridDesigner))]
	public abstract class NorthwindGridBase : System.Web.UI.WebControls.DataGrid, ISupportInitialize, INamingContainer
	{
		protected static readonly ILog log = LogManager.GetLogger(typeof(NorthwindPageBase));
		protected DataManager m_DataManager = null;
		protected IStructDataCollection m_RowsData;
		protected IStructDataCollection m_OriginRowsData;
		protected CStructData m_OriginRowData; // keeping the state before entering to edit the fields if null means a new row so cancel edit will remove the line
		protected NorthwindWebEnv m_WebEnv;
		protected Hashtable m_CellsPosition;
		protected EditModeEnum m_PageEditMode;
		protected EditModeEnum m_UserEditMode = 0;
		protected SelectionModeEnum m_SelectionMode;
		protected bool m_DesignMode = (System.Web.HttpContext.Current == null);
		protected Hashtable m_GridLineActionsName;
		public delegate void NewRowEventHandler(Object sender, EventArgs args);
		protected NorthwindToolBarWCC m_GridButtom;
		protected int m_LastSelectedDataIndex;
		protected IDictionary m_DataObjectsContainer;
		protected string m_DataInstanceName;
		protected string m_BubbleEventName;
		protected CFieldAttributeCollection m_FieldAttributeCollection;
		protected CFieldAttributeCollection m_UserFieldAttributeCollection;
		protected CFieldAttributeCollection m_EmptyFieldAttributeCollection;
		protected CFieldAttributeCollection m_FieldsCollectionToCreateTheGridBy;
		protected int m_FieldsListType = 0;
		protected bool m_EditAllRows = false;
		protected bool m_GridCreated = false;
		public delegate void GeneralWebEventHandler(Object sender, GeneralWebEvent args);
		public event GeneralWebEventHandler OnGeneralWebEvent;


		public NorthwindGridBase()
			: base()
		{
			m_EmptyFieldAttributeCollection = new CFieldAttributeCollection();
			m_RowsData = null;
			m_OriginRowsData = null;
			m_OriginRowData = null;
			m_DataObjectsContainer = null;

			m_CellsPosition = new Hashtable();
			// Default settings for the grid Pager
			PagerStyle.Mode = PagerMode.NumericPages;


			PagerStyle.PageButtonCount = 10;


			PagerStyle.HorizontalAlign = HorizontalAlign.Right;

			// Default settings for pagination
			AllowPaging = true;
			PageSize = 14;

			// Other visual default settings
			GridLines = GridLines.None;
			CellSpacing = 2;

			this.CssClass = "DataGridTable";
			CellPadding = 2;



			ForeColor = ColorTranslator.FromHtml("#000000");
			//Font.Size = FontUnit.Small;
			//Font.Name = "Arial";


			// Settings for heading  
			HeaderStyle.CssClass = "HeaderStyle";

			// Settings for SelectItemStyle
			SelectedItemStyle.CssClass = "SelectedItemStyle";
			//SelectedItemStyle.HorizontalAlign = HorizontalAlign.Center;

			// Settings for ItemStyle
			ItemStyle.CssClass = "ItemStyle";

			// Settings for ItemStyle
			AlternatingItemStyle.CssClass = "AlternatingItemStyle";

			// Sorting
			AllowSorting = true;
			Attributes["SortedAscending"] = "yes";

			this.AutoGenerateColumns = false;

			if (!m_DesignMode)
			{
				// Set event handlers

				EditCommand += new DataGridCommandEventHandler(OnEditCommand);

				ItemCreated += new DataGridItemEventHandler(OnItemCreated);
				SortCommand += new DataGridSortCommandEventHandler(OnSortCommand);
				PageIndexChanged += new DataGridPageChangedEventHandler(OnPageIndexChanged);

				UpdateCommand += new DataGridCommandEventHandler(OnUpdateCommand);

				DeleteCommand += new DataGridCommandEventHandler(OnDeleteCommand);
				CancelCommand += new DataGridCommandEventHandler(OnCancelCommand);
				///Load += new EventHandler(OnLoad);
				this.SelectedIndexChanged += new EventHandler(OnSelectedIndexChanged);

				this.NewRow += new NewRowEventHandler(OnNewRow);

			}
			// actions
			//AllowEdit = true;
			//AllowAdd = true;
			//AllowDelete = true;

			//AllowSelect = true;
			//ShowToolBar = true;
			EnableViewState = true;
		}

		[Browsable(true)]
		public event NewRowEventHandler NewRow;

		protected override void OnLoad(EventArgs e)
		{
			WebEnv.DataManager = this.DataManager;
			string eventArg = Page.Request["__EVENTARGUMENT"];
			string eventTarget = Page.Request["__EVENTTARGET"];

			/*
			if (m_DesignMode)
			{
				Recreate();
			}*/
			if (UserEditMode != 0 && UserEditMode != EditMode)
			{
				EditMode = UserEditMode;
				Recreate();
				UpdateView();
			}

			if (this.Columns.Count == 0)
			{
				Recreate();
				UpdateView();
			}
			if (this.Page.IsPostBack)
			{
				if (!GridCreated) UpdateView();
			}
			base.OnLoad(e);

			if (EditAllRows && this.Page.IsPostBack) // collect all fields from all rows
			{
				foreach (DataGridItem dataGridItem in this.Items)
				{
					int dataIndex = DataIndex(dataGridItem.ItemIndex);
					CStructData structData = (CStructData)RowsDataDisplay[dataIndex];
					m_WebEnv.GetColumnsControlsValues((NorthwindGrid)this, dataGridItem.ItemIndex, structData);
				}
			}

			ScriptManager current = ScriptManager.GetCurrent(Page);
			if (current != null)
			{
				Button changeLayoutButton = (Button)this.ToolBar.GetWebControl("ChangeLayout");
				if (changeLayoutButton != null)
					current.RegisterPostBackControl(changeLayoutButton);
			}

		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual Hashtable GridLineActionsName
		{
			get
			{
				if (m_GridLineActionsName == null)
				{
					m_GridLineActionsName = new Hashtable();
					m_GridLineActionsName[GridLineActionsNameEnum.SELECT_ROW] = "Select";


					m_GridLineActionsName[GridLineActionsNameEnum.DELETE] = "Delete";

					m_GridLineActionsName[GridLineActionsNameEnum.EDIT] = "Edit";

					m_GridLineActionsName[GridLineActionsNameEnum.UPDATE] = "Update";
					m_GridLineActionsName[GridLineActionsNameEnum.CANCEL] = "Cancel";
				}

				return (m_GridLineActionsName);
			}
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

		public Hashtable CellsPosition
		{
			get { return m_CellsPosition; }
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public DataManager DataManager
		{
			get
			{
				if (m_DataManager == null)
				{
					if (this.Page is NorthwindPage)
					{
						NorthwindPage page = (NorthwindPage)(this.Page);
						m_DataManager = (page.DataManager);
					}
					else
					{

						throw new Exception("You must set the DataManager before using this grid");
					}
				}
				return (m_DataManager);
			}
			set
			{
				m_DataManager = value;
			}

		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		protected int InternalFieldsListType
		{
			set
			{
				m_FieldsListType = value;
				this.ViewState["FieldsListType"] = value;
			}

			get
			{
				if (this.ViewState["FieldsListType"] == null)
					m_FieldsListType = 0;
				else
					m_FieldsListType = (int)this.ViewState["FieldsListType"];
				return (m_FieldsListType);
			}
		}



		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Hashtable SelectedRows
		{
			get
			{
				if ((Hashtable)ViewState["SelectedRows"] == null)
				{

					Hashtable selectedRows = new Hashtable();
					SelectedRows = selectedRows;
				}
				return (Hashtable)ViewState["SelectedRows"];
			}
			set
			{
				ViewState["SelectedRows"] = value;
			}
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int LastSelectedDataIndex
		{

			get
			{
				if (ViewState["LastSelectedDataIndex"] == null)
				{
					return (-1);
				}

				int lastSelectedDataIndex = (int)ViewState["LastSelectedDataIndex"];

				if (lastSelectedDataIndex == -1 && SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
				{
					int[] slectedLines = this.GetSelectedIndices();
					if (slectedLines.Length > 0)
						return slectedLines[0];
					else
						return (-1);
				}
				return (lastSelectedDataIndex);
			}
			set
			{
				ViewState["LastSelectedDataIndex"] = value;
			}
		}

		// PROPERTY: SortExpression
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public String SortExpression
		{
			get { return Attributes["SortExpression"]; }
		}

		// PROPERTY: IsSortedAscending
		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]


		public bool IsSortedAscending
		{
			get { return Attributes["SortedAscending"] == "yes"; }
		}

		public EditModeEnum EditMode
		{
			get
			{
				if (ViewState["EditMode"] == null)
				{
					if (!DesignMode && SessionManager.UserExist) // maybe session expired
					{
						if (SessionManager.UserExist && SessionManager.User.Type == (short)UserTypeEnum.DEBUG)
							return EditModeEnum.ALL;
						else
							return EditModeEnum.VIEW_ONLY;
					}
					else
						return EditModeEnum.VIEW_ONLY;

				}
				return (EditModeEnum)ViewState["EditMode"];
			}
			set
			{
				if (EditMode != value)
				{
					ViewState["EditMode"] = value;
					//if (this.ChildControlsCreated)
					//{
					//this.UpdateView();
					//}					 
				}
				//if (ShowToolBar)
				//	ToolBar.EditMode = value;
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public EditModeEnum UserEditMode
		{
			get
			{
				if (m_UserEditMode != 0)
					return m_UserEditMode;

				if (ViewState["UserEditMode"] != null)
				{
					return (EditModeEnum)ViewState["UserEditMode"];
				}
				return 0;
			}
			set
			{
				ViewState["UserEditMode"] = value;
				m_UserEditMode = value;
				if (m_UserEditMode != 0 && m_UserEditMode != EditMode)
				{
					EditMode = m_UserEditMode;
					Recreate();
					UpdateView();
				}
			}
		}

		[NotifyParentProperty(true)]
		public bool AllowEdit
		{
			get
			{
				if (Attributes["AllowEdit"] == null || UserEditMode != 0)
				{
					if (EditMode == EditModeEnum.ALL || EditMode == EditModeEnum.UPDATE)
						return true;
					else
						return false;
				}
				return (Attributes["AllowEdit"] == "yes");
			}
			set { Attributes["AllowEdit"] = (value ? "yes" : "no"); }


		}

		[NotifyParentProperty(true)]
		public bool AllowAdd
		{
			get
			{
				if (MediaType == MediaTypeEnum.Print) return false;

				if (Attributes["AllowAdd"] == null || UserEditMode != 0)
				{
					if (EditMode == EditModeEnum.ALL)
						return true;
					else
						return false;
				}
				return (Attributes["AllowAdd"] == "yes");
			}

			set { Attributes["AllowAdd"] = (value ? "yes" : "no"); }
		}

		[NotifyParentProperty(true)]
		public bool AllowDelete
		{
			get
			{
				if (MediaType == MediaTypeEnum.Print) return false;

				if (Attributes["AllowDelete"] == null || UserEditMode != 0)
				{
					if (EditMode == EditModeEnum.ALL)
						return true;
					else
						return false;
				}
				return (Attributes["AllowDelete"] == "yes");
			}
			set { Attributes["AllowDelete"] = (value ? "yes" : "no"); }
		}

		[NotifyParentProperty(true)]
		public bool AllowSelect
		{
			get
			{
				if (MediaType == MediaTypeEnum.Print) return false;
				if (Attributes["AllowSelect"] == null)
					return true;

				return (Attributes["AllowSelect"] == "yes");
			}

			set { Attributes["AllowSelect"] = (value ? "yes" : "no"); }
		}

		[NotifyParentProperty(true)]
		public bool AllowChangeLayout
		{
			get
			{
				if (MediaType == MediaTypeEnum.Print) return false;
				if (Attributes["AllowChangeLayout"] == null)
					return false;

				return (Attributes["AllowChangeLayout"] == "yes");
			}

			set { Attributes["AllowChangeLayout"] = (value ? "yes" : "no"); }
		}

		public SelectionModeEnum SelectionMode
		{
			get
			{
				if (!DesignMode)
				{
					/*
					if (SessionManager.UserExist  && SessionManager.User.Type == (short)UserTypeEnum.DEBUG)
					{
						m_SelectionMode = SelectionModeEnum.MULTIPL_SELECTION_MODE;
					}
					  Zion: this is not working well*/
					return m_SelectionMode;
				}
				else
					return m_SelectionMode;
			}
			set { m_SelectionMode = value; }
		}

		// PROPERTY: PagerCurrentPageCssClass
		String m_PagerCurrentPageCssClass = "";
		[NotifyParentProperty(true)]
		public String PagerCurrentPageCssClass
		{
			get { return m_PagerCurrentPageCssClass; }
			set { m_PagerCurrentPageCssClass = value; }
		}

		// PROPERTY: PagerOtherPageCssClass
		String m_PagerOtherPageCssClass = "";
		[NotifyParentProperty(true)]
		public String PagerOtherPageCssClass
		{
			get { return m_PagerOtherPageCssClass; }
			set { m_PagerOtherPageCssClass = value; }
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public NorthwindWebEnv WebEnv
		{
			get { return m_WebEnv; }
			set
			{

				m_WebEnv = value;

			}
		}



		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IDictionary DataObjectsContainer
		{
			set
			{
				m_DataObjectsContainer = value;
			}

			get
			{
				return (m_DataObjectsContainer);
			}
		}

		// EVENT HANDLER: ItemCreated			


		public void OnItemCreated(Object sender, DataGridItemEventArgs e)
		{
			// Get the newly created item
			ListItemType itemType = e.Item.ItemType;


			// PAGER
			if (itemType == ListItemType.Pager)
			{
				TableCell pager = (TableCell)e.Item.Controls[0];
				pager.HorizontalAlign = HorizontalAlign.Left;
				// Enumerates all the items in the pager...
				for (int i = 0; i < pager.Controls.Count; i += 2)
				{
					// It can be either a Label or a Link button
					if (pager.Controls[i] is LinkButton)
					{
						LinkButton h = (LinkButton)pager.Controls[i];
						h.Text = "[ " + h.Text + " ]";
						h.CssClass = m_PagerOtherPageCssClass;
					}
					else if (pager.Controls[i] is Label)
					{
						Label l = (Label)pager.Controls[i];
						l.CssClass = "PageNums";
						if (pager.Controls.Count > 1)
							l.Text = "Page " + l.Text;
						else
							l.Text = "";

						if (m_PagerCurrentPageCssClass == "")
						{
							l.ForeColor = ColorTranslator.FromHtml("#333777");

							l.Font.Bold = true;
						}
						else
							l.CssClass = m_PagerCurrentPageCssClass;
					}
					else
						throw new Exception("Pager controls can be LinkButton or Label");
				}
			}

			// HEADER
			if (itemType == ListItemType.Header)
			{
				String strSortExpression = Attributes["SortExpression"];

				bool m_SortedAscending = (Attributes["SortedAscending"] == "yes");
				String strOrder = (m_SortedAscending ? " 5" : " 6");

				for (int i = 0; i < Columns.Count; i++)
				{
					// draw to reflect sorting

					if (strSortExpression == Columns[i].SortExpression)
					{
						TableCell cell = e.Item.Cells[i];
						Label lblSorted = new Label();
						lblSorted.Font.Name = "webdings";
						lblSorted.Font.Size = FontUnit.XSmall;
						lblSorted.Text = strOrder;
						cell.Controls.Add(lblSorted);
					}
				}
			}


			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				if (itemType == ListItemType.Item || (itemType == ListItemType.AlternatingItem) || (itemType == ListItemType.SelectedItem))
				{
					if (SelectedRows.ContainsKey(DataIndex(e.Item.ItemIndex)))
					{
						e.Item.CssClass = "SelectedItemStyle";
					}
				}
			}

			// FOOTER
			if (itemType == ListItemType.Footer)
			{
				int numCells = this.Columns.Count;
				int i;

				for (i = 1; i < numCells; i++)
				{
					e.Item.Cells.RemoveAt(1);
				}
				e.Item.Cells[0].ColumnSpan = Columns.Count;

				TableCell cell = e.Item.Cells[0];


				CreateFooterControls(cell);
				m_GridCreated = true;
			}


		}


		public bool GridCreated
		{
			get
			{
				return m_GridCreated;
			}
		}

		/* example of how to change the background color of specific row depends on the data in the row

		void ItemDataBoundEventHandler(object sender, DataGridItemEventArgs e)
		{
			if (e.Item.ItemType == ListItemType.Item ||
				e.Item.ItemType == ListItemType.AlternatingItem)
			{
				// Check to see if the price is below a certain threshold
				double price;
				price = Convert.ToDouble(DataBinder.Eval(e.Item.DataItem, "price"))
			  
					if (price < 10.0)

						e.Item.BackColor = System.Drawing.Color.Yellow;
			}
		}

		*/

		protected virtual void CreateFooterControls(TableCell tableCell)
		{
			int numColumns = tableCell.Controls.Count;
			tableCell.CssClass = "grid_toolbar";
			if (ShowToolBar)
			{
				if (!ToolBar.ToolbarCreated)
				{
					ToolBar.Recreate();
				}
				ToolBar.ID = this.ID + "_ToolBar";
				tableCell.Controls.Add(ToolBar);

				ImageButton editLineButton = ToolBar.EditLineButton;
				if (editLineButton != null)
				{
					editLineButton.Click += new ImageClickEventHandler(editLineButton_Click);
				}
				ImageButton addLineButton = ToolBar.AddLineButton;
				if (addLineButton != null)
				{
					addLineButton.Click += new ImageClickEventHandler(addLineButton_Click);
				}

				ImageButton addLineLikeButton = ToolBar.AddLineLikeButton;
				if (addLineLikeButton != null)
				{
					addLineLikeButton.Click += new ImageClickEventHandler(addLineLikeButton_Click);
				}

				ImageButton deleteLinesButton = ToolBar.DeleteLinesButton;

				if (deleteLinesButton != null)
				{
					deleteLinesButton.Click += new ImageClickEventHandler(deleteLinesButton_Click);
				}


				ImageButton unDeleteLinesButton = ToolBar.UnDeleteLinesButton;

				if (unDeleteLinesButton != null)
				{
					unDeleteLinesButton.Click += new ImageClickEventHandler(unDeleteLinesButton_Click);
				}

				ImageButton selectButton = ToolBar.SelectButton;
				if (selectButton != null)
				{
					selectButton.Click += new ImageClickEventHandler(selectButton_Click);
				}

				ImageButton cancelSelectButton = ToolBar.CancelSelectButton;
				if (cancelSelectButton != null)
				{
					cancelSelectButton.Click += new ImageClickEventHandler(cancelSelectButton_Click);
				}

				ImageButton selectAllButton = ToolBar.SelectAllButton;
				if (selectAllButton != null)
				{
					selectAllButton.Click += new ImageClickEventHandler(selectAllButton_Click);
				}

				ImageButton unSelectAllButton = ToolBar.UnSelectAllButton;
				if (unSelectAllButton != null)
				{
					unSelectAllButton.Click += new ImageClickEventHandler(unSelectAllButton_Click);
				}

				ImageButton copyButton = ToolBar.CopyButton;
				if (copyButton != null)
				{
					copyButton.Click += new ImageClickEventHandler(copyButton_Click);
				}

				ImageButton pastButton = ToolBar.PasteButton;
				if (pastButton != null)
				{
					pastButton.Click += new ImageClickEventHandler(pastButton_Click);
				}

				ImageButton discardChangesButton = ToolBar.DiscardChangesButton;
				if (discardChangesButton != null)
				{
					discardChangesButton.Click += new ImageClickEventHandler(discardChangesButton_Click);
				}

				ImageButton saveButton = ToolBar.SaveButton;
				if (saveButton != null)
				{
					saveButton.Click += new ImageClickEventHandler(saveButton_Click);
				}

				ImageButton firstPage = ToolBar.FirstPageButton;
				if (firstPage != null)
				{
					firstPage.Click += new ImageClickEventHandler(firstPageButton_Click);

				}

				ImageButton jumpBack = ToolBar.JumpBackButton;

				if (jumpBack != null)
				{
					jumpBack.Click += new ImageClickEventHandler(jumpBackButton_Click);
				}

				ImageButton backPage = ToolBar.BackPageButton;

				if (backPage != null)
				{
					backPage.Click += new ImageClickEventHandler(backPageButton_Click);
				}

				ImageButton nextPage = ToolBar.NextPageButton;
				if (nextPage != null)
				{
					nextPage.Click += new ImageClickEventHandler(nextPageButton_Click);
				}

				ImageButton jumpNext = ToolBar.JumpNextButton;
				if (jumpNext != null)
				{

					jumpNext.Click += new ImageClickEventHandler(jumpNextButton_Click);
				}

				ImageButton lastPage = ToolBar.LastPageButton;
				if (lastPage != null)
				{
					lastPage.Click += new ImageClickEventHandler(lastPageButton_Click);
				}

				ImageButton jumpToPage = ToolBar.JumpToPageButton;
				if (jumpToPage != null)
				{
					jumpToPage.Click += new ImageClickEventHandler(jumpToPageButton_Click);
				}

				ImageButton pageSize = ToolBar.PageSizeButton;
				if (pageSize != null)
				{


					pageSize.Click += new ImageClickEventHandler(pageSizeButton_Click);
				}

				ImageButton digButton = ToolBar.DigButton;
				if (digButton != null)
				{
					digButton.Click += new ImageClickEventHandler(digButton_Click);
				}

				ImageButton printButton = ToolBar.PrintButton;
				if (printButton != null)
				{
					printButton.OnClientClick = "javascript:CallPrint('" + this.ClientID + "');";
				}

				//else
				//	tableCell.Controls.Add(ToolBar);

			}
		}
		public virtual void UpdateToolbarAttributes(CToolbarAttributeCollection toolbarAttributeCollection)
		{
			(this.Page as NorthwindPage).UpdateToolbarAttributes((this as NorthwindGrid), toolbarAttributeCollection);

		}
		public virtual void CustomToolbarItemControl_Click(object sender)
		{
			(this.Page as NorthwindPage).OnCustomToolbarItemControlClicked(sender, this as NorthwindGrid);
		}

		public virtual string RowDataObjectName
		{
			get
			{
				if (Attributes["RowDataObjectName"] == null)
					return "";

				else
					return (Attributes["RowDataObjectName"]);
			}
			set
			{
				Attributes["RowDataObjectName"] = value;
			}
		}


		[PersistenceMode(PersistenceMode.InnerProperty)]
		[NotifyParentProperty(true)]
		public CFieldAttributeCollection FieldsCollection
		{
			get
			{
				if (m_FieldsListType != 0)
				{
					return m_EmptyFieldAttributeCollection;
				}

				if (m_FieldAttributeCollection == null)
					m_FieldAttributeCollection = new CFieldAttributeCollection();

				m_FieldAttributeCollection.RemoveDuplicates();
				return (m_FieldAttributeCollection);

			}
			/*
			set
			{
				if (InternalFieldsListType != 0)
				{
					m_FieldAttributeCollection = null;
				}
				else
				{
					m_FieldAttributeCollection = value;

					if (!AllowAdd && !AllowDelete && !AllowEdit)
					{
						m_FieldAttributeCollection.RemoveAllByFieldValue(CFieldAttribute.FIELDS_ENUM.NUM, 0); // row status
					}
				}
			}
			 * */
		}

		protected CFieldAttributeCollection InternalFieldsCollection
		{
			get
			{
				if (m_FieldAttributeCollection == null)
				{
					m_FieldAttributeCollection = CreateFieldsCollection();
				}
				m_FieldAttributeCollection.RemoveDuplicates();
				return (m_FieldAttributeCollection);


			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public CFieldAttributeCollection UserFieldsCollection
		{
			get
			{
				if (m_UserFieldAttributeCollection != null)
				{
					return m_UserFieldAttributeCollection;
				}

				LastValuesManager lastValuesManager = SessionManager.LastValuesManager;
				string uniqueName = string.Format("{0}_{1}", this.Page.GetType().Name, this.ID);
				List<CStructData> fieldAttributesList = lastValuesManager.GetStructDataList("FieldAttributes", uniqueName, typeof(CFieldAttribute));
				if (fieldAttributesList != null)
					m_UserFieldAttributeCollection = new CFieldAttributeCollection(fieldAttributesList);
				return (m_UserFieldAttributeCollection);
			}
			set
			{
				m_UserFieldAttributeCollection = value;
				m_FieldsCollectionToCreateTheGridBy = null;
				Recreate();
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public CFieldAttributeCollection FieldsCollectionToCreateTheGridBy
		{
			get
			{
				if (m_FieldsCollectionToCreateTheGridBy != null)
				{
					AddRowStatusColumn(m_FieldsCollectionToCreateTheGridBy);
					this.CustomiseFieldsCollection(m_FieldsCollectionToCreateTheGridBy);
					return m_FieldsCollectionToCreateTheGridBy;
				}
				m_FieldsCollectionToCreateTheGridBy = new CFieldAttributeCollection();
				if (UserFieldsCollection != null && UserFieldsCollection.Count > 0)
				{
					m_FieldsCollectionToCreateTheGridBy.CopyFrom(UserFieldsCollection);
				}
				else
				{
					m_FieldsCollectionToCreateTheGridBy.CopyFrom(InternalFieldsCollection);
				}
				AddRowStatusColumn(m_FieldsCollectionToCreateTheGridBy);
				this.CustomiseFieldsCollection(m_FieldsCollectionToCreateTheGridBy);
				return m_FieldsCollectionToCreateTheGridBy;
			}
		}

		public virtual void CustomiseFieldsCollection()
		{
			if (!AllowEdit)
			{
				FieldsCollectionToCreateTheGridBy.SetReadOnly();
			}
		}

		public virtual void CustomiseFieldsCollection(CFieldAttributeCollection fieldAttributeCollection)
		{
			if (!AllowEdit)
			{
				fieldAttributeCollection.SetReadOnly();
			}
		}

		virtual protected void AddRowStatusColumn(CFieldAttributeCollection fieldAttributeCollection)
		{
			CFieldAttribute fieldAttribute;

			if (IsRowDataIsRecordData() && fieldAttributeCollection.FindByFieldValue(CFieldAttribute.FIELDS_ENUM.NUM, 0) == null) // row status
			{
				if (AllowEdit || AllowAdd || AllowDelete)
				{
					// for record there is a record status column
					fieldAttribute = fieldAttributeCollection.InsertNewFieldAttribute(0); // add at first
					fieldAttribute.Num = 0;
					fieldAttribute.Name = "RecordStatus";
					fieldAttribute.ShowMode = (Northwind.General.FieldShowModeEnum)Northwind.General.FieldShowModeEnum.SHOW_READ_ONLY;
				}
			}

		}


		virtual protected CFieldAttributeCollection CreateFieldsCollection()
		{
			CFieldAttributeCollection fieldAttributeCollection;

			if (InternalFieldsListType == (int)CStructData.FieldsListEnum.Dynamic)
				fieldAttributeCollection = WebEnv.CreateFieldsCollectionDynamically(this);
			else
				fieldAttributeCollection = WebEnv.CreateFieldsCollection(InternalFieldsListType);
			return fieldAttributeCollection;
		}

		public virtual void ShowAll()
		{
			m_FieldsListType = 0; // none will bring all fields
			m_FieldAttributeCollection = CreateFieldsCollection();
		}

		public virtual void ShowSummary()
		{
			throw new NotImplementedException("ShowSummary()");
		}

		public virtual void ShowAllExceptSummary()
		{
			throw new NotImplementedException("ShowAllExceptSummary()");
		}

		// EVENT HANDLER: SortCommand


		public void OnSortCommand(Object sender, DataGridSortCommandEventArgs e)
		{

			String strSortExpression = Attributes["SortExpression"];
			String strSortedAscending = Attributes["SortedAscending"];

			// Sets the new sorting field
			Attributes["SortExpression"] = e.SortExpression;


			// Sets the order (defaults to ascending). If you click on the
			// sorted column, the order reverts.
			Attributes["SortedAscending"] = "yes";

			if (e.SortExpression == strSortExpression)
				Attributes["SortedAscending"] = (strSortedAscending == "yes" ? "no" : "yes");



			Sort(e.SortExpression, Attributes["SortedAscending"]);
			SetCurrentPageIndex(0);
			LastSelectedDataIndex = -1;
		}


		public abstract void Sort(String sortExpression, String sortedAscending);

		// EVENT HANDLER: PageIndexChanged
		public void OnPageIndexChanged(Object sender, DataGridPageChangedEventArgs e)
		{
			if (CurrentPageIndex != e.NewPageIndex)
			{

				if (SelectionMode == SelectionModeEnum.SINGLE_SELECTION_MODE)
				{
					if (SelectedRows.Count > 0)
					{
						int selectedDataLineBefore = LastSelectedDataIndex;

						if (selectedDataLineBefore >= 0)
							if (LineInPage(selectedDataLineBefore, e.NewPageIndex))
								SelectedIndex = selectedDataLineBefore % PageSize;
							else
								SelectedIndex = -1;
					}
					else
						SelectedIndex = -1;

				}
				CurrentPageIndex = e.NewPageIndex;

				// Refresh the grid
				UpdateView();

				BubbleEventName = "PageIndexChanged";
				this.RaiseBubbleEvent(this, e);
			}

		}


		protected virtual void OnCancelCommand(object source, DataGridCommandEventArgs e)
		{
			IStructDataCollection rowsData = RowsData;
			if (OriginRowData == null)
			{
				rowsData.RemoveAt(DataIndex(EditItemIndex));
			}
			else
			{
				rowsData[DataIndex(EditItemIndex)] = OriginRowData.Clone();
			}
			// keep RowsData for next post
			KeepRowsData(rowsData);
			// Reset the edit mode for the current item
			EditItemIndex = -1;

			// Refresh the grid
			UpdateView();
		}

		private void OnUpdateCommand(object source, DataGridCommandEventArgs e)
		{

			// TODO: Retrieve new text and update the data source
			CStructData structData = (CStructData)RowsDataDisplay[DataIndex(EditItemIndex)];
			m_WebEnv.GetColumnsControlsValues((NorthwindGrid)this, e.Item.ItemIndex, structData);

			// Reset the edit mode for the current item
			EditItemIndex = -1;
			// Refresh the grid
			UpdateView();
		}

		private void OnDeleteCommand(object source, DataGridCommandEventArgs e)
		{
			if (e.Item.ItemIndex != -1)
			{
				if (RowsDataDisplay[DataIndex(e.Item.ItemIndex)] is CRecordData)
				{
					CRecordData recordData = (CRecordData)RowsDataDisplay[DataIndex(e.Item.ItemIndex)];
					// if it is new record we can delete the row for the collection.
					if (recordData.GetStatus() == CRecordData.RECORD_STATUS_ENUM.NEW_RECORD)
					{
						RowsDataDisplay.RemoveAt(DataIndex(e.Item.ItemIndex));
					}
					else
					{
						recordData.SetDeleted();
					}
					// Reset the edit mode for the current item
					EditItemIndex = -1;
				}
				else
				{
					RowsDataDisplay.RemoveAt(DataIndex(e.Item.ItemIndex));
					EditItemIndex = -1;
				}
			}
			// Refresh the grid
			UpdateView();
		}

		protected virtual void OnNewCliked(object sender, EventArgs e)
		{
			EventArgs eventArgs = new EventArgs();
			OnNewRow(eventArgs);
		}

		protected virtual void SetInitValuesForNewData(CStructData structData)
		{
			GeneralWebEvent generalWebEvent = new GeneralWebEvent();
			generalWebEvent.EvenetType = GeneralWebEvent.EventTypeEnum.NewRowWasInserted;
			generalWebEvent.StructData = structData;
			SendGeneralWebEvent(generalWebEvent);
		}


		public virtual void UpdateView()
		{
			if (!this.Visible)
				return;

			// Bind the data

			if (RowsData == null)
				return;
			//throw new Exception("You must first set RowsData");

			if (this.SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
				SelectedIndex = -1;
			DataSource = RowsDataDisplay;
			if (CurrentPageIndex > LastPageNum)
				SetCurrentPageIndex(LastPageNum);
			try // invalid value
			{
				DataBind();
			}
			catch (Exception ex)
			{
				log.Error("Binding Error in " + this.GetType().Name, ex);
				SetErrorMessage(ex.Message);
			}
		}

		[Browsable(true)]
		public string DataInstanceName
		{
			set
			{
				m_DataInstanceName = value;
			}
			get
			{
				if (m_DataInstanceName == null)
					m_DataInstanceName = this.RowDataObjectName;
				return (m_DataInstanceName);
			}
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string BubbleEventName
		{
			set
			{
				m_BubbleEventName = value;
			}


			get
			{
				return (m_BubbleEventName);
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IStructDataCollection RowsData
		{
			get
			{

				//if (m_RowsData != null)
				//	return (m_RowsData);

				if (DesignMode)
					return null;
				m_RowsData = null;
				if (DataInstanceName != "" && DataInstanceName != null)
				{
					if (KeepDataInSession)
					{
						if (this.Page.Session[DataInstanceName] == null)
							return null;
						m_RowsData = (IStructDataCollection)this.Page.Session[DataInstanceName];
					}
					else
					{
						if (this.ViewState[DataInstanceName] == null)

							return null;
						m_RowsData = (IStructDataCollection)this.ViewState[DataInstanceName];
					}
				}
				if (OriginRowsData == null && m_RowsData != null)
					KeepOrigin();

				return (m_RowsData);
			}
			set
			{
				m_RowsData = value;
				KeepRowsData(m_RowsData);
				KeepOrigin();
				SelectedIndex = -1;
				EditItemIndex = -1;
				UpdateView();
				if (Columns.Count == 0)
					Recreate();

			}
		}

		public void KeepRowsData(IStructDataCollection rowsData)
		{
			if (DataInstanceName != "" && DataInstanceName != null)
			{
				if (KeepDataInSession)
					this.Page.Session[DataInstanceName] = rowsData;
				else
					this.ViewState[DataInstanceName] = rowsData;
			}
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public virtual IStructDataCollection RowsDataDisplay
		{
			get
			{
				return RowsData;
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IStructDataCollection OriginRowsData
		{
			get
			{
				if (m_OriginRowsData != null)

					return (m_OriginRowsData);

				if (DataInstanceName != "" && DataInstanceName != null)
				{

					if (KeepDataInSession)
						m_OriginRowsData = (IStructDataCollection)this.Page.Session[DataInstanceName + "OriginData"];

					else
						m_OriginRowsData = (IStructDataCollection)this.ViewState[DataInstanceName + "OriginData"];
				}
				return (m_OriginRowsData);
			}
			set
			{

				m_OriginRowsData = value;

				if (DataInstanceName != "" && DataInstanceName != null)
				{
					if (KeepDataInSession)
						this.Page.Session[DataInstanceName + "OriginData"] = m_OriginRowsData;
					else
						this.ViewState[DataInstanceName + "OriginData"] = m_OriginRowsData;
				}
			}
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public CStructData OriginRowData
		{
			get
			{
				if (m_OriginRowData != null)
					return (m_OriginRowData);

				if (DataInstanceName != "" && DataInstanceName != null)
				{
					if (KeepDataInSession)
						m_OriginRowData = (CStructData)this.Page.Session[DataInstanceName + "OriginRowData"];
					else
						m_OriginRowData = (CStructData)this.ViewState[DataInstanceName + "OriginRowData"];
				}
				return (m_OriginRowData);
			}
			set
			{

				m_OriginRowData = value;

				if (DataInstanceName != "" && DataInstanceName != null)
				{
					if (KeepDataInSession)
					{
						if (value != null)
							this.Page.Session[DataInstanceName + "OriginRowData"] = m_OriginRowData.Clone();
						else
						{
							if (this.Page.Session[DataInstanceName + "OriginRowData"] != null)
								this.Page.Session.Remove(DataInstanceName + "OriginRowData");
						}
					}
					else
					{
						if (value != null)
							this.ViewState[DataInstanceName + "OriginRowData"] = m_OriginRowData.Clone();
						else
						{
							if (this.ViewState[DataInstanceName + "OriginRowData"] != null)
								this.ViewState.Remove(DataInstanceName + "OriginRowData");
						}
					}
				}
			}
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IStructDataCollection NewRowsData
		{
			set
			{
				RowsData = value;
				KeepOrigin();
			}
		}

		public void KeepOrigin()
		{
			OriginRowsData = m_RowsData.CloneReturnsIStructDataCollection();
		}

		[Browsable(true)]
		public bool KeepDataInSession
		{
			get
			{
				if (ViewState["KeepDataInSession"] == null)
				{
					KeepDataInSession = true;
				}
				return ((bool)ViewState["KeepDataInSession"]);
			}

			set
			{
				ViewState["KeepDataInSession"] = value;
			}
		}

		/*
		protected virtual void OnLoad(object sender, EventArgs e)
		{
		}
		*/

		public virtual void Recreate()
		{
			if (this.Page == null)
				return;
			//NorthwindWebEnv.Trace(this, this.ID + ".Recreate()");
			SendGeneralWebEvent(GeneralWebEvent.EventTypeEnum.BeforeCreateChildControls);
			if (!DesignMode)
			{
				/*
				if (SessionManager.UserExist  && SessionManager.User.Type == (short)UserTypeEnum.DEBUG)
				{
					FieldsCollectionToCreateTheGridBy.ShowAll();
				}
				 */
			}
			this.Columns.Clear();
			string gridIconsPath = Northwind.General.NorthwindGeneral.GetWebGridImagesURL(Page.Theme);

			// create column actions
			if (AllowSelect)
			{
				ButtonColumn selectButton = new ButtonColumn();
				selectButton.HeaderStyle.CssClass = "DataGridSelectColumn";
				selectButton.CommandName = "Select";
				selectButton.Text = "<img class='DataGridImageImage'  src='" + gridIconsPath + "closed.gif' title='" + GridLineActionsName[GridLineActionsNameEnum.SELECT_ROW] + "'>";

				//selectButton.Text = "<img border=0 align=absmiddle src='" + gridIconsPath + "closed.gif' title='" + GridLineActionsName[GridLineActionsNameEnum.SELECT_ROW] + "'>";
				this.Columns.Add(selectButton);

			}

			if (AllowEdit && !EditAllRows)
			{
				EditCommandColumn editCommandColumn = new EditCommandColumn();
				editCommandColumn.HeaderStyle.CssClass = "DataGridEditColumn";
				//editCommandColumn.ItemStyle.Width = new Unit(38, UnitType.Pixel);
				//editCommandColumn.HeaderStyle.Width = 38;

				editCommandColumn.EditText = "<img class='DataGridImageImage' src='" + gridIconsPath + "edit.gif' title='" + GridLineActionsName[GridLineActionsNameEnum.EDIT] + "'>";

				editCommandColumn.CancelText = "<img class='DataGridImageImage' src='" + gridIconsPath + "cancel.gif' title='" + GridLineActionsName[GridLineActionsNameEnum.CANCEL] + "'>";
				editCommandColumn.UpdateText = "<img  class='DataGridImageImage' src='" + gridIconsPath + "ok.gif' title='" + GridLineActionsName[GridLineActionsNameEnum.UPDATE] + "'>";
				this.Columns.Add(editCommandColumn);
				//NorthwindWebEnv.Trace(this, "Grid: Edit Command Created for " + this.ID);
			}

			if (AllowDelete)
			{
				ButtonColumn deleteButton = new ButtonColumn();
				deleteButton.HeaderStyle.CssClass = "DataGridDeleteColumn";
				deleteButton.CommandName = "Delete";

				deleteButton.Text = "<img class='DataGridImageImage' src='" + gridIconsPath + "cancel.gif' title='" + GridLineActionsName[GridLineActionsNameEnum.DELETE] + "'>";
				this.Columns.Add(deleteButton);
			}

			// create columns
			CFieldAttribute rowStatusFieldAttribute = FieldsCollectionToCreateTheGridBy.FindByFieldValue(CFieldAttribute.FIELDS_ENUM.NUM, 0);
			if (rowStatusFieldAttribute != null)
			{
				if (MediaType == MediaTypeEnum.Print || EditMode == EditModeEnum.VIEW_ONLY &&

					(!AllowAdd && !AllowDelete && !AllowEdit))
					rowStatusFieldAttribute.ShowMode = FieldShowModeEnum.HIDDEN;
				else
					rowStatusFieldAttribute.ShowMode = FieldShowModeEnum.SHOW_READ_ONLY;
			}
			if (EditAllRows)
				m_WebEnv.EditAllRows = true;
			else
				m_WebEnv.EditAllRows = false;
			m_WebEnv.CreateGridColumns((NorthwindGrid)this, FieldsCollectionToCreateTheGridBy);

			if (MediaType == MediaTypeEnum.Print)
			{
				foreach (DataGridColumn dataGridColumn in this.Columns)
				{
					dataGridColumn.SortExpression = "";
				}
			}

			CreateExtraCustomColumn();

			if (ShowToolBar)
				ToolBar.Grid = (NorthwindGrid)this;
			//GridCreated = true;
			//this.ChildControlsCreated = true;
		}

		public virtual void CreateExtraCustomColumn()
		{
		}

		protected virtual void OnEditCommand(object source, DataGridCommandEventArgs e)
		{
			EditLine(e.Item.ItemIndex, true);
			//UpdateView();
		}

		protected virtual void EditLine(int lineNumber, bool wasDatebeforeEdit)
		{
			int dataIndex = DataIndex(lineNumber);
			if (wasDatebeforeEdit)
				OriginRowData = RowsData.GetAtReturnsStructData(dataIndex);
			else
				OriginRowData = null;
			EditItemIndex = lineNumber;
			UpdateView();
		}

		protected virtual void OnSelectedIndexChanged(object sender, EventArgs e)
		{
			if (RowsData == null)
				return; // ignore this event
			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				if (SelectedRows.ContainsKey(SelectedDataIndex))
				{

					SelectedRows.Remove(SelectedDataIndex);
					LastSelectedDataIndex = -1;
				}
				else
				{

					SelectedRows[SelectedDataIndex] = "1";
					LastSelectedDataIndex = SelectedDataIndex;

				}
			}
			else
			{
				if (SelectedRows.ContainsKey(SelectedDataIndex))
				{
					SelectedRows.Remove(SelectedDataIndex);
					SelectedIndex = -1;
					LastSelectedDataIndex = -1;
				}
				else
				{

					SelectedRows.Clear();
					SelectedRows[SelectedDataIndex] = "1";
					LastSelectedDataIndex = SelectedDataIndex;
				}

			}
			UpdateView();

			BubbleEventName = "SelectedIndexChanged";
			this.RaiseBubbleEvent(this, e);

		}

		protected override void PrepareControlHierarchy()
		{
			base.PrepareControlHierarchy();
		}
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
		}

		protected override void OnPreRender(EventArgs e)
		{
			if (this.Columns.Count == 0)
				Recreate();
			if (!GridCreated)
				UpdateView();
			CustomiseToolbar();
			base.OnPreRender(e);
			//(this.Page as NorthwindPage).InjectFixedHeaderForGrid((NorthwindGrid)this);
		}



		[Browsable(false)]
		public bool IsInDesignMode()
		{

			return (m_DesignMode);
		}

		public virtual void CheckInDesignMode(string property)
		{
			//if (!IsInDesignMode()) // vv-
			//	throw new Exception("Property "+property+ " Is Design Proprty, You are not allowed to change this property at run time");
		}


		// method responsible for notifying registered


		//	objects of the NewRow event
		protected virtual void OnNewRow(EventArgs e)
		{
			// Has any objects registered interest with our event? 
			if (NewRow != null)
			{
				// Yes, notify all the objects in the delegate linked list
				NewRow(this, e);
			}
		}


		private void OnNewRow(Object sender, EventArgs args)
		{
			CStructData structData;
			int dataIndexToInsertAt;

			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				int[] selectedIndices = GetSelectedIndices();
				if (selectedIndices.Length > 0)
					dataIndexToInsertAt = selectedIndices[0];
				else
					dataIndexToInsertAt = -1;
			}
			else
			{
				dataIndexToInsertAt = SelectedDataIndex;
			}
			structData = RowsData.InsertNewReturnsStructData(dataIndexToInsertAt);
			SetInitValuesForNewData(structData);

			if (AllowEdit)
			{
				if (dataIndexToInsertAt != -1)
				{
					EditLine(dataIndexToInsertAt, false);
					//EditItemDataIndex = SelectedDataIndex;
				}
				else
				{
					int lineInPage = ShowDataLine(RowsData.Count - 1);
					EditLine(lineInPage, false);
					//EditItemDataIndex = RowsData.Count - 1;
				}
			}
			else
				UpdateView();
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int SelectedDataIndex
		{
			get
			{
				int indexData = this.SelectedIndex;
				if (CurrentPageIndex > 0)
				{
					indexData += CurrentPageIndex * PageSize;
				}
				return (indexData);
			}
			set
			{
				if (value < PageSize)
					SelectedIndex = value;
				else
				{
					SetCurrentPageIndex(value / PageSize);
					SelectedIndex = (value % PageSize);
				}
			}
		}

		/*
		public override int SelectedIndex
		{
			get
			{
				if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
				{
					if (SelectedRows.Count > 0)
					{
						int[] selectedIndices = GetSelectedIndices();
						return selectedIndices[0];
					}
					else
						return -1;
				}
				return base.SelectedIndex;
			}
			set
			{
				base.SelectedIndex = value;
			}
		}
		*/
		/*
		public int SelectedDataIndex
		{
			get
			{
				int indexData;
				if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
				{
					indexData = LastSelectedDataIndex;
				}
				else
				{
					indexData = this.SelectedIndex;
					if (CurrentPageIndex > 0)
					{
						indexData += CurrentPageIndex * PageSize;
					}
				}
				return (indexData);
			}
			set
			{
				if (value < PageSize)
					SelectedIndex = value;
				else
				{
					SetCurrentPageIndex(value / PageSize);
					SelectedIndex = (value % PageSize);
				}
			}
		}
		*/

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int EditItemDataIndex
		{
			get
			{
				int indexData = this.EditItemIndex;
				if (CurrentPageIndex > 0)
				{
					indexData += CurrentPageIndex * PageSize;
				}
				return (indexData);
			}

			set
			{
				if (value < PageSize)
					EditItemIndex = value;
				else
				{

					SetCurrentPageIndex(value / PageSize);

					EditItemIndex = (value % PageSize);
				}
			}
		}

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int DataIndex(int itemIndex)
		{
			int indexData = itemIndex;
			if (CurrentPageIndex > 0)
			{
				indexData += CurrentPageIndex * PageSize;
			}

			return (indexData);
		}

		public virtual int ShowDataLine(int dataLine)
		{
			int lineInPage;
			SetCurrentPageIndex(dataLine / this.CurrentPageSize);
			lineInPage = dataLine - (CurrentPageIndex * CurrentPageSize);
			return (lineInPage);
		}


		public virtual int GetDataLine(int pageIndex, int lineIndex)
		{
			int dataLine = lineIndex;

			if (pageIndex > 0)
			{
				dataLine += dataLine * PageSize;
			}

			return dataLine;
		}

		[Browsable(true)]
		public bool KeepRowsDataInSession
		{
			get
			{
				if (ViewState["KeepRowsDataInSession"] == null)
				{
					KeepRowsDataInSession = true;
				}
				return ((bool)ViewState["KeepRowsDataInSession"]);
			}
			set
			{
				ViewState["KeepRowsDataInSession"] = value;
			}
		}

		public int[] GetSelectedIndices()
		{
			if (this.SelectionMode == SelectionModeEnum.SINGLE_SELECTION_MODE)
			{

				throw new Exception("Selection mode is Single - Please use SelectedIndex instead");
			}

			int[] selectedIndices = new int[SelectedRows.Count];
			int indexToAddTo = 0;

			for (int i = 0; i < RowsDataDisplay.Count; i++)
			{
				if (SelectedRows.ContainsKey(i))
				{

					selectedIndices[indexToAddTo++] = i;
				}
			}
			return (selectedIndices);
		}


		public void SetCurrentPageIndex(int currentPageIndex)
		{

			CurrentPageIndex = currentPageIndex;

			DataGridPageChangedEventArgs e = new DataGridPageChangedEventArgs(this, currentPageIndex);
			BubbleEventName = "PageIndexChanged";
			RaiseBubbleEvent(this, e);

			UpdateView();
		}


		// vv- delete when you can

		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public NorthwindToolBarWCC GridButtom
		{
			get
			{
				return ToolBar;
			}
		}

		[Browsable(true)]
		[NotifyParentProperty(true)]
		public bool ShowToolBar
		{
			get
			{
				if (Attributes["ShowToolBar"] == null)
				{
					ShowToolBar = true;
				}
				return (Attributes["ShowToolBar"] == true.ToString());
			}
			set
			{
				Attributes["ShowToolBar"] = value.ToString();
				if (value)
					ShowFooter = true;
				else
					ShowFooter = false;
			}
		}

		[Browsable(true)]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[NotifyParentProperty(true)]
		public NorthwindToolBarWCC ToolBar
		{
			get
			{
				if (ShowToolBar)
				{
					if (m_GridButtom == null)
					{
						m_GridButtom = new NorthwindToolBarWCC();
						m_GridButtom.ID = this.ID + "_ToolBar";
						m_GridButtom.ToolBarType = NorthwindToolBarWCC.ToolBarTypeEnum.Grid;
						m_GridButtom.Grid = (NorthwindGrid)this;
						m_GridButtom.Page = this.Page;
					}
					if (m_GridButtom.Page == null)
						m_GridButtom.Page = this.Page;
					return m_GridButtom;
				}
				else
					return null;
			}
			set
			{
				m_GridButtom = value;
				m_GridButtom.Grid = (NorthwindGrid)this;
				m_GridButtom.Page = this.Page;
			}
		}

		private void editLineButton_Click(object sender, ImageClickEventArgs e)
		{

			if (this.IsInsideEdit)
			{

				FinishEditingFirst();
				return;
			}

			if (this.LastSelectedDataIndex != -1)
			{

				SelectedIndex = LastSelectedDataIndex;

				EditLine(SelectedIndex, false);
				UpdateView();
			}
		}

		private void addLineButton_Click(object sender, ImageClickEventArgs e)
		{
			EventArgs eventArgs = new EventArgs();
			OnNewRow(eventArgs);
		}

		private void addLineLikeButton_Click(object sender, ImageClickEventArgs e)
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			AddLineLike();
			UpdateView();
		}

		protected void AddLineLike()
		{
			if (this.LastSelectedDataIndex != -1)
			{
				SelectedDataIndex = LastSelectedDataIndex;

				CStructData slectedStructData = this.RowsData.GetAtReturnsStructData(SelectedDataIndex);

				CStructData newStructData = this.RowsDataDisplay.InsertNewReturnsStructData(-1);
				if (IsRowDataIsRecordData())
				{
					((CRecordData)newStructData).CopyFrom((CRecordData)slectedStructData);
					((CRecordData)newStructData).SetNew();
				}
				else
					newStructData.CopyFrom(slectedStructData);
				int editLine = ShowDataLine(RowsDataDisplay.Count - 1);
				EditLine(editLine, false);
			}
		}

		[Browsable(false)]
		public bool IsRowDataIsRecordData()
		{
			if (RowsData == null)
				return true;

			if (RowsData.ElementType.IsSubclassOf(typeof(CRecordData)))
				return (true);
			else
				return (false);
		}

		private void deleteLinesButton_Click(object sender, ImageClickEventArgs e)
		{
			DeleteLines();
		}



		protected void DeleteLines()
		{

			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}

			CRecordData recordData;
			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				int[] selectedLines = GetSelectedIndices();

				for (int i = 0; i < selectedLines.Length; i++)
				{
					recordData = (CRecordData)this.RowsDataDisplay.GetAtReturnsStructData(selectedLines[i]);
					recordData.SetDeleted();
				}
			}
			else if (this.SelectedIndex != -1)
			{
				recordData = (CRecordData)this.RowsDataDisplay.GetAtReturnsStructData(SelectedDataIndex);
				recordData.SetDeleted();
			}
			UpdateView();
		}

		private void unDeleteLinesButton_Click(object sender, ImageClickEventArgs e)
		{
			UnDeleteLines();

		}

		protected void UnDeleteLines()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			CRecordData recordData;
			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				int[] selectedLines = GetSelectedIndices();

				for (int i = 0; i < selectedLines.Length; i++)
				{
					recordData = (CRecordData)this.RowsDataDisplay.GetAtReturnsStructData(selectedLines[i]);
					recordData.SetUndeleted();
				}
			}
			else if (this.SelectedIndex != -1)
			{

				recordData = (CRecordData)this.RowsDataDisplay.GetAtReturnsStructData(SelectedDataIndex);

				recordData.SetUndeleted();
			}
			UpdateView();

		}


		private void selectButton_Click(object sender, ImageClickEventArgs e)
		{
			ImageButton imageButton = (ImageButton)sender;

			imageButton.CommandArgument = this.DataInstanceName;
			BubbleEventName = "Select";
			this.RaiseBubbleEvent(this, e);
			UpdateView();
		}

		private void cancelSelectButton_Click(object sender, ImageClickEventArgs e)
		{
			ImageButton imageButton = (ImageButton)sender;

			imageButton.CommandArgument = this.DataInstanceName;
			BubbleEventName = "CancelSelect";
			this.RaiseBubbleEvent(this, e);
			UpdateView();
		}

		private void selectAllButton_Click(object sender, ImageClickEventArgs e)
		{
			SelectAll();
		}



		public void SelectAll()
		{

			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}

			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				int i;
				SelectedRows.Clear();
				for (i = 0; i < this.RowsDataDisplay.Count; i++)
				{
					SelectedRows[i] = "1";
				}
				SelectedIndex = -1;
			}
			UpdateView();
		}


		private void unSelectAllButton_Click(object sender, ImageClickEventArgs e)
		{
			UnselectAll();
		}

		public void UnselectAll()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}


			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				int i;
				SelectedRows.Clear();
			}

			SelectedIndex = -1;
			LastSelectedDataIndex = -1;
			UpdateView();
		}

		private void copyButton_Click(object sender, ImageClickEventArgs e)
		{
			Copy();
		}

		public void Copy()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}

			CStructData structData;
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(this.RowDataObjectName);
			if (SelectionMode == SelectionModeEnum.MULTIPL_SELECTION_MODE)
			{
				int[] selectedLines = GetSelectedIndices();



				for (int i = 0; i < selectedLines.Length; i++)
				{
					stringBuilder.Append("~");
					structData = (CStructData)this.RowsDataDisplay.GetAtReturnsStructData(selectedLines[i]);

					stringBuilder.Append(structData.ToFormattedString());
				}

			}
			else if (this.SelectedIndex != -1)
			{

				stringBuilder.Append("~");
				structData = (CStructData)this.RowsDataDisplay.GetAtReturnsStructData(SelectedDataIndex);
				stringBuilder.Append(structData.ToFormattedString());
			}
			this.Page.Session["Clipboard"] = stringBuilder.ToString();
		}

		private void pastButton_Click(object sender, ImageClickEventArgs e)
		{
			Past();
		}

		public void Past()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}

			string clipBoardText = (string)Page.Session["Clipboard"];
			if (clipBoardText != null)
			{

				CStructData structData;
				IStructDataCollection structDataCollection = RowsData.CloneReturnsIStructDataCollection();

				//structDataCollection.Clear();
				string[] parts = clipBoardText.Split('~');
				int lineToInsertDataBefore = LastSelectedDataIndex;
				int firstLineInsertedAt = lineToInsertDataBefore;
				if (firstLineInsertedAt == -1)
					firstLineInsertedAt = RowsData.Count;

				if (parts[0] == this.RowDataObjectName)
				{
					for (int i = 1; i < parts.Length; i++)
					{
						if (parts[i] != "")
						{
							structData = RowsData.InsertNewReturnsStructData(lineToInsertDataBefore);
							if (lineToInsertDataBefore != -1)

								lineToInsertDataBefore++;
							structData.FromFormattedString(parts[i]);
						}
					}
				}
				ShowDataLine(firstLineInsertedAt);
				UpdateView();
			}
		}



		private void discardChangesButton_Click(object sender, ImageClickEventArgs e)
		{
			DiscardChanges();
		}

		public void DiscardChanges()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			RowsData = OriginRowsData.CloneReturnsIStructDataCollection();
			EditItemIndex = -1;
			SelectedIndex = -1;
			UpdateView();
		}

		private void saveButton_Click(object sender, ImageClickEventArgs e)
		{

			Save();
		}


		virtual public void Save()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}

			try
			{
				DataManager.BeginTrans();
				BeforeSave();
				DataManager.Save((IRecordDataCollection)RowsData);

				DataManager.CommitTrans();
				AfterSave();
				DataManager.CommitStatusAfterSave((IRecordDataCollection)RowsData);
				KeepOrigin();
				UpdateView();
				SetInformationMessage("Grid data was saved successfully");
			}
			catch (Exception ex)
			{
				if (DataManager != null)
				{
					if (DataManager.IsInsideTransaction)
					{
						DataManager.RollbackTrans();
					}
				}
				SetErrorMessage("Failed to save grid data <br> Error: " + NorthwindGeneral.GetFullExceptionMessages(ex));
			}
		}

		virtual protected void BeforeSave()
		{
		}

		virtual protected void AfterSave()
		{
		}

		private void firstPageButton_Click(object sender, ImageClickEventArgs e)
		{
			FirstPage();
		}

		public void FirstPage()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			SetCurrentPageIndex(0);
		}

		private void jumpBackButton_Click(object sender, ImageClickEventArgs e)
		{

			JumpBack();
		}


		public void JumpBack()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			int pageToJump = CurrentPageIndex - NumPagesToJump;
			if (pageToJump < 0)
				pageToJump = 0;
			SetCurrentPageIndex(pageToJump);
		}

		private void backPageButton_Click(object sender, ImageClickEventArgs e)
		{
			BackPage();
		}

		public void BackPage()
		{

			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			int pagePage = CurrentPageIndex - 1;
			if (pagePage < 0)

				pagePage = 0;
			SetCurrentPageIndex(pagePage);
		}

		private void nextPageButton_Click(object sender, ImageClickEventArgs e)
		{
			NextPage();
		}

		public void NextPage()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			int nextPage = CurrentPageIndex + 1;
			if (nextPage > LastPageNum)
				nextPage = LastPageNum;
			SetCurrentPageIndex(nextPage);

		}


		private void jumpNextButton_Click(object sender, ImageClickEventArgs e)
		{
			JumpNext();
		}

		public void JumpNext()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			int pageToJump = CurrentPageIndex + NumPagesToJump;
			if (pageToJump > LastPageNum)
				pageToJump = LastPageNum;
			SetCurrentPageIndex(pageToJump);
		}


		private void lastPageButton_Click(object sender, ImageClickEventArgs e)
		{
			LastPage();
		}


		public void LastPage()
		{

			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			SetCurrentPageIndex(LastPageNum);
		}

		private void jumpToPageButton_Click(object sender, ImageClickEventArgs e)
		{

			JumpToPage();
		}

		public void JumpToPage()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			TextBox jumpToPageTextBox = ToolBar.JumpToPageTextBox;
			if (jumpToPageTextBox != null)
			{
				int jumpToPage;
				try
				{
					jumpToPage = Convert.ToInt32(jumpToPageTextBox.Text);
					jumpToPage--;
				}

				catch (Exception ex)
				{
					jumpToPage = -1;
				}
				if (jumpToPage >= 0 && jumpToPage <= LastPageNum)
					SetCurrentPageIndex(jumpToPage);
				else
					SetErrorMessage("Invalid page num to jump to");
			}
		}

		private void pageSizeButton_Click(object sender, ImageClickEventArgs e)
		{
			SetPageSize();
		}


		public void SetPageSize()
		{
			if (this.IsInsideEdit && !EditAllRows)
			{
				FinishEditingFirst();
				return;
			}
			TextBox pageSizeTextBox = ToolBar.PageSizeTextBox;
			if (pageSizeTextBox != null)
			{
				int pageSize;
				try
				{
					pageSize = Convert.ToInt32(pageSizeTextBox.Text);
				}
				catch (Exception ex)
				{
					pageSize = -1;
				}
				if (pageSize >= 0 && pageSize <= RowsData.Count)
					PageSize = pageSize;
				else if (pageSize > RowsDataDisplay.Count)
					PageSize = RowsDataDisplay.Count;
				else
					SetErrorMessage("Invalid page size");

				if (CurrentPageIndex > RowsDataDisplay.Count / PageSize)
					SetCurrentPageIndex(RowsDataDisplay.Count / PageSize - 1);
				UpdateView();
			}
		}

		private void digButton_Click(object sender, ImageClickEventArgs e)
		{
			ImageButton imageButton = (ImageButton)sender;
			imageButton.CommandArgument = this.DataInstanceName;
			BubbleEventName = "Dig";
			this.RaiseBubbleEvent(this, e);
		}


		[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public int TotalNumPages
		{
			get
			{
				int reminder = RowsDataDisplay.Count % CurrentPageSize;

				int totalNumPages = RowsDataDisplay.Count / CurrentPageSize;
				if (