3204 lines
95 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.SuperGrid
{
///<summary>
/// DataBinding helper class
///</summary>
public class DataBinder : IDisposable
{
#region Private variables
private readonly GridPanel _Panel;
private CurrencyManager _CurrencyManager;
private PropertyDescriptorCollection _Pdc;
private DataView _DataView;
private DataRow _TempDataRow;
private BindingSource _BindingSource;
private BindingSource _BaseBindingSource;
private object _BaseDataSource;
private string _BaseDataMember;
private bool _ConnectionInProgress;
private bool _NotificationInProgress;
private bool _UpdateInProgress;
private bool _UpdatePosInProgress;
private ushort _DataResetCount;
private ushort _BeginUpdateCount;
private object _LastDataItemAdded;
#endregion
///<summary>
/// DataBinding
///</summary>
///<param name="panel"></param>
internal DataBinder(GridPanel panel)
{
_Panel = panel;
}
#region Internal properties
#region BaseDataMember
internal string BaseDataMember
{
get { return (_BaseDataMember); }
set { _BaseDataMember = value; }
}
#endregion
#region BaseDataSource
internal object BaseDataSource
{
get { return (_BaseDataSource); }
set { _BaseDataSource = value; }
}
#endregion
#region CanDeleteRow
internal bool CanDeleteRow
{
get
{
if (CurrencyManager != null)
{
if (_DataView != null)
return (_DataView.AllowDelete);
}
return (true);
}
}
#endregion
#region CanInsertRow
internal bool CanInsertRow
{
get
{
if (CurrencyManager != null)
{
if (_DataView != null)
return (_DataView.AllowNew);
}
return (true);
}
}
#endregion
#region ConnectionInProgress
internal bool ConnectionInProgress
{
get { return (_ConnectionInProgress); }
set { _ConnectionInProgress = value; }
}
#endregion
#region CurrencyManager
internal CurrencyManager CurrencyManager
{
get { return (_CurrencyManager); }
set
{
if (_CurrencyManager != value)
{
if (_CurrencyManager != null)
{
_CurrencyManager.ListChanged -= CurrencyManagerListChanged;
_CurrencyManager.PositionChanged -= CmPositionChanged;
_CurrencyManager.MetaDataChanged -= CurrencyManagerMetaDataChanged;
_Panel.SuperGrid.LoadVirtualRow -= SuperGridLoadVirtualRow;
}
_CurrencyManager = value;
if (_BaseBindingSource != null)
_BaseBindingSource.PositionChanged -= BsPositionChanged;
_BaseBindingSource = null;
if (_CurrencyManager != null)
{
_Pdc = CurrencyManager.GetItemProperties();
if (_Panel.IsSubPanel == false)
_CurrencyManager.PositionChanged += CmPositionChanged;
_BaseBindingSource = _Panel.DataSource as BindingSource;
if (_BaseBindingSource != null)
_BaseBindingSource.PositionChanged += BsPositionChanged;
_CurrencyManager.MetaDataChanged += CurrencyManagerMetaDataChanged;
if (_Panel.VirtualMode == true)
{
_Panel.VirtualRowCount = _CurrencyManager.Count;
_Panel.SuperGrid.LoadVirtualRow += SuperGridLoadVirtualRow;
}
}
else
{
_Pdc = null;
}
}
}
}
#region CurrencyManagerMetaDataChanged
void CurrencyManagerMetaDataChanged(object sender, EventArgs e)
{
if (CurrencyManager != null)
{
_Pdc = CurrencyManager.GetItemProperties();
_Panel.InvalidateMerge();
}
}
#endregion
#endregion
#region DataResetCount
internal ushort DataResetCount
{
get { return (_DataResetCount); }
set
{
_DataResetCount = value;
if (_Panel.VirtualMode == true)
_Panel.VirtualRows.Clear();
if (_UpdatingFilter == true)
{
_Panel.NeedToUpdateBoundData = true;
}
else
{
_Panel.NeedToUpdateBindings = true;
_Panel.NeedToUpdateDataFilter = true;
}
_Panel.UnDeleteAll();
_Panel.InvalidateMerge();
}
}
#endregion
#region DataView
internal DataView DataView
{
get { return (_DataView); }
set { _DataView = value; }
}
#endregion
#region GetValue
internal object GetValue(GridCell cell, object value)
{
if (cell.GridRow.IsTempInsertRow == false)
{
if (CurrencyManager != null && _Pdc != null)
{
if ((uint)cell.GridRow.DataItemIndex < CurrencyManager.List.Count)
{
int index = cell.GridRow.DataItemIndex;
if (_Panel.VirtualMode == true && _Panel.VirtualTempInsertRow != null)
{
if (index > _Panel.VirtualTempInsertRow.RowIndex)
index--;
}
object dataItem = CurrencyManager.List[index];
PropertyDescriptorCollection pdc = GetPdc(dataItem);
GridColumn col = _Panel.Columns[cell.ColumnIndex];
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
if (pd != null)
return (pd.GetValue(dataItem));
}
}
}
return (value);
}
#endregion
#region IsSortable
internal bool IsSortable
{
get
{
if (_BaseDataSource is DataSet)
return (true);
if (_BaseDataSource is IBindingList)
{
IBindingList list = (IBindingList)_BaseDataSource;
return (list.SupportsSorting);
}
if (_BaseDataSource is IListSource)
{
IList list2 = ((IListSource)_BaseDataSource).GetList();
if (list2 is IBindingList)
return (((IBindingList)list2).SupportsSorting);
}
return (false);
}
}
#endregion
#region IsUpdateSuspended
internal bool IsUpdateSuspended
{
get { return (_BeginUpdateCount > 0); }
}
#endregion
#region NotificationInProgress
internal bool NotificationInProgress
{
get { return (_NotificationInProgress); }
set { _NotificationInProgress = value; }
}
#endregion
#region Pdc
internal PropertyDescriptorCollection Pdc
{
get { return (_Pdc); }
set { _Pdc = value; }
}
#endregion
#region RowCount
internal int RowCount
{
get
{
if (CurrencyManager != null)
return (CurrencyManager.Count);
return (0);
}
}
#endregion
#region SetValue
internal void SetValue(GridCell cell, object value)
{
if (cell.GridRow.IsTempInsertRow == false)
{
if (CurrencyManager != null && _Pdc != null)
{
GridRow row = (GridRow)cell.GridRow;
if ((uint)row.DataItemIndex < CurrencyManager.List.Count)
{
object dataItem = CurrencyManager.List[row.DataItemIndex];
PropertyDescriptorCollection pdc = GetPdc(dataItem);
GridColumn col = _Panel.Columns[cell.ColumnIndex];
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
if (pd != null)
{
if (pd.IsReadOnly == false)
{
object cvalue = value;
if ((value != null && Convert.IsDBNull(value) == false) &&
value.GetType() != pd.PropertyType && (value is IConvertible))
{
cvalue = Convert.ChangeType(value, Nullable.GetUnderlyingType(pd.PropertyType) ?? pd.PropertyType);
}
pd.SetValue(dataItem, cvalue);
UpdatePosInProgress = true;
CurrencyManager.EndCurrentEdit();
UpdatePosInProgress = false;
}
}
}
}
}
}
#endregion
#region UpdateInProgress
internal bool UpdateInProgress
{
get { return (_UpdateInProgress); }
set { _UpdateInProgress = value; }
}
#endregion
#region UpdatePosInProgress
internal bool UpdatePosInProgress
{
get { return (_UpdatePosInProgress); }
set { _UpdatePosInProgress = value; }
}
#endregion
#endregion
#region Clear
internal void Clear()
{
if (_Panel.SuperGrid != null)
_Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand;
CurrencyManager = null;
_BaseDataSource = null;
_BaseDataMember = null;
_DataView = null;
_BindingSource = null;
_Panel.ActiveRow = null;
_Panel.MergeScan = null;
_Panel.DataRelation = null;
if (_Panel.VirtualMode == true)
{
_Panel.VirtualTempInsertRow = null;
_Panel.VirtualRows.Clear();
}
_TempDataRow = null;
_LastDataItemAdded = null;
}
#endregion
#region DataConnect
internal void DataConnect()
{
_BaseDataSource = _Panel.DataSource;
_BaseDataMember = _Panel.DataMember;
if (_BaseDataSource != null)
{
_BindingSource = _BaseDataSource as BindingSource;
if (_BindingSource != null)
{
BindingSource bs = _BindingSource.DataSource as BindingSource;
if (bs != null)
{
if (string.IsNullOrEmpty(_BindingSource.DataMember) == false)
_BaseDataMember = _BindingSource.DataMember;
else
_BindingSource = null;
while (bs.DataSource is BindingSource)
bs = (BindingSource)bs.DataSource;
DataSet dss = bs.DataSource as DataSet;
if (dss != null)
{
DataRelation dsr = dss.Relations[_BaseDataMember];
if (dsr != null)
{
_BaseDataSource = dss;
_BaseDataMember = dsr.ChildTable.TableName;
}
}
}
else
{
_BaseDataSource = _BindingSource.DataSource;
_BaseDataMember = _BindingSource.DataMember;
}
}
DataView = null;
if (_BaseDataSource is DataSet)
AddDataSetTable((DataSet)_BaseDataSource, _BaseDataMember);
//else if (_BaseDataSource is DataTable)
// AddDataTable((DataTable)_BaseDataSource);
else if (_BaseDataSource is IBindingList)
AddIList((IBindingList)_BaseDataSource);
else if (_BaseDataSource is IList)
AddIList((IList)_BaseDataSource);
else if (_BaseDataSource is IListSource)
{
DataTable dt = _BaseDataSource as DataTable;
if (dt != null)
DataView = dt.DefaultView;
AddIList(((IListSource)_BaseDataSource).GetList());
}
else
AddDefaultObject(_BaseDataSource);
}
}
#endregion
#region SetDataConnection
private bool SetDataConnection(object dataSource)
{
if (ConnectionInProgress == false)
{
ClearDataNotification(dataSource);
if (_BindingSource != null || _Panel.SuperGrid.BindingContext != null)
{
ConnectionInProgress = true;
try
{
SetDataNotification(dataSource);
}
finally
{
ConnectionInProgress = false;
}
}
}
return (NotificationInProgress == false);
}
#endregion
#region SetDataNotification
private void SetDataNotification(object dataSource)
{
ISupportInitializeNotification notification =
dataSource as ISupportInitializeNotification;
if (notification == null || notification.IsInitialized == true)
{
CurrencyManager = (_BindingSource != null)
? _BindingSource.CurrencyManager
: _Panel.SuperGrid.BindingContext[DataView ?? dataSource] as CurrencyManager;
}
else
{
CurrencyManager = null;
if (NotificationInProgress == false)
{
notification.Initialized += DataSourceInitialized;
NotificationInProgress = true;
}
}
}
#endregion
#region ClearDataNotification
private void ClearDataNotification(object dataSource)
{
ISupportInitializeNotification notification =
dataSource as ISupportInitializeNotification;
if (notification != null && NotificationInProgress == true)
{
notification.Initialized -= DataSourceInitialized;
NotificationInProgress = false;
}
}
#endregion
#region DataSourceInitialized
private void DataSourceInitialized(object sender, EventArgs e)
{
ISupportInitializeNotification dataSource =
_Panel.DataSource as ISupportInitializeNotification;
if (dataSource != null)
{
NotificationInProgress = false;
dataSource.Initialized -= DataSourceInitialized;
CurrencyManager =
_Panel.SuperGrid.BindingContext[dataSource] as CurrencyManager;
}
}
#endregion
#region CmPositionChanged
void CmPositionChanged(object sender, EventArgs e)
{
if (IsUpdateSuspended == false && UpdatePosInProgress == false)
{
CurrencyManager cm = sender as CurrencyManager;
if (cm != null && cm == _CurrencyManager)
UpdatePosition(cm.Position);
}
}
#region BsPositionChanged
void BsPositionChanged(object sender, EventArgs e)
{
if (_UpdatePosInProgress == false)
{
BindingSource bs = sender as BindingSource;
if (bs != null)
UpdatePosition(bs.Position);
}
}
#endregion
#region UpdatePosition
private void UpdatePosition(int position)
{
if (_Panel.IsSubPanel == false)
{
GridRow row = FindDataGridRowIndex(position);
if (row != null && _Panel.ActiveRow != row)
{
try
{
_UpdatePosInProgress = true;
if (row.Visible == false)
row.Visible = true;
if (_Panel.AutoSelectNewBoundRows == true)
{
_Panel.ClearAll();
_Panel.SetActiveRow(row, true);
_Panel.SetSelectedRows(row.GridIndex, 1, true);
bool skey = (_Panel.MultiSelect == true) ?
((Control.ModifierKeys & Keys.Shift) == Keys.Shift) : false;
if (skey == false || _Panel.SelectionRowAnchor == null)
_Panel.SelectionRowAnchor = row;
row.EnsureVisible();
}
}
finally
{
_UpdatePosInProgress = false;
}
}
}
}
#endregion
#endregion
#region SetPosition
internal bool SetPosition(GridRow row)
{
if (_UpdatePosInProgress == false)
{
if (row != null && row.IsTempInsertRow == false)
{
if (CurrencyManager != null)
{
if (SetCmPosition(row) == false)
return (false);
_Panel.ActiveRow = row;
if (_Panel.IsSubPanel == false)
{
if (_BaseBindingSource != null)
_BaseBindingSource.Position = CurrencyManager.Position;
}
}
}
}
return (true);
}
#region SetCmPosition
private bool SetCmPosition(GridRow row)
{
if (CurrencyManager == null)
return (false);
while (true)
{
_UpdatePosInProgress = true;
try
{
CurrencyManager.Position = row.DataItemIndex;
break;
}
catch (Exception exp)
{
GridRow crow = null;
if ((uint)CurrencyManager.Position < _Panel.Rows.Count)
{
crow = _Panel.Rows[CurrencyManager.Position] as GridRow;
if (crow != null)
ReloadRow(crow);
}
bool retry = false;
bool throwException = false;
if (_Panel.SuperGrid.HasDataErrorHandler == true)
{
object value = crow;
if (_Panel.SuperGrid.DoDataErrorEvent(_Panel, null, exp,
DataContext.SetRowPosition, ref value, ref throwException, ref retry) == true)
{
return (false);
}
}
if (throwException == true)
throw;
if (retry == false)
return (false);
}
finally
{
_UpdatePosInProgress = false;
}
}
return (true);
}
#endregion
#endregion
#region AddIList
internal void AddIList(IList list)
{
bool autogen = _Panel.AutoGenerateColumns;
ProcessChildRelations crVisibility = _Panel.ProcessChildRelations;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
_Panel, null, null, ref autogen, ref crVisibility) == false)
{
AddIList(list, autogen, crVisibility);
}
}
#region AddIList
internal void AddIList(IList list, bool autogen, ProcessChildRelations crProcess)
{
if (SetDataConnection(list) == true)
{
if (_Pdc != null)
{
if (autogen == true && _Panel.IsDesignerHosted == false)
AutoGenerateListColumns(null);
if (_Panel.VirtualMode == false)
{
if (crProcess != ProcessChildRelations.Never)
{
bool rowsUnresolved = false;
for (int i = 0; i < list.Count; i++)
{
object o = list[i];
if (o != null)
{
GridRow row = GetNewRow(o);
row.DataItem = o;
row.DataItemIndex = i;
Type type = o.GetType();
if (type != null)
{
if (CheckNestedFields(row, type, crProcess) == false)
CheckNestedProperties(row, type, crProcess);
}
rowsUnresolved |= row.RowsUnresolved;
_Panel.Rows.Add(row);
}
}
if (rowsUnresolved == true)
{
_Panel.ShowTreeButtons = true;
_Panel.ShowTreeLines = true;
_Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand;
_Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand;
}
}
}
UpdateSuperGridSort(false);
}
if (CurrencyManager != null)
{
CurrencyManager.ListChanged -= CurrencyManagerListChanged;
CurrencyManager.ListChanged += CurrencyManagerListChanged;
}
_Panel.SuperGrid.DoDataBindingCompleteEvent(_Panel);
if (_Panel.ShowInsertRow == true)
{
_Panel.ShowInsertRow = false;
_Panel.ShowInsertRow = true;
}
}
}
#region CheckNestedFields
private bool CheckNestedFields(GridRow row, Type type, ProcessChildRelations crProcess)
{
if ((_Panel.NestedListScanTypes & NestedListScanTypes.Fields) == NestedListScanTypes.Fields)
{
FieldInfo[] fia = type.GetFields();
foreach (FieldInfo fi in fia)
{
if (IsNestedList(fi.FieldType.Name) == true)
{
if (IsVisibleItem(type, fi) == true)
{
if (crProcess == ProcessChildRelations.Always || fia.Length > 0)
{
row.RowsUnresolved = true;
return (true);
}
}
}
}
}
return (false);
}
#endregion
#region CheckNestedProperties
private bool CheckNestedProperties(GridRow row, Type type, ProcessChildRelations crProcess)
{
if ((_Panel.NestedListScanTypes & NestedListScanTypes.Properties) == NestedListScanTypes.Properties)
{
PropertyInfo[] pia = type.GetProperties();
foreach (PropertyInfo pi in pia)
{
if (IsNestedList(pi.PropertyType.Name) == true)
{
if (IsVisibleItem(type, pi) == true)
{
if (crProcess == ProcessChildRelations.Always || pia.Length > 0)
row.RowsUnresolved = true;
return (true);
}
}
}
}
return (false);
}
#endregion
#region IsNestedList
private bool IsNestedList(string name)
{
return (name.Equals("List`1") || name.Equals("BindingList`1"));
}
#endregion
#endregion
#region AutoGenerateListColumns
private void AutoGenerateListColumns(GetNewGridColumn callBack)
{
if (_Pdc != null)
{
foreach (PropertyDescriptor pd in _Pdc)
{
if (pd.PropertyType.IsInterface == false)
{
if (IsNestedList(pd.PropertyType.Name) == false && IsVisibleItem(pd) == true)
{
if (FindGridColumn(_Panel, pd.Name) == null)
{
GridColumn gcol = (callBack != null) ? callBack() : new GridColumn();
if (gcol != null)
{
gcol.DataPropertyName = pd.Name;
gcol.Name = pd.DisplayName;
gcol.Width = 100;
SetColumnEditor(pd.PropertyType, gcol);
_Panel.Columns.Add(gcol);
}
}
}
}
}
}
}
#endregion
#region IsVisibleItem
private bool IsVisibleItem(Type type, FieldInfo fi)
{
foreach (Attribute attr in fi.GetCustomAttributes(true))
{
IsVisibleToSuperGrid dattr = attr as IsVisibleToSuperGrid;
if (dattr != null)
return (dattr.Visible);
}
return (true);
}
private bool IsVisibleItem(Type type, PropertyInfo pi)
{
foreach (Attribute attr in pi.GetCustomAttributes(true))
{
IsVisibleToSuperGrid dattr = attr as IsVisibleToSuperGrid;
if (dattr != null)
return (dattr.Visible);
}
return (true);
}
private bool IsVisibleItem(PropertyDescriptor pd)
{
foreach (Attribute attr in pd.Attributes)
{
IsVisibleToSuperGrid dattr = attr as IsVisibleToSuperGrid;
if (dattr != null)
return (dattr.Visible);
}
return (true);
}
#endregion
#region GetNewRow
private GridRow GetNewRow(object o)
{
GridRow row = new GridRow();
PropertyDescriptorCollection pdc = GetPdc(o);
foreach (GridColumn col in _Panel.Columns)
{
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
object value = (pd != null)
? pd.GetValue(o) : null;
row.Cells.Add(new GridCell(value));
}
return (row);
}
#endregion
#endregion
#region AddDataSetTable
internal void AddDataSetTable(DataSet dataSet, string dataMember)
{
if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0)
dataMember = dataSet.Tables[0].TableName;
if (string.IsNullOrEmpty(dataMember) == false)
AddDataTable(dataSet.Tables[dataMember]);
}
#endregion
#region AddDataTable
internal void AddDataTable(DataTable dt)
{
bool autogen = _Panel.AutoGenerateColumns;
ProcessChildRelations crVisibility = _Panel.ProcessChildRelations;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
_Panel, null, dt.TableName, ref autogen, ref crVisibility) == false)
{
AddDataTable(dt, autogen, crVisibility);
}
}
internal void AddDataTable(
DataTable dt, bool autogen, ProcessChildRelations crProcess)
{
if (SetDataConnection(dt) == true)
{
if (CurrencyManager != null)
{
CurrencyManager.ListChanged -= CurrencyManagerListChanged;
CurrencyManager.ListChanged += CurrencyManagerListChanged;
if (autogen == true && _Panel.IsDesignerHosted == false)
AutoGenerateDataTableColumns(dt, null);
if (_Panel.VirtualMode == false)
{
int pindex = (crProcess != ProcessChildRelations.Never) ? GetPrimaryColumnIndex(dt) : -1;
bool rowsUnresolved = (pindex >= 0 && dt.ChildRelations.Count > 0);
for (int i = 0; i < CurrencyManager.Count; i++)
{
DataRowView view = CurrencyManager.List[i] as DataRowView;
if (view != null)
{
GridRow row = GetNewRow(dt, view);
row.DataItem = view;
row.DataItemIndex = i;
row.RowsUnresolved = rowsUnresolved;
_Panel.Rows.Add(row);
}
}
if (rowsUnresolved == true)
{
_Panel.PrimaryColumnIndex = pindex;
_Panel.ShowTreeButtons = true;
_Panel.ShowTreeLines = true;
_Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand;
_Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand;
}
}
else
{
if (_Panel.IsFiltered == true)
dt.DefaultView.RowFilter = "";
}
DataView = dt.DefaultView;
UpdateSuperGridSort(false);
_Panel.SuperGrid.DoDataBindingCompleteEvent(_Panel);
}
}
}
#endregion
#region AddDefaultObject
private void AddDefaultObject(object source)
{
if (SetDataConnection(source) == true)
{
if (_Pdc != null)
{
if (_Panel.AutoGenerateColumns == true && _Panel.IsDesignerHosted == false)
AutoGenerateListColumns(null);
IList list = CurrencyManager.List;
for (int i = 0; i < list.Count; i++)
{
object o = list[i];
if (o != null)
{
GridRow row = GetNewRow(o);
row.DataItem = o;
row.DataItemIndex = i;
_Panel.Rows.Add(row);
}
}
_Panel.SuperGrid.DoDataBindingCompleteEvent(_Panel);
}
if (CurrencyManager != null)
{
CurrencyManager.ListChanged -= CurrencyManagerListChanged;
CurrencyManager.ListChanged += CurrencyManagerListChanged;
}
}
}
#endregion
#region GetPrimaryColumnIndex
private int GetPrimaryColumnIndex(DataTable dt)
{
if (dt.ChildRelations.Count > 0)
{
DataRelation dr = dt.ChildRelations[0];
if (dr.ParentColumns.Length > 0)
{
GridColumn col =
FindGridColumn(_Panel, dr.ParentColumns[0].ColumnName);
if (col != null)
return (col.ColumnIndex);
}
}
return (-1);
}
#endregion
#region AutoGenerateDataTableColumns
private void AutoGenerateDataTableColumns(DataTable dt, GetNewGridColumn callBack)
{
foreach (DataColumn dtColumn in dt.Columns)
{
if ((dtColumn.ColumnMapping & MappingType.Hidden) != MappingType.Hidden)
{
if (FindGridColumn(_Panel, dtColumn.ColumnName) == null)
{
GridColumn gcol = (callBack != null) ? callBack() : new GridColumn();
if (gcol != null)
{
gcol.DataPropertyName = dtColumn.ColumnName;
gcol.Name = dtColumn.ColumnName;
gcol.Width = 100;
gcol.DefaultNewRowCellValue = dtColumn.DefaultValue;
gcol.ReadOnly = dtColumn.ReadOnly;
if (String.IsNullOrEmpty(dtColumn.Caption) == false)
gcol.HeaderText = dtColumn.Caption;
SetColumnEditor(dtColumn.DataType, gcol);
_Panel.Columns.Add(gcol);
}
}
}
}
}
#region SetColumnEditor
private void SetColumnEditor(Type type, GridColumn col)
{
col.DataType = type;
if (type != null)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
Type type2 = Nullable.GetUnderlyingType(type);
if (type2 != null)
type = type2;
}
if (type == typeof(String) || type == typeof(SqlString))
{
col.EditorType = typeof(GridTextBoxXEditControl);
}
else if (type == typeof(Boolean) || type == typeof(SqlBoolean))
{
col.EditorType = typeof(GridCheckBoxXEditControl);
}
else if (type == typeof(DateTime) || type == typeof(SqlDateTime)
|| type == typeof(TimeSpan))
{
col.EditorType = typeof(GridDateTimeInputEditControl);
}
else if (type == typeof(Decimal) || type == typeof(SqlDecimal) ||
type == typeof(Double) || type == typeof(SqlDouble) ||
type == typeof(Single) || type == typeof(SqlSingle))
{
col.EditorType = typeof(GridDoubleInputEditControl);
}
else if (type == typeof(Int64) || type == typeof(SqlInt64))
{
col.EditorType = typeof(GridDoubleIntInputEditControl);
}
else if (type == typeof(Int16) || (type == typeof(SqlInt16) ||
type == typeof(Int32) || type == typeof(SqlInt32)))
{
col.EditorType = typeof(GridIntegerInputEditControl);
}
}
}
#endregion
#endregion
#region AutoGenerateColumns
internal void AutoGenerateColumns(GetNewGridColumn callBack)
{
if (CurrencyManager != null)
{
DataSet dataSet = _BaseDataSource as DataSet;
if (dataSet != null)
{
string dataMember = _BaseDataMember;
if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0)
dataMember = dataSet.Tables[0].TableName;
if (string.IsNullOrEmpty(dataMember) == false)
AutoGenerateDataTableColumns(dataSet.Tables[dataMember], callBack);
}
else
{
AutoGenerateListColumns(callBack);
}
}
}
#endregion
#region GetNewRow
private GridRow GetNewRow(DataTable dt, DataRowView view)
{
GridRow row = new GridRow();
for (int i = 0; i < _Panel.Columns.Count; i++)
{
GridColumn col = _Panel.Columns[i];
DataColumn dtColumn = FindDataColumn(dt, col);
object o = (dtColumn != null)
? view.Row.ItemArray[dtColumn.Ordinal] : null;
row.Cells.Add(new GridCell(o));
}
return (row);
}
#endregion
#region IsColumnDataBound
internal bool IsColumnDataBound(GridColumn col)
{
if (_Pdc != null)
{
PropertyDescriptor pd = FindPropertyDescriptor(_Pdc, col);
return (pd != null);
}
return (false);
}
#endregion
#region GetPdc
private PropertyDescriptorCollection GetPdc(object dataItem)
{
if (_Panel.EnableDiscreteBoundRows == true)
{
if (dataItem != null)
return (TypeDescriptor.GetProperties(dataItem.GetType()));
}
return (_Pdc);
}
#endregion
#region FindPropertyDescriptor
private PropertyDescriptor FindPropertyDescriptor(PropertyDescriptorCollection pdc, GridColumn col)
{
if (pdc != null)
{
foreach (PropertyDescriptor pd in pdc)
{
if (string.IsNullOrEmpty(col.DataPropertyName) == true)
{
if (pd.Name.Equals(col.Name) == true)
return (pd);
}
else
{
if (pd.Name.Equals(col.DataPropertyName) == true)
return (pd);
}
}
}
return (null);
}
#endregion
#region FindDataColumn
private DataColumn FindDataColumn(DataTable dt, GridColumn col)
{
foreach (DataColumn dtColumn in dt.Columns)
{
if (string.IsNullOrEmpty(col.DataPropertyName) == true)
{
if (dtColumn.ColumnName.Equals(col.Name) == true)
return (dtColumn);
}
else
{
if (dtColumn.ColumnName.Equals(col.DataPropertyName) == true)
return (dtColumn);
}
}
return (null);
}
#endregion
#region FindGridColumn
private GridColumn FindGridColumn(GridPanel panel, string name)
{
foreach (GridColumn col in panel.Columns)
{
if (string.IsNullOrEmpty(col.DataPropertyName) == true)
{
if (name.Equals(col.Name) == true)
return (col);
}
else
{
if (name.Equals(col.DataPropertyName) == true)
return (col);
}
}
return (null);
}
#endregion
#region SuperGridBeforeExpand
void SuperGridBeforeExpand(object sender, GridBeforeExpandEventArgs e)
{
if (e.GridPanel == _Panel)
ResolveRow(e.GridContainer);
}
#endregion
#region ResolveRow
internal void ResolveRow(GridContainer crow)
{
if (crow.RowsUnresolved == true)
{
crow.RowsUnresolved = false;
GridRow row = crow as GridRow;
if (row != null)
{
DataRowView view = row.DataItem as DataRowView;
if (view != null)
{
DataTable dt = view.DataView.Table;
StringBuilder sb = new StringBuilder();
foreach (DataRelation dr in dt.ChildRelations)
CreateNestedTablePanel(_Panel, row, dr, sb);
}
else if (_BaseDataSource is IList)
{
object o = row.DataItem;
Type type = o.GetType();
if (type != null)
{
FieldInfo[] fia = type.GetFields();
foreach (FieldInfo fi in fia)
CreateNestedListFieldPanel(_Panel, row, type, fi);
PropertyInfo[] pia = type.GetProperties();
foreach (PropertyInfo pi in pia)
CreateNestedListPropertyPanel(_Panel, row, type, pi);
}
}
}
}
}
#region CreateNestedTablePanel
private void CreateNestedTablePanel(GridPanel panel,
GridRow row, DataRelation dr, StringBuilder sb)
{
DataTable ct = dr.ChildTable;
bool autogen = true;
ProcessChildRelations crProcess = _Panel.ProcessChildRelations;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
_Panel, row, ct.TableName, ref autogen, ref crProcess) == false)
{
if (crProcess != ProcessChildRelations.Never)
{
sb.Length = 0;
for (int i = 0; i < dr.ParentColumns.Length; i++)
{
DataColumn col = dr.ParentColumns[i];
GridColumn gc = FindGridColumn(panel, col.ColumnName);
if (gc != null)
{
object val = row.Cells[gc.ColumnIndex].Value;
if (val != null)
{
string sval = val.ToString();
if (sval.Length > 0)
{
if (sb.Length > 0)
sb.Append(" AND ");
sb.Append("[" + dr.ChildColumns[i] + "]=");
if (sval.Contains("'") == true)
sval = sval.Replace("'", "''");
sb.Append("'" + sval + "'");
}
}
}
}
string t = sb.ToString();
DataView view = new
DataView(ct, t, "", DataViewRowState.CurrentRows);
if (view.Count > 0 || crProcess == ProcessChildRelations.Always)
{
GridPanel ipanel = new GridPanel();
ipanel.Name = ct.TableName;
ipanel.AutoGenerateColumns = autogen;
ipanel.ProcessChildRelations = crProcess;
ipanel.SetDataSource(panel.DataSource);
ipanel.SetDataMember(ct.TableName);
ipanel.DataRelation = dr;
ipanel.DataBinder.DataView = view;
ipanel.DataBinder.BaseDataSource = ipanel.DataSource;
ipanel.DataBinder.BaseDataMember = ipanel.DataMember;
row.Rows.Add(ipanel);
ipanel.DataBinder.AddDataTable(ct, autogen, crProcess);
}
else
{
view.Dispose();
}
}
}
}
#endregion
#region CreateNestedListFieldPanel
private void CreateNestedListFieldPanel(GridPanel _Panel,
GridRow row, Type type, FieldInfo fi)
{
bool autogen = true;
ProcessChildRelations crProcess = _Panel.ProcessChildRelations;
if (IsNestedList(fi.FieldType.Name) == true)
{
if (IsVisibleItem(type, fi) == true)
{
IList list = fi.GetValue(row.DataItem) as IList;
if (list != null)
{
GridPanel ipanel = new GridPanel();
ipanel.Name = fi.Name;
ipanel.AutoGenerateColumns = autogen;
ipanel.ProcessChildRelations = crProcess;
ipanel.NestedListScanTypes = _Panel.NestedListScanTypes;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
_Panel, row, null, ref autogen, ref crProcess) == false)
{
if (crProcess != ProcessChildRelations.Never)
{
if (list.Count > 0 || crProcess == ProcessChildRelations.Always)
{
ipanel.SetDataSource(list);
ipanel.DataBinder.BaseDataSource = ipanel.DataSource;
row.Rows.Add(ipanel);
ipanel.DataBinder.AddIList((IList)ipanel.DataSource, autogen, crProcess);
}
}
}
}
}
}
}
#endregion
#region CreateNestedListPropertyPanel
private void CreateNestedListPropertyPanel(GridPanel _Panel,
GridRow row, Type type, PropertyInfo pi)
{
bool autogen = true;
ProcessChildRelations crProcess = _Panel.ProcessChildRelations;
if (IsNestedList(pi.PropertyType.Name) == true)
{
if (IsVisibleItem(type, pi) == true)
{
IList list = pi.GetValue(row.DataItem, null) as IList;
if (list != null)
{
GridPanel ipanel = new GridPanel();
ipanel.Name = pi.Name;
ipanel.AutoGenerateColumns = autogen;
ipanel.ProcessChildRelations = crProcess;
ipanel.NestedListScanTypes = _Panel.NestedListScanTypes;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
ipanel, row, null, ref autogen, ref crProcess) == false)
{
if (crProcess != ProcessChildRelations.Never)
{
if (list.Count > 0 || crProcess == ProcessChildRelations.Always)
{
ipanel.SetDataSource(list);
ipanel.DataBinder.BaseDataSource = ipanel.DataSource;
row.Rows.Add(ipanel);
ipanel.DataBinder.AddIList((IList)ipanel.DataSource, autogen, crProcess);
}
}
}
}
}
}
}
#endregion
#endregion
#region CurrencyManagerListChanged
void CurrencyManagerListChanged(object sender, ListChangedEventArgs e)
{
if (_Panel.SuperGrid.InvokeRequired)
{
_Panel.SuperGrid.BeginInvoke(
new MethodInvoker(delegate { CurrencyManagerListChangedUIThread(sender, e); }));
}
else
{
CurrencyManagerListChangedUIThread(sender, e);
}
}
void CurrencyManagerListChangedUIThread(object sender, ListChangedEventArgs e)
{
if (IsUpdateSuspended == false && UpdateInProgress == false)
{
GridRow row = null;
try
{
UpdateInProgress = true;
CurrencyManager cm = sender as CurrencyManager;
if (cm != null && cm == _CurrencyManager)
{
IList list = cm.List;
bool updateGrouping = true;
if (e.ListChangedType == ListChangedType.ItemAdded)
{
if ((uint)e.NewIndex < CurrencyManager.Count)
{
row = AddDataGridRow(list, e.NewIndex);
if (row != null)
_Panel.SuperGrid.DoRowLoadedEvent(_Panel, row);
}
}
else
{
switch (e.ListChangedType)
{
case ListChangedType.ItemChanged:
UpdateDataGridRow(list, e.NewIndex);
updateGrouping = false;
break;
case ListChangedType.ItemDeleted:
DeleteDataGridRow(e.NewIndex);
break;
case ListChangedType.ItemMoved:
MoveDataGridRow(e.OldIndex, e.NewIndex);
break;
case ListChangedType.Reset:
_Panel.FlushActiveRow();
DataResetCount++;
if (_Panel.VirtualMode == false)
{
_Panel.Rows.Clear();
if (_Panel.ShowInsertRow == true)
_Panel.LoadInsertRow = true;
}
else
{
_Panel.VirtualRows.Clear();
Refresh();
}
UpdateSuperGridSort(true);
break;
}
_LastDataItemAdded = null;
}
if (updateGrouping == true)
UpdateGrouping();
}
}
finally
{
UpdateInProgress = false;
}
}
}
#region AddDataGridRow
private GridRow AddDataGridRow(IList list, int index)
{
GridElement selItem = _Panel.SuperGrid.ActiveElement;
if (_Panel.VirtualMode == true)
{
_Panel.VirtualRows.MaxRowIndex = index - 1;
_Panel.VirtualRowCount = CurrencyManager.Count;
_Panel.InvalidateRender();
if (_Panel.AutoSelectNewBoundRows == false)
{
if (_Panel.ActiveRow != null)
index = _Panel.ActiveRow.RowIndex;
else
index = -1;
}
if (index > _Panel.VirtualRowCount)
index = _Panel.VirtualRowCount - 1;
if (index >= 0)
SelectRow(_Panel, index);
return (null);
}
else
{
GridRow row = null;
object o = list[index];
if (o != _LastDataItemAdded)
{
row = GetNewRow(o);
row.DataItem = o;
row.DataItemIndex = index;
AddNestedLink(list, row);
UpdateRowsDataIndex(index, 1);
if (_Panel.IsGrouped == true)
{
_Panel.Rows.Insert(0, row);
}
else
{
_Panel.Rows.Insert(index, row);
_Panel.UpdateRowPosition(row);
index = row.RowIndex;
}
if (_Panel.AutoSelectNewBoundRows == true)
{
SelectRow(_Panel, index);
}
else
{
int selCount = _Panel.SelectedRowCount;
ushort selUpdateCount = _Panel.SelectionUpdateCount;
_Panel.ClearAll();
SelectLastElement(selItem);
if (selCount == 1)
_Panel.SelectionUpdateCount = selUpdateCount;
}
}
else
{
row = UpdateDataGridRow(list, index);
}
_LastDataItemAdded = o;
return (row);
}
}
#region AddNestedLink
private void AddNestedLink(IList list, GridRow row)
{
if (_BaseDataSource is DataSet)
AddDataSetLink(row);
else if (_BaseDataSource is IBindingList)
AddIListLink(row);
else if (_BaseDataSource is IList)
AddIListLink(row);
else if (_BaseDataSource is IListSource)
AddIListLink(row);
}
#region AddDataSetLink
private void AddDataSetLink(GridRow row)
{
DataRowView view = row.DataItem as DataRowView;
if (view != null)
{
DataTable dt = view.DataView.Table;
if (dt != null)
{
bool autogen = _Panel.AutoGenerateColumns;
ProcessChildRelations crVisibility = _Panel.ProcessChildRelations;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
_Panel, null, dt.TableName, ref autogen, ref crVisibility) == false)
{
AddDataTableLink(row, dt, autogen, crVisibility);
}
}
}
}
#region AddDataTableLink
private void AddDataTableLink(GridRow row,
DataTable dt, bool autogen, ProcessChildRelations crProcess)
{
int pindex = (crProcess != ProcessChildRelations.Never) ? GetPrimaryColumnIndex(dt) : -1;
row.RowsUnresolved = (pindex >= 0 && dt.ChildRelations.Count > 0);
if (row.RowsUnresolved == true)
{
_Panel.ShowTreeButtons = true;
_Panel.ShowTreeLines = true;
_Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand;
_Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand;
}
}
#endregion
#endregion
#region AddIListLink
private void AddIListLink(GridRow row)
{
bool autogen = _Panel.AutoGenerateColumns;
ProcessChildRelations crVisibility = _Panel.ProcessChildRelations;
if (_Panel.SuperGrid.DoDataBindingStartEvent(
_Panel, null, null, ref autogen, ref crVisibility) == false)
{
AddIListLink(row, autogen, crVisibility);
}
}
#region AddIListLink
private void AddIListLink(GridRow row, bool autogen, ProcessChildRelations crProcess)
{
if (crProcess != ProcessChildRelations.Never)
{
bool rowsUnresolved = false;
if (row.DataItem != null)
{
Type type = row.DataItem.GetType();
if (type != null)
{
if (CheckNestedFields(row, type, crProcess) == false)
CheckNestedProperties(row, type, crProcess);
}
rowsUnresolved |= row.RowsUnresolved;
}
if (rowsUnresolved == true)
{
_Panel.ShowTreeButtons = true;
_Panel.ShowTreeLines = true;
_Panel.SuperGrid.BeforeExpand -= SuperGridBeforeExpand;
_Panel.SuperGrid.BeforeExpand += SuperGridBeforeExpand;
}
}
}
#endregion
#endregion
#endregion
#endregion
#region DeleteDataGridRow
private void DeleteDataGridRow(int dataItemIndex)
{
GridRow row = FindDataGridRowIndex(dataItemIndex);
if (row != null)
{
if (row.DataItem != null)
{
GridElement selItem = _Panel.SuperGrid.ActiveElement;
UpdateRowsDataIndex(row.DataItemIndex, -1);
row.DataItem = null;
row.DataItemIndex = -1;
int index = row.RowIndex;
if (_Panel.VirtualMode == true)
{
_Panel.VirtualRows.MaxRowIndex = index - 1;
_Panel.VirtualRowCount--;
_Panel.InvalidateRender();
if (_Panel.AutoSelectDeleteBoundRows == false)
{
if (_Panel.ActiveRow != null)
index = _Panel.ActiveRow.RowIndex;
else
index = -1;
}
if (index > _Panel.VirtualRowCount)
index = _Panel.VirtualRowCount - 1;
if (index >= 0)
SelectRow(_Panel, index);
}
else
{
GridContainer cont = (GridContainer) row.Parent;
cont.Rows.RemoveAt(index);
if (_Panel.AutoSelectDeleteBoundRows == true)
{
if (index >= cont.Rows.Count)
index--;
if ((uint)index < cont.Rows.Count)
{
SelectRow(cont, index);
row = cont.Rows[index] as GridRow;
if (row != null)
CurrencyManager.Position = row.DataItemIndex;
}
}
else
{
SelectLastElement(selItem);
}
}
}
}
}
#endregion
#region SelectLastElement
private void SelectLastElement(GridElement selItem)
{
_Panel.SuperGrid.NeedToUpdateIndicees = true;
_Panel.UpdateIndicees(_Panel, _Panel.Rows, true);
if (selItem is GridCell)
_Panel.SetSelected((GridCell)selItem, true);
else if (selItem is GridRow)
_Panel.SetSelected((GridRow)selItem, true);
}
#endregion
#region MoveDataGridRow
private void MoveDataGridRow(int oldDataIndex, int newDataIndex)
{
if (_Panel.VirtualMode == true)
{
_Panel.VirtualRows.Clear();
}
else
{
GridRow oldRow = FindDataGridRowIndex(oldDataIndex);
GridRow newRow = FindDataGridRowIndex(newDataIndex);
if (oldRow != null && newRow != null)
{
GridContainer cont = (GridContainer) oldRow.Parent;
int newIndex = newRow.RowIndex;
if (oldRow.RowIndex < newRow.RowIndex)
{
for (int i = oldRow.RowIndex; i < newRow.RowIndex; i++)
{
cont.Rows[i] = cont.Rows[i + 1];
((GridRow) cont.Rows[i]).DataItemIndex--;
((GridRow) cont.Rows[i]).RowIndex--;
}
}
else
{
for (int i = oldRow.RowIndex; i > newRow.RowIndex; i--)
{
cont.Rows[i] = cont.Rows[i - 1];
((GridRow) cont.Rows[i]).DataItemIndex++;
((GridRow) cont.Rows[i]).RowIndex++;
}
}
cont.Rows[newIndex] = oldRow;
newRow.RowIndex = newIndex;
newRow.DataItemIndex = newDataIndex;
}
}
}
#endregion
#region UpdateDataGridRow
private GridRow UpdateDataGridRow(IList list, int dataIndex)
{
GridRow row = FindDataGridRowIndex(dataIndex);
if (row != null)
UpdateListRow(row, list[dataIndex]);
return (row);
}
#endregion
#region UpdateListRow
private void UpdateListRow(GridRow row, object o)
{
PropertyDescriptorCollection pdc = GetPdc(o);
foreach (GridColumn col in _Panel.Columns)
{
if (col.ColumnIndex < row.Cells.Count)
{
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
if (pd != null)
{
object value = pd.GetValue(o);
object value2 = row.Cells[col.ColumnIndex].ValueEx;
row.Cells[col.ColumnIndex].ValueEx = value;
if (col.Visible == true)
row.Cells[col.ColumnIndex].InvalidateRender();
int cval = -2;
if (_Panel.GroupColumns.Contains(col) == true)
{
if ((cval = CompareVal.CompareTo(value, value2)) != 0)
_Panel.NeedsGrouped = true;
}
if (_Panel.KeepRowsSorted == true)
{
if (col.IsSortColumn == true)
{
if (cval == -2)
cval = CompareVal.CompareTo(value, value2);
if (cval != 0)
{
if (row == _Panel.ActiveRow)
row.RowNeedsSorted = true;
else
_Panel.NeedsSorted = true;
}
}
}
}
}
}
row.DataItem = o;
DataRowView drv = o as DataRowView;
if (drv != null)
{
if (drv.Row.RowState == DataRowState.Unchanged)
row.RowDirty = false;
}
_Panel.NeedsFilterScan = true;
}
#endregion
#region UpdateGrouping
private void UpdateGrouping()
{
if (_Panel.GroupColumns.Count > 0)
{
_Panel.NeedsGrouped = true;
_Panel.InvalidateLayout();
}
}
#endregion
#endregion
#region FindDataGridRowIndex
private GridRow FindDataGridRowIndex(int dataItemIndex)
{
if (_Panel.ActiveRow != null)
{
GridRow row = _Panel.ActiveRow as GridRow;
if (row != null &&
row.IsTempInsertRow == false && row.IsInsertRow == false)
{
if (row.DataItemIndex == dataItemIndex)
return (row);
}
}
if (_Panel.VirtualMode == true)
return (FindDataGridVirtualRowIndex(dataItemIndex));
return (FindDataGridRealRowIndex(_Panel.Rows, dataItemIndex));
}
private GridRow FindDataGridVirtualRowIndex(int dataItemIndex)
{
if ((uint)dataItemIndex < _Panel.VirtualRowCount)
return (_Panel.VirtualRows[dataItemIndex]);
return (null);
}
private GridRow FindDataGridRealRowIndex(
IEnumerable<GridElement> items, int dataItemIndex)
{
foreach (GridElement item in items)
{
if (item is GridRow)
{
GridRow row = item as GridRow;
if (row.IsTempInsertRow == false && row.IsInsertRow == false)
{
if (row.DataItemIndex == dataItemIndex)
return (row);
}
}
else if (item is GridGroup)
{
GridRow row = FindDataGridRealRowIndex(((GridGroup)item).Rows, dataItemIndex);
if (row != null)
return (row);
}
}
return (null);
}
#endregion
#region FindDataGridRow
private GridRow FindDataGridRow(int dataItemIndex)
{
if (_Panel.ActiveRow != null)
{
GridRow row = _Panel.ActiveRow as GridRow;
if (row != null &&
row.IsTempInsertRow == false && row.IsInsertRow == false)
{
if (row.DataItem == CurrencyManager.List[dataItemIndex])
return (row);
}
}
if (_Panel.VirtualMode == true)
return (FindDataGridVirtualRowIndex(dataItemIndex));
return (FindDataGridRealRow(_Panel.Rows, dataItemIndex));
}
#region FindDataGridRealRow
private GridRow FindDataGridRealRow(IEnumerable<GridElement> items, int dataItemIndex)
{
foreach (GridElement item in items)
{
if (item is GridRow)
{
GridRow row = item as GridRow;
if (row.IsTempInsertRow == false && row.IsInsertRow == false)
{
if (row.DataItem == CurrencyManager.List[dataItemIndex])
return (row);
}
}
else if (item is GridGroup)
{
GridRow row = FindDataGridRealRowIndex(((GridGroup)item).Rows, dataItemIndex);
if (row != null)
return (row);
}
}
return (null);
}
#endregion
#endregion
#region SelectRow
private void SelectRow(GridContainer cont, int index)
{
_Panel.LatentActiveContainer = cont;
_Panel.LatentActiveRowIndex = index;
}
#endregion
#region UpdateRowsDataIndex
private void UpdateRowsDataIndex(int index, int n)
{
if (_Panel.VirtualMode == false)
UpdateRowsDataIndexEx(_Panel.Rows, index, n);
}
private void UpdateRowsDataIndexEx(
IEnumerable<GridElement> items, int index, int n)
{
foreach (GridContainer item in items)
{
GridRow row = item as GridRow;
if (row != null)
{
if (row.DataItemIndex >= index)
row.DataItemIndex += n;
}
if (item.Rows.Count > 0)
UpdateRowsDataIndexEx(item.Rows, index, n);
}
}
#endregion
#region RemoveRow
internal void RemoveRow(GridRow row)
{
if (CurrencyManager != null)
{
UpdateInProgress = true;
UpdatePosInProgress = true;
try
{
int index = row.DataItemIndex;
CurrencyManager.RemoveAt(index);
}
finally
{
UpdateInProgress = false;
UpdatePosInProgress = false;
_Panel.UpdateRowCount();
}
if (row.DataItem != null)
UpdateRowsDataIndex(row.DataItemIndex, -1);
}
}
#endregion
#region InsertRow
internal void InsertRow(int index, GridRow row)
{
if (CurrencyManager != null && _Pdc != null)
{
if (index > CurrencyManager.Count)
index = CurrencyManager.Count;
UpdateInProgress = true;
UpdatePosInProgress = true;
object dataSource = _Panel.DataSource;
string dataMember = _Panel.DataMember;
try
{
while (dataSource is BindingSource)
{
BindingSource bs = (BindingSource)dataSource;
dataSource = bs.DataSource;
if (dataMember == null)
dataMember = bs.DataMember;
}
if (dataSource is DataSet)
InsertDataSetRow((DataSet)dataSource, dataMember, index, row);
else if (dataSource is DataTable)
InsertDataTableRow((DataTable)dataSource, index, row);
else
InsertListRow(index, row);
}
finally
{
UpdateInProgress = false;
UpdatePosInProgress = false;
}
}
}
#region InsertDataSetRow
private void InsertDataSetRow(DataSet dataSet,
string dataMember, int index, GridRow row)
{
DataTable table = GetDataTable(dataSet, dataMember);
if (table != null)
InsertDataTableRow(table, index, row);
}
#endregion
#region InsertDataTableRow
private void InsertDataTableRow(DataTable table, int index, GridRow row)
{
DataRow drow = _TempDataRow ?? table.NewRow();
_TempDataRow = null;
for (int i = 0; i < Pdc.Count; i++)
{
PropertyDescriptor pd = Pdc[i];
GridColumn col = FindGridColumn(_Panel, pd.Name);
if (col != null)
{
object value = (col.ColumnIndex < row.Cells.Count) ?
row.Cells[col.ColumnIndex].ValueEx ?? DBNull.Value : DBNull.Value;
drow[i] = value;
}
}
UpdateRowsDataIndex(index, 1);
row.DataItem = drow;
row.DataItemIndex = index;
if (index < CurrencyManager.Count)
{
DataRowView drv = CurrencyManager.List[index] as DataRowView;
if (drv != null)
{
int idx = table.Rows.IndexOf(drv.Row);
if (idx >= 0)
index = idx;
}
table.Rows.InsertAt(drow, index);
}
else
{
table.Rows.Add(drow);
}
}
#endregion
#region InsertListRow
private void InsertListRow(int index, GridRow row)
{
if (Pdc.Count > 0)
{
Type type = Pdc[0].ComponentType;
object item;
if (type == typeof(DataRowView))
item = ((DataView)_BaseDataSource).AddNew();
else
item = Activator.CreateInstance(type);
for (int i = 0; i < Pdc.Count; i++)
{
PropertyDescriptor pd = Pdc[i];
GridColumn col = FindGridColumn(_Panel, pd.Name);
if (col != null)
{
object o = row.Cells[col.ColumnIndex].ValueEx;
if (o != null && o is DBNull == false)
pd.SetValue(item, o);
}
}
UpdateRowsDataIndex(index, 1);
row.DataItem = item;
row.DataItemIndex = index;
_UpdatePosInProgress = true;
if (type != typeof(DataRowView))
{
if (CurrencyManager != null)
CurrencyManager.List.Insert(index, item);
}
else
{
DataRowView dv = (DataRowView)item;
dv.EndEdit();
}
_UpdatePosInProgress = false;
}
}
#endregion
#endregion
#region GetDefaultValues
internal void GetDefaultValues(GridRow row)
{
if (CurrencyManager != null)
{
object dataSource = _Panel.DataSource;
string dataMember = _Panel.DataMember;
while (dataSource is BindingSource)
{
BindingSource bs = (BindingSource) dataSource;
dataSource = bs.DataSource;
if (dataMember == null)
dataMember = bs.DataMember;
}
if (dataSource is DataSet)
GetDataSetDefaultValues((DataSet) dataSource, dataMember, row);
else if (dataSource is DataTable)
GetTableDefaultValues((DataTable)dataSource, row);
}
GridColumnCollection columns = _Panel.Columns;
for (int i = 0; i < columns.Count; i++)
{
if (columns[i].DefaultNewRowCellValue != null)
row.Cells[i].ValueEx = columns[i].DefaultNewRowCellValue;
}
if (_Panel.SuperGrid != null)
_Panel.SuperGrid.DoRowSetDefaultValuesEvent(_Panel, row, NewRowContext.RowInit);
}
#region GetDataSetDefaultValues
private void GetDataSetDefaultValues
(DataSet dataSet, string dataMember, GridRow row)
{
DataTable table = GetDataTable(dataSet, dataMember);
if (table != null)
GetTableDefaultValues(table, row);
}
#endregion
#region GetTableDefaultValues
private void GetTableDefaultValues(DataTable table, GridRow row)
{
_TempDataRow = table.NewRow();
UpdateForeignKey(table, _TempDataRow);
for (int i = 0; i < Pdc.Count; i++)
{
GridColumn col = FindGridColumn(_Panel, Pdc[i].Name);
if (col != null)
{
if (col.ColumnIndex < row.Cells.Count)
row.Cells[col.ColumnIndex].ValueEx = _TempDataRow[i];
}
}
}
#region UpdateForeignKey
private void UpdateForeignKey(DataTable table, DataRow drow)
{
DataRelation dataRel = _Panel.DataRelation;
if (dataRel != null &&
dataRel.ParentColumns != null && dataRel.ChildColumns != null)
{
BindingSource bs = _Panel.DataSource as BindingSource;
if (bs != null)
{
bs = bs.DataSource as BindingSource;
if (bs != null && bs.Current != null)
UpdateDataRowForeignKey(dataRel, drow, bs.Current);
}
else
{
GridRow row = _Panel.Parent as GridRow;
if (row != null)
UpdateDataRowForeignKey(dataRel, drow, row.DataItem);
}
}
}
#region UpdateDataRowForeignKey
private void UpdateDataRowForeignKey(
DataRelation dataRel, DataRow drow, object item)
{
DataRowView drv = item as DataRowView;
if (drv != null)
{
for (int i = 0; i < dataRel.ParentColumns.Length; i++)
{
if (i < dataRel.ChildColumns.Length)
{
drow[dataRel.ChildColumns[i].ColumnName] =
drv[dataRel.ParentColumns[i].ColumnName];
}
}
}
}
#endregion
#endregion
#endregion
#endregion
#region GetDataTable
private DataTable GetDataTable(DataSet dataSet, string dataMember)
{
if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0)
dataMember = dataSet.Tables[0].TableName;
if (_Panel.DataRelation == null)
_Panel.DataRelation = dataSet.Relations[dataMember];
DataTable table = (_Panel.DataRelation != null)
? _Panel.DataRelation.ChildTable : dataSet.Tables[dataMember];
return (table);
}
#endregion
#region ReloadRow
internal void ReloadRow(GridRow row)
{
if (CurrencyManager != null && _Pdc != null)
{
if ((uint)row.RowIndex < CurrencyManager.List.Count)
{
PropertyDescriptorCollection pdc = GetPdc(row.DataItem);
foreach (GridCell cell in row.Cells)
{
GridColumn col = _Panel.Columns[cell.ColumnIndex];
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
if (pd != null)
cell.ValueEx = pd.GetValue(row.DataItem);
}
}
}
}
#endregion
#region UpdateSuperGridSort
private void UpdateSuperGridSort(bool reset)
{
if (reset == true ||
(_Panel.SortColumns == null || _Panel.SortColumns.Count == 0))
{
if (CurrencyManager != null)
{
if (_BaseDataSource is DataView)
{
SetSuperGridDataSetSort(((DataView)_BaseDataSource).Sort);
}
else if (_BaseDataSource is IBindingList)
{
SetSuperGridListSort((IBindingList)_BaseDataSource);
}
else if (_BaseDataSource is IListSource)
{
IList list = ((IListSource)_BaseDataSource).GetList();
if (list is IBindingList)
SetSuperGridListSort((IBindingList)list);
}
}
}
}
#region SetSuperGridDataSetSort
private void SetSuperGridDataSetSort(string sort)
{
_Panel.ClearSort();
if (string.IsNullOrEmpty(sort) == false)
{
const string cref = @"((\[(?<name>\w+)\])|(?<name>\w+))\s*(?<order>ASC|DESC)*";
Regex p = new Regex(cref);
MatchCollection mc = p.Matches(sort);
foreach (Match ma in mc)
{
GridColumn col = FindGridColumn(_Panel, ma.Groups["name"].Value);
if (col != null)
{
SortDirection dir = SortDirection.Ascending;
Group grp = ma.Groups["order"];
if (grp != null)
{
dir = grp.Value.Equals("DESC")
? SortDirection.Descending : SortDirection.Ascending;
}
_Panel.AddSort(col, dir);
}
}
_Panel.SuperGrid.DoRowsSortedEvent(_Panel);
}
_Panel.NeedsSorted = false;
}
#endregion
#region SetSuperGridListSort
private void SetSuperGridListSort(IBindingList list)
{
_Panel.ClearSort();
if (list.SupportsSorting == true && list.IsSorted == true)
{
if (list.SortProperty != null)
{
string name = list.SortProperty.Name;
GridColumn col = FindGridColumn(_Panel, name);
if (col != null)
{
SortDirection dir = (list.SortDirection == ListSortDirection.Ascending)
? SortDirection.Ascending
: SortDirection.Descending;
_Panel.AddSort(col, dir);
}
_Panel.SuperGrid.DoRowsSortedEvent(_Panel);
}
}
_Panel.NeedsSorted = false;
}
#endregion
#endregion
#region UpdateDataSourceSort
internal void UpdateDataSourceSort()
{
if (CurrencyManager != null)
{
if (CurrencyManager.List.Count > 0)
{
DataRowView drv = CurrencyManager.List[0] as DataRowView;
if (drv != null)
{
string sort = GetSortString(drv);
drv.DataView.Sort = sort;
}
else if (_BaseDataSource is IBindingList)
UpdateListSort((IBindingList)_BaseDataSource);
else if (_BaseDataSource is IListSource)
{
IList list = ((IListSource)_BaseDataSource).GetList();
if (list is IBindingList)
UpdateListSort((IBindingList)list);
}
}
if (_Panel.VirtualMode == true)
_Panel.VirtualRows.Clear();
}
}
#endregion
#region UpdateListSort
private void UpdateListSort(IBindingList iBindingList)
{
if (iBindingList.SupportsSorting == true)
{
List<GridColumn> sortColumns = _Panel.SortColumns;
if (sortColumns != null && sortColumns.Count > 0)
{
IBindingListView blv = iBindingList as IBindingListView;
if (blv != null && blv.SupportsAdvancedSorting == true)
{
PropertyDescriptorCollection pdc = GetPdc(null);
ListSortDescription[] lsd = new ListSortDescription[sortColumns.Count];
for (int i = 0; i < sortColumns.Count; i++)
{
GridColumn col = sortColumns[i];
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
ListSortDirection dir = (col.SortDirection == SortDirection.Ascending)
? ListSortDirection.Ascending
: ListSortDirection.Descending;
lsd[i] = new ListSortDescription(pd, dir);
}
blv.ApplySort(new ListSortDescriptionCollection(lsd));
}
else
{
GridColumn col = sortColumns[0];
PropertyDescriptorCollection pdc = GetPdc(null);
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
if (pd != null)
{
ListSortDirection dir = (col.SortDirection == SortDirection.Ascending)
? ListSortDirection.Ascending
: ListSortDirection.Descending;
iBindingList.ApplySort(pd, dir);
}
}
}
else if (iBindingList.IsSorted == true)
{
iBindingList.RemoveSort();
}
}
}
#endregion
#region GetSortString
private string GetSortString(DataRowView drv)
{
List<GridColumn> sortColumns = _Panel.SortColumns;
if (sortColumns != null && sortColumns.Count > 0)
{
StringBuilder sb = new StringBuilder();
foreach (GridColumn column in sortColumns)
GetColumnSort(drv, column, sb);
if (sb.Length > 0)
sb.Length--;
return (sb.ToString());
}
return (null);
}
#endregion
#region GetColumnSort
private void GetColumnSort(
DataRowView drv, GridColumn column, StringBuilder sb)
{
DataColumn dc = FindDataColumn(drv.DataView.Table, column);
if (dc != null)
{
sb.Append("[");
sb.Append(dc.ColumnName);
sb.Append("]");
sb.Append(column.SortDirection == SortDirection.Ascending ? " ASC," : " DESC,");
}
}
#endregion
#region FlushRow
internal bool FlushRow()
{
if (CurrencyManager != null)
{
while (true)
{
_UpdateInProgress = true;
_UpdatePosInProgress = true;
try
{
CurrencyManager.EndCurrentEdit();
break;
}
catch (Exception exp)
{
GridRow crow = null;
if ((uint) CurrencyManager.Position < _Panel.Rows.Count)
{
crow = _Panel.Rows[CurrencyManager.Position] as GridRow;
if (crow != null)
ReloadRow(crow);
}
bool retry = false;
bool throwException = false;
if (_Panel.SuperGrid.HasDataErrorHandler == true)
{
object value = crow;
if (_Panel.SuperGrid.DoDataErrorEvent(_Panel, null, exp,
DataContext.RowFlush, ref value,
ref throwException, ref retry) == true)
{
return (false);
}
}
if (throwException == true)
throw;
if (retry == false)
return (false);
}
finally
{
_UpdateInProgress = false;
_UpdatePosInProgress = false;
}
}
}
return (true);
}
#endregion
#region SuperGridLoadVirtualRow
void SuperGridLoadVirtualRow(object sender, GridVirtualRowEventArgs e)
{
if (CurrencyManager != null && _Pdc != null)
{
GridRow row = e.GridRow;
GridRow vrow = _Panel.VirtualTempInsertRow;
int index = e.Index;
if (vrow != null)
{
if (index == vrow.RowIndex)
{
for (int i = 0; i < _Panel.Columns.Count; i++)
row.Cells[i].ValueEx = vrow.Cells[i].Value;
row.RowNeedsSorted = true;
row.RowNeedsStored = true;
row.IsTempInsertRow = vrow.IsTempInsertRow;
return;
}
if (index > vrow.RowIndex)
index--;
}
if (index == _Panel.VirtualRowCount)
{
if (_Panel.ShowInsertRow == true)
{
vrow = _Panel.VirtualInsertRow;
if (vrow != null)
{
for (int i = 0; i < _Panel.Columns.Count; i++)
row.Cells[i].ValueEx = vrow.Cells[i].Value;
row.RowNeedsSorted = true;
row.RowNeedsStored = true;
row.IsTempInsertRow = vrow.IsTempInsertRow;
return;
}
}
}
if ((uint)index < CurrencyManager.List.Count)
{
row.DataItem = CurrencyManager.List[index];
row.DataItemIndex = index;
PropertyDescriptorCollection pdc = GetPdc(row.DataItem);
foreach (GridColumn col in _Panel.Columns)
{
PropertyDescriptor pd = FindPropertyDescriptor(pdc, col);
if (pd != null)
row.Cells[col.ColumnIndex].ValueEx = pd.GetValue(row.DataItem);
}
}
}
}
#endregion
#region Filter management
#region UpdateFilter
private bool _UpdatingFilter;
internal void UpdateFilter()
{
if (CurrencyManager != null)
{
DataTable dt = null;
if (_BaseDataSource is DataSet)
{
DataSet dataSet = _BaseDataSource as DataSet;
string dataMember = _BaseDataMember;
if (string.IsNullOrEmpty(dataMember) && dataSet.Tables.Count > 0)
dataMember = dataSet.Tables[0].TableName;
if (string.IsNullOrEmpty(dataMember) == false)
dt = dataSet.Tables[dataMember];
}
else if (_BaseDataSource is DataTable)
{
dt = _BaseDataSource as DataTable;
}
if (dt != null)
{
_UpdatingFilter = true;
try
{
dt.DefaultView.RowFilter = GetDataViewRowFilter();
}
catch (Exception exp)
{
MessageBoxEx.Show(exp.Message);
}
finally
{
Refresh();
_UpdatingFilter = false;
}
}
}
}
#endregion
#region GetDataViewRowFilter
private string GetDataViewRowFilter()
{
StringBuilder sb = new StringBuilder();
if (String.IsNullOrEmpty(_Panel.FilterExpr) == false)
{
sb.Append("(");
sb.Append(_Panel.FilterExpr);
sb.Append(") && ");
}
foreach (GridColumn col in _Panel.Columns)
{
if (String.IsNullOrEmpty(col.FilterExpr) == false)
{
sb.Append("(");
sb.Append(col.FilterExpr);
sb.Append(") and ");
}
}
if (sb.Length > 0)
sb.Length -= 4;
string s = sb.ToString();
return (s);
}
#endregion
#endregion
#region Begin/EndUpdate
internal void BeginUpdate()
{
_BeginUpdateCount++;
}
internal void EndUpdate()
{
if (_BeginUpdateCount > 0)
{
--_BeginUpdateCount;
if (_BeginUpdateCount == 0)
Refresh();
}
}
#endregion
#region Refresh
private void Refresh()
{
if (CurrencyManager != null)
{
CurrencyManager.Refresh();
if (_Panel.VirtualMode == true)
_Panel.VirtualRowCount = _CurrencyManager.Count;
}
_Panel.UpdateRowCount();
}
#endregion
#region Dispose
/// <summary>
/// Data Binder Dispose
/// </summary>
public void Dispose()
{
Clear();
}
#endregion
}
}