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 { /// /// DataBinding helper class /// 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 /// /// DataBinding /// /// 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 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 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 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 = @"((\[(?\w+)\])|(?\w+))\s*(?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 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 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 /// /// Data Binder Dispose /// public void Dispose() { Clear(); } #endregion } }