3204 lines
95 KiB
C#
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
|
|
}
|
|
}
|