Click here to Skip to main content
15,893,486 members
Articles / Programming Languages / C# 4.0

Relationship Oriented Programming - The IDE plus More on Agile Project Management

Rate me:
Please Sign up or sign in to vote.
4.98/5 (25 votes)
12 Mar 2012CPOL81 min read 77.8K   1.2K   49  
An Integrated Development Environment (IDE) for the Relationship Oriented Programming Tool.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Columns;

using Clifton.Tools.Data;

using Interfaces.UI;

namespace UI.DX
{
	public class DxGridControl : GridControl, IGrid
	{
		protected GridView gridView;

		public bool BestFit { get; set; }
		public bool ColumnAutoWidth { get; set; }
		public bool readOnly;

		public bool ReadOnly
		{
			get { return readOnly; }
			set 
			{ 
				readOnly = value;
				gridView.OptionsBehavior.Editable = value;
			}
		}

		public bool ShowGroupPanel
		{
			get { return gridView.OptionsView.ShowGroupPanel; }
			set { gridView.OptionsView.ShowGroupPanel = value; }
		}

		public List<DataRow> SelectedRows
		{
			get
			{
				List<DataRow> selectedRows = new List<DataRow>();
				if (DataSource is DataView)
				{
					gridView.GetSelectedRows().ForEach(t => selectedRows.Add(((DataRowView)gridView.GetRow(t)).Row));
				}
				else if (DataSource is DataTable)
				{
					gridView.GetSelectedRows().ForEach(t => selectedRows.Add((DataRow)gridView.GetRow(t)));
				}
				else if (DataSource is DataSet)
				{
					gridView.GetSelectedRows().ForEach(t => selectedRows.Add(((DataRowView)gridView.GetRow(t)).Row));
				}
				else if (DataSource is BindingSource)
				{
					gridView.GetSelectedRows().ForEach(t => selectedRows.Add(((DataRowView)gridView.GetRow(t)).Row));
				}
				else
				{
					throw new ApplicationException("The grid's data source must be a DataView, DataTable, or DataSet.");
				}

				return selectedRows;
			}
		}

		public int SelectedRowsCount
		{
			get
			{
				return gridView.GetSelectedRows().Length;
			}
		}

		new public object DataSource
		{
			get { return base.DataSource; }
			set 
			{
				Clear();
				base.DataSource = value;
				gridView.OptionsView.ColumnAutoWidth = ColumnAutoWidth;

				if (BestFit)
				{
					gridView.BestFitColumns();
				}
			}
		}

		new public string DataMember
		{
			get { return base.DataMember; }
			set { base.DataMember = value; }
		}

		/// <summary>
		/// Stub, supports .NET DataGridView control.
		/// </summary>
		public bool AutoGenerateColumns
		{
			get { return gridView.OptionsBehavior.AutoPopulateColumns; }
			set { gridView.OptionsBehavior.AutoPopulateColumns = value; }
		}

		public string DataTableName
		{
			get
			{
				if (DataSource is DataView)
				{
					return ((DataView)DataSource).Table.TableName;
				}
				else if (DataSource is DataTable)
				{
					return ((DataTable)DataSource).TableName;
				}
				else if (DataSource is DataSet)
				{
					return DataMember;
				}
				else
				{
					throw new ApplicationException("The grid's DataSource must be either a DataView or DataTable.");
				}
			}
		}

		public DxGridControl()
		{
			gridView = new GridView();
			gridView.GridControl = this;
			MainView = gridView;
			ViewCollection.Add(gridView);

			gridView.OptionsSelection.MultiSelect = true;
			gridView.ShowingEditor += new CancelEventHandler(OnShowingEditor);
			// gridView.ShownEditor += new EventHandler(OnShownEditor);
			// gridView.HiddenEditor += new EventHandler(OnHiddenEditor);
			gridView.KeyDown += new System.Windows.Forms.KeyEventHandler(OnKeyDown);
			gridView.OptionsBehavior.AllowAddRows = DefaultBoolean.True;

			// By default, for a DataSet, we do not want to show relationships on the same grid.
			gridView.OptionsDetail.EnableMasterViewMode = false;
		}

		public void ClearColumns()
		{
			gridView.Columns.Clear();
		}

		/// <summary>
		/// Required to get the grid to change its column list when a new data source is assigned.
		/// </summary>
		public void Clear()
		{
			base.DataSource = null;
			gridView.Columns.Clear();
		}

		/// <summary>
		/// Stub.  Used in .NET DataGridView control.
		/// </summary>
		public void FixColumnHeaders() {}

		public void AddColumn(DataColumn dc)
		{
			GridColumn gc = new GridColumn();
			// gc.AppearanceCell.TextOptions.HAlignment = (HorzAlignment)ci.HorizontalAlignment;
			gc.AppearanceCell.Options.UseTextOptions = true;
			RepositoryItem editor = null;

			switch (dc.DataType.Name.ToUpper())
			{
				case "STRING":
				case "INT32":
					editor = new RepositoryItemTextEdit();
					break;

				case "DATETIME":
					editor = new RepositoryItemDateEdit();
					((RepositoryItemDateEdit)editor).EditMask = "MM/dd/yyyy hh:mm tt";
					((RepositoryItemDateEdit)editor).Mask.UseMaskAsDisplayFormat = true;
					break;

				case "BOOLEAN":
					break;

				default:
					editor = new RepositoryItemCheckEdit();
					break;
			}

			gc.ColumnEdit = editor;
			gc.Caption = dc.Caption;
			gc.FieldName = dc.ColumnName;
			gc.VisibleIndex = gridView.Columns.Count;						// Set the index first...
			gc.Visible = !(dc.ColumnMapping == MappingType.Hidden);			// ... then the visibility, otherwise setting the index sets the column to always visible.

			gridView.Columns.Add(gc);
		}

		public void AddLookupColumn(DataView dataSource, string valueMember, string displayMember, DataColumn dc)
		{
			GridColumn gc = new GridColumn();

			RepositoryItemLookUpEdit comboBox = new RepositoryItemLookUpEdit();
			comboBox.DataSource = dataSource;
			comboBox.ValueMember = valueMember;
			comboBox.DisplayMember = displayMember;
			comboBox.NullText = String.Empty;
			comboBox.ShowHeader = false;
			comboBox.ShowFooter = false;
			comboBox.Columns.Clear();
			LookUpColumnInfo lookupColumnInfo = new LookUpColumnInfo(displayMember);
			comboBox.Columns.Add(lookupColumnInfo);
			comboBox.ThrowExceptionOnInvalidLookUpEditValueType = true;

			gc.FieldName = dc.ColumnName;
			gc.ColumnEdit = comboBox;
			gc.Caption = dc.Caption;
			gc.VisibleIndex = gridView.Columns.Count;
			gridView.Columns.Add(gc);
		}

		public void AdjustColumnWidths()
		{
			gridView.OptionsView.ColumnAutoWidth = ColumnAutoWidth;

			if (BestFit)
			{
				gridView.BestFitColumns();
			}
		}

		/// <summary>
		/// Cancel the ability to edit the field if the grid is in read-only mode.
		/// TODO: There must be a better way to do this!
		/// </summary>
		protected void OnShowingEditor(object sender, CancelEventArgs e)
		{
			e.Cancel = readOnly;
		}

		protected void OnKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if (e.KeyCode == Keys.Down && (gridView.IsLastRow || gridView.IsNewItemRow(gridView.FocusedRowHandle)))
			{
				gridView.CloseEditor();
				gridView.UpdateCurrentRow();
				gridView.AddNewRow();
				e.Handled = true;
			}
		}

		// =========== The next two events handle custom lookup values depending on the row being edited.
		// Enable the ShowEditor and HiddenEditor events to enable this.

		/*
		* 
		* From : http://community.devexpress.com/forums/p/68358/232492.aspx
		Hello,

		I have a grid with a LoopUpEditor in a certain column, for this column I want to show different options in the editor depending of the row I'm editing (not the same editing options in the combo for all the rows)

		I managed to implement this in the normal .Net DataGridViewColumn control, basically what I do is select the appropiate filter in the event CellBeginEdit and disable it in the EndBeginEdit event.

		Now I'm migrating to DevExpress. While I can substitute the CellBeginEdit event for the CustomRowCellEditForEditing event in the devexpress gridcontrol, I can't find the equivalent of the EndBeginEdit event.

		I managed to implement this using the ShownEditor and HiddenEditor events as seen in this article:
		* 
		* http://documentation.devexpress.com/#WindowsForms/DevExpressXtraGridViewsBaseColumnView_ShownEditortopic
		*/

		protected DataView clone = null;

		protected void OnShownEditor(object sender, System.EventArgs e)
		{
			GridView view = sender as GridView;

			if (view.ActiveEditor is LookUpEdit)
			{
				Text = view.ActiveEditor.Parent.Name;
				LookUpEdit edit = (LookUpEdit)view.ActiveEditor;

				DataTable table = edit.Properties.DataSource as DataTable;
				clone = new DataView(table);
				DataRow row = view.GetDataRow(view.FocusedRowHandle);
				// Example:
				// clone.RowFilter = "[CountryCode] = " + row["CountryCode"].ToString();
				edit.Properties.DataSource = clone;
			}
		}

		protected void OnHiddenEditor(object sender, System.EventArgs e)
		{
			if (clone != null)
			{
				clone.Dispose();
				clone = null;
			}
		}
	}
}

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
Architect Interacx
United States United States
Blog: https://marcclifton.wordpress.com/
Home Page: http://www.marcclifton.com
Research: http://www.higherorderprogramming.com/
GitHub: https://github.com/cliftonm

All my life I have been passionate about architecture / software design, as this is the cornerstone to a maintainable and extensible application. As such, I have enjoyed exploring some crazy ideas and discovering that they are not so crazy after all. I also love writing about my ideas and seeing the community response. As a consultant, I've enjoyed working in a wide range of industries such as aerospace, boatyard management, remote sensing, emergency services / data management, and casino operations. I've done a variety of pro-bono work non-profit organizations related to nature conservancy, drug recovery and women's health.

Comments and Discussions