// -------------------------------------------------------
// SqlBuilder by Elm�Soft
// www.netcult.ch/elmue
// www.codeproject.com/KB/database/SqlBuilder.aspx
// -------------------------------------------------------
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace SqlBuilder.Controls
{
/// <summary>
/// A DataGrid which does not allow the user to add new rows
/// </summary>
public class DataGridFix : DataGrid
{
#region DataGridTextBoxColumnEx
/// <summary>
/// A Text Column which may prohibit editing
/// </summary>
public class DataGridTextBoxColumnEx : DataGridTextBoxColumn
{
int ms32_Column;
DataGridFix mi_Grid;
StringFormat mi_Trimming = new StringFormat();
public DataGridTextBoxColumnEx(DataGridFix i_Grid, int s32_Column)
{
mi_Grid = i_Grid;
ms32_Column = s32_Column;
mi_Trimming.Trimming = StringTrimming.EllipsisCharacter;
}
protected override void Edit(CurrencyManager i_DataSource, int s32_Row, Rectangle k_Bounds, bool b_ReadOnly, string s_InstantText, bool b_CellVisible)
{
if (ReadOnly)
return;
if (!mi_Grid.OnBeforeEdit(s32_Row, ms32_Column))
return;
base.Edit(i_DataSource, s32_Row, k_Bounds, b_ReadOnly, s_InstantText, b_CellVisible);
}
protected override int GetPreferredHeight(Graphics i_Graph, object o_Value)
{
SizeF k_Size = i_Graph.MeasureString(Functions.ToStr(o_Value), mi_Grid.Font, Width, mi_Trimming);
return (int)k_Size.Height + 4;
}
protected override void Paint(Graphics i_Graph, Rectangle k_Bounds, CurrencyManager i_DataSource, int s32_Row, Brush i_BkBrush, Brush i_ForeBrush, bool b_RightAlign)
{
i_BkBrush = new SolidBrush(Defaults.GridBackColor(false, false, ReadOnly));
object o_Value = GetColumnValueAtRow(i_DataSource, s32_Row);
i_Graph.FillRectangle(i_BkBrush, k_Bounds);
i_Graph.DrawString(Functions.ToStr(o_Value), mi_Grid.Font, i_ForeBrush, k_Bounds, mi_Trimming);
}
}
#endregion
#region DataGridBoolColumnEx
/// <summary>
/// A Checkbox Column which may prohibit editing
/// </summary>
public class DataGridBoolColumnEx : DataGridBoolColumn
{
int ms32_Column;
DataGridFix mi_Grid;
public DataGridBoolColumnEx(DataGridFix i_Grid, int s32_Column)
{
mi_Grid = i_Grid;
ms32_Column = s32_Column;
}
protected override void Edit(CurrencyManager i_DataSource, int s32_Row, Rectangle k_Bounds, bool b_ReadOnly, string s_InstantText, bool b_CellVisible)
{
if (ReadOnly)
return;
if (!mi_Grid.OnBeforeEdit(s32_Row, ms32_Column))
return;
base.Edit(i_DataSource, s32_Row, k_Bounds, b_ReadOnly, s_InstantText, b_CellVisible);
}
protected override void Paint(Graphics i_Graph, Rectangle k_Bounds, CurrencyManager i_DataSource, int s32_Row, Brush i_BkBrush, Brush i_ForeBrush, bool b_RightAlign)
{
i_BkBrush = new SolidBrush(Defaults.GridBackColor(false, false, ReadOnly));
// Paint the checkbox always at the top of the grid cell
i_Graph.FillRectangle(i_BkBrush, k_Bounds);
k_Bounds = new Rectangle(k_Bounds.X, k_Bounds.Y, k_Bounds.Width, 18);
base.Paint(i_Graph, k_Bounds, i_DataSource, s32_Row, i_BkBrush, i_ForeBrush, b_RightAlign);
}
}
#endregion
public delegate bool delBeforeEdit(int s32_Row, int s32_Column, ref object o_Value);
public event delBeforeEdit evBeforeEdit;
protected override void OnCreateControl()
{
base.OnCreateControl();
// Disable adding new rows
if (ListManager != null)
{
DataView i_View = (DataView)ListManager.List;
i_View.AllowNew = false;
}
}
// Adds a new column to the grid and the given table
public void AddColumn(DataGridTableStyle i_Style, DataTable i_Table, string s_ColName,
Type t_Type, int s32_Width, bool b_ReadOnly, out int s32_Column)
{
s32_Column = i_Table.Columns.Count;
i_Table.Columns.Add(s_ColName, t_Type);
DataGridColumnStyle i_Col;
if (t_Type == typeof(bool))
{
DataGridBoolColumnEx i_BoolCol = new DataGridBoolColumnEx(this, s32_Column);
i_BoolCol.AllowNull = false;
i_Col = i_BoolCol;
}
else
{
i_Col = new DataGridTextBoxColumnEx(this, s32_Column);
}
i_Col.Width = s32_Width;
i_Col.NullText = "";
i_Col.MappingName = s_ColName;
i_Col.HeaderText = s_ColName;
i_Col.ReadOnly = b_ReadOnly;
i_Style.GridColumnStyles.Add(i_Col);
}
/// <summary>
/// Fire event, return false if editing the cell is not allowed
/// </summary>
public bool OnBeforeEdit(int s32_Row, int s32_Column)
{
if (evBeforeEdit == null)
return true;
object o_Value = this[s32_Row, s32_Column];
if (!evBeforeEdit(s32_Row, s32_Column, ref o_Value))
{
this[s32_Row, s32_Column] = o_Value;
PushValue();
return false;
}
return true;
}
/// <summary>
/// Store user changes on the currently editing grid cell into the underlying datatable
/// </summary>
public void PushValue()
{
// ATTENTION: Just another wicked .NET framework bug:
// If EndCurrentEdit() is not called the rowstate in the DataTable is only set to "Modified"
// if the user terminates editing the cell with the ENTER key. If he leaves the cell with the mouse
// the new value is stored in the DataTable but the table's rowstate remains "Unchanged"
ListManager.EndCurrentEdit();
}
/// <summary>
/// The fuccccccking idiots from Microsoft$ made the function RowAutoResize() private.
/// The stupid guys also made all other properties private which access the rows directly.
/// So to adapt the height of a row to its real content height
/// here a doubleclick on the row header must be simulated.
/// </summary>
public void AutoResizeRow(int Row)
{
Rectangle k_Rect = GetCellBounds(Row, 0);
int X = RowHeaderWidth / 2;
int Y = k_Rect.Bottom;
OnMouseDown(new MouseEventArgs(MouseButtons.Left, 2, X, Y, 0));
}
}
}