Click here to Skip to main content
13,701,212 members
Click here to Skip to main content

Stats

3M views
19.8K downloads
994 bookmarked
Posted 19 Jan 2003
Licenced MIT

SourceGrid - Open Source C# Grid Control

, 4 Aug 2013
SourceGrid is a free open source grid control. Supports virtual grid, custom cells and editors, advanced formatting options and many others features
SourceGrid2
References
SourceLibrary.dll
vssver.scc
SampleProject
App.ico
bin
Release
SampleProject.exe
SourceGrid2.dll
SourceLibrary.dll
Extensions
Add.ico
ArrowDown.ICO
ArrowUp.ICO
Delete.ICO
Refresh.ico
vssver.scc
Samples
CalcioSmall.bmp
FACE00.ICO
FACE01.ICO
FACE02.ICO
FACE04.ICO
new.bmp
vssver.scc
SourceGrid
BehaviorModels
vssver.scc
bin
Release
SourceGrid2.dll
SourceLibrary.dll
vssver.scc
Cells
vssver.scc
Common
Icons
CheckBoxChecked.ico
CheckBoxCheckedDisable.ico
CheckBoxCheckedSel.ico
CheckBoxUnChecked.ico
CheckBoxUnCheckedDisable.ico
CheckBoxUnCheckedSel.ico
clear.ico
copy.ico
cut.ico
DeleteCol.ico
DeleteRow.ico
InsertCol.ico
InsertRow.ico
paste.ico
properties.ico
SortDown.ico
SortUp.ico
Thumbs.db
vssver.scc
vssver.scc
DataModels
vssver.scc
Grid.bmp
Grids
vssver.scc
GridVirtual.bmp
SourceGrid2.snk
VisualModels
vssver.scc
SourceGrid
DemoProject
App.ico
bin
Release
DemoProject.exe
SourceGrid.dll
SourceLibrary.dll
FACE00.ICO
FACE01.ICO
FACE02.ICO
FACE04.ICO
new.bmp
PropertyStyleGrid
WorksheetStyleGrid
References
SourceLibrary.dll
SourceGrid
bin
Release
SourceGrid.dll
Cells
Models
PropertyStyleGrid
SourceGrid.snk
TypeCreator
Utility
Chris.Beckett.MenuImageLib
SubItem16.ico
Control
Controls
Icons
CheckBoxChecked.ico
CheckBoxCheckedDisable.ico
CheckBoxCheckedSel.ico
CheckBoxUnChecked.ico
CheckBoxUnCheckedDisable.ico
CheckBoxUnCheckedSel.ico
clear.ico
copy.ico
cut.ico
DeleteCol.ico
DeleteRow.ico
InsertCol.ico
InsertRow.ico
paste.ico
properties.ico
SortDown.ico
SortUp.ico
WorksheetStyleGrid
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

namespace SourceGrid2.Cells.Real
{
	/// <summary>
	/// Represents a Cell in a grid, with Cell.Value support and row/col span. Support also ToolTipText, ContextMenu and Cursor
	/// </summary>
	public class Cell : Virtual.CellVirtual, ICell, ICellToolTipText, ICellCursor, ICellContextMenu
	{
		#region Constructors
		/// <summary>
		/// Cell constructor
		/// </summary>
		public Cell():this(null)
		{
		}

		/// <summary>
		/// Cell constructor
		/// </summary>
		/// <param name="p_Value">The value of the cell</param>
		public Cell(object p_Value)
		{
			Value = p_Value;
			VisualModel = VisualModels.Common.Default; //Default Visual properties
			Behaviors.Add(BehaviorModels.ToolTipText.Default);
			Behaviors.Add(BehaviorModels.Cursor.Default);
			Behaviors.Add(BehaviorModels.ContextMenu.Default);
		}

		/// <summary>
		/// Create a cell with an editor using the type specified. (using Utility.CreateCellModel).
		/// </summary>
		/// <param name="p_Value"></param>
		/// <param name="p_Type">Type of the cell</param>
		public Cell(object p_Value, Type p_Type):this(p_Value)
		{
			DataModel = Utility.CreateDataModel(p_Type);
		}

		/// <summary>
		/// Cell constructor
		/// </summary>
		/// <param name="p_Value">The value of the cell</param>
		/// <param name="p_Editor">The editor of this cell</param>
		public Cell(object p_Value, DataModels.IDataModel p_Editor):this(p_Value)
		{
			DataModel = p_Editor;
		}

		/// <summary>
		/// Create a new instance of the cell.
		/// </summary>
		/// <param name="p_Value">Initial value of the cell.</param>
		/// <param name="p_Editor">Formatters used for string conversion, if null is used a shared default formatter.</param>
		/// <param name="p_VisualModel">Visual properties of the current cell, if null is used a shared default properties.</param>
		public Cell(object p_Value, DataModels.IDataModel p_Editor, VisualModels.IVisualModel p_VisualModel):this(p_Value)
		{
			DataModel = p_Editor;

			if (p_VisualModel!=null)
				VisualModel = p_VisualModel;
		}

		#endregion

		#region Cell Data (Value, DisplayText, Tag)

		//ATTENTION: is reccomanded that all the actions fired by the user interface does not modify this property
		// instead call the CellEditor.ChangeCellValue to preserve data consistence

		/// <summary>
		/// Get the value of the current cell
		/// </summary>
		/// <param name="p_Position"></param>
		/// <returns></returns>
		public override object GetValue(Position p_Position)
		{
			return Value;
		}

		/// <summary>
		/// Set the value of the cell
		/// </summary>
		/// <param name="p_Position"></param>
		/// <param name="p_Value"></param>
		public override void SetValue(Position p_Position, object p_Value)
		{
			if (m_Value != p_Value)
			{
				m_Value = p_Value;

				OnValueChanged(new PositionEventArgs(p_Position, this));
			}
		}

		/// <summary>
		/// The string representation of the Cell.GetValue method (default Value.ToString()).
		/// </summary>
		/// <param name="p_Position"></param>
		/// <returns></returns>
		public override string GetDisplayText(Position p_Position)
		{
			return DisplayText;
		}


		/// <summary>
		/// The string representation of the Cell.Value property (default Value.ToString())
		/// </summary>
		public virtual string DisplayText
		{
			get
			{
				return base.GetDisplayText(m_Range.Start);
			}
		}

		private object m_Value = null;
		/// <summary>
		/// Value of the cell 
		/// </summary>
		public virtual object Value
		{
			get{return m_Value;}
			set
			{
				SetValue(m_Range.Start, value);
			}
		}

		/// <summary>
		/// Object to put additional info for this cell
		/// </summary>
		private object m_Tag = null;
		/// <summary>
		/// Object to put additional info for this cell
		/// </summary>
		public virtual object Tag
		{
			get{return m_Tag;}
			set{m_Tag = value;}
		}

		/// <summary>
		/// ToString method
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			return DisplayText;
		}
		#endregion

		#region LinkToGrid

		/// <summary>
		/// Link the cell at the specified grid. 
		/// For Cell derived classes you must call BindToGrid(Grid p_grid, Position p_Position).
		/// </summary>
		/// <param name="p_grid"></param>
		public override void BindToGrid(GridVirtual p_grid)
		{
			throw new SourceGridException("Invalid method for this class, use BindToGrid(Grid p_grid, Position p_Position)");
		}


		/// <summary>
		/// Link the cell at the specified grid.
		/// REMARKS: To insert a cell in a grid use Grid.InsertCell, this methos is for internal use only
		/// </summary>
		/// <param name="p_grid"></param>
		/// <param name="p_Position"></param>
		public virtual void BindToGrid(Grid p_grid, Position p_Position)
		{
			m_Range.MoveTo(p_Position);
			base.BindToGrid(p_grid);
			RefreshSpanSearch();
		}
		/// <summary>
		/// Remove the link of the cell from the previous grid.
		/// REMARKS: To remove a cell from a grid use the grid.RemoveCell, this method is for internal use only
		/// </summary>
		public override void UnBindToGrid()
		{
			m_Range.MoveTo(Position.Empty);
			base.UnBindToGrid();
		}
		#endregion

		#region Range and Position
		private Range m_Range = Range.Empty; //la posizione � Range.Start

		/// <summary>
		/// Returns the current Row and Col position. If this cell is not attached to the grid returns Position.Empty. And the range occupied by the current cell.
		/// Returns the Range of the cells occupied by the current cell. If RowSpan and ColSpan = 1 then this method returns a single cell.
		/// </summary>
		public Range Range
		{
			get{return m_Range;}
		}

		/// <summary>
		/// Current Row
		/// </summary>
		public int Row
		{
			get{return m_Range.Start.Row;}
		}

		/// <summary>
		/// Current Column
		/// </summary>
		public int Column
		{
			get{return m_Range.Start.Column;}
		}
		#endregion

		#region Row/Col Span

		private void RefreshSpanSearch()
		{
			if (Grid is SourceGrid2.Grid)
			{
				Grid l_grid = (SourceGrid2.Grid)Grid;
				l_grid.SetMaxSpanSearch(Math.Max(ColumnSpan, RowSpan)-1, false);
			}
		}

		/// <summary>
		/// ColSpan for merge operation
		/// </summary>
		public int ColumnSpan
		{
			get{return m_Range.ColumnsCount;}
			set
			{
				m_Range.ColumnsCount = value;
				RefreshSpanSearch();
				Invalidate();
			}
		}
		/// <summary>
		/// RowSpan for merge operation
		/// </summary>
		public int RowSpan
		{
			get{return m_Range.RowsCount;}
			set
			{
				m_Range.RowsCount = value;
				RefreshSpanSearch();
				Invalidate();
			}
		}

		/// <summary>
		/// Returns true if the position specified is inside the current cell range (use Range.Contains)
		/// </summary>
		/// <param name="p_Position"></param>
		/// <returns></returns>
		public virtual bool ContainsPosition(Position p_Position)
		{
			return m_Range.Contains(p_Position);
		}
		#endregion

		#region CalculateRequiredSize
		/// <summary>
		/// If the cell is not linked to a grid the result is not accurate (Font can be null). This method use RowSpan and ColSpan of the current Cell (InternalGetRequiredSize).
		/// </summary>
		/// <param name="p_Position">Position of the current cell</param>
		/// <param name="g"></param>
		/// <returns></returns>
		public override Size CalculateRequiredSize(Position p_Position, Graphics g)
		{
			//override base CalculateRequiredSize to use correct RowSpan and ColumnSpan
			return InternalCalculateRequiredSize(p_Position, g, RowSpan, ColumnSpan);
		}
		#endregion

		#region Selection

		/// <summary>
		/// Gets or Sets if the current cell is selected
		/// </summary>
		public bool Select
		{
			get
			{
				if (Grid!=null)
					return Grid.Selection.Contains( m_Range.Start );
				else
					return false;
			}
			set
			{
				if (Select != value && Grid != null)
				{
					if (value)
						Grid.Selection.Add( m_Range.Start );
					else
						Grid.Selection.Remove( m_Range.Start );
				}
			}
		}

		#endregion

		#region Focus
		/// <summary>
		/// True if the has the focus
		/// </summary>
		public bool Focused
		{
			get
			{
				if (Grid!=null)
					return Grid.FocusCellPosition == m_Range.Start;
				else
					return false;
			}
		}

		/// <summary>
		/// Give the focus at the cell
		/// </summary>
		/// <returns>Returns if the cell can receive the focus</returns>
		public bool Focus()
		{
			if (Grid!=null)
				return Grid.SetFocusCell(m_Range.Start);
			else
				return false;
		}
		
		/// <summary>
		/// Remove the focus from the cell
		/// </summary>
		/// <returns>Returns true if the cell can leave the focus otherwise false</returns>
		public bool LeaveFocus()
		{
			if (Grid!=null && Focused)
				return Grid.SetFocusCell(Position.Empty);
			else
				return true;
		}

		#endregion

		#region Editing
		/// <summary>
		/// True if this cell is currently in edit state, otherwise false.
		/// </summary>
		public bool IsEditing()
		{
			return IsEditing(m_Range.Start);
		}

		/// <summary>
		/// Start the edit operation with the current editor specified in the Model property. Using the current cell position.
		/// </summary>
		/// <param name="p_Position">Not used with this type of class.</param>
		/// <param name="p_NewStartEditValue">The value that the editor receive</param>
		public override void StartEdit(Position p_Position, object p_NewStartEditValue)
		{
			base.StartEdit (m_Range.Start, p_NewStartEditValue); //uso come posizione quella corrente
		}
		#endregion

		#region Invalidate
		/// <summary>
		/// Invalidate this cell
		/// </summary>
		public override void Invalidate()
		{
			if (Grid!=null)
				Grid.InvalidateRange(Range);
		}
		#endregion

		#region ToolTipText

		private string m_ToolTipText;
		/// <summary>
		/// ToolTipText for the current cell
		/// </summary>
		public virtual string ToolTipText
		{
			get{return m_ToolTipText;}
			set{m_ToolTipText = value;}
		}

		/// <summary>
		/// Returns the tooltip text for the current cell position. Returns the ToolTipText property.
		/// </summary>
		/// <param name="p_Position"></param>
		/// <returns></returns>
		public virtual string GetToolTipText(Position p_Position)
		{
			return m_ToolTipText;
		}
		#endregion

		#region ICellContextMenu
		/// <summary>
		/// To optimize creation of the cell I create only the collection when we need it
		/// </summary>
		private MenuCollection m_ContextMenuItems = null;

		/// <summary>
		/// Context Menu
		/// </summary>
		public MenuCollection ContextMenuItems
		{
			get
			{
				if (m_ContextMenuItems==null)
					m_ContextMenuItems = new MenuCollection();
				return m_ContextMenuItems;
			}
			set{m_ContextMenuItems = value;}
		}

		/// <summary>
		/// Get the contextmenu of the specified cell
		/// </summary>
		/// <param name="p_Position"></param>
		public MenuCollection GetContextMenu(Position p_Position)
		{
			return m_ContextMenuItems;
		}
		#endregion

		#region ICellCursor Members

		private Cursor m_Cursor;

		/// <summary>
		/// Cursor of the cell
		/// </summary>
		public Cursor Cursor
		{
			get{return m_Cursor;}
			set{m_Cursor = value;}
		}

		/// <summary>
		/// Get the Cursor property. This is required by the ICellCursor interface.
		/// </summary>
		/// <param name="p_Position"></param>
		/// <returns></returns>
		public virtual Cursor GetCursor(Position p_Position)
		{
			return m_Cursor;
		}
		#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 MIT License

Share

About the Author

Davide Icardi
Software Developer
Italy Italy
No Biography provided

You may also be interested in...

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01-2016 | 2.8.180910.1 | Last Updated 4 Aug 2013
Article Copyright 2003 by Davide Icardi
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid