import {
DependencyObject,
INotifyPropertyChanged,
IValueConverter,
} from '../../basecomponentmodel';
import { Control } from '../../basecomponentmodel/Control';
import { Dependency } from '../../basecomponentmodel/Dependency';
import { DependencyProperty } from '../../basecomponentmodel/DependencyProperty';
import { DependencyPropertyChangedEventArgs } from '../../basecomponentmodel/DependencyPropertyChangedEventArgs';
import { RuntimeStyleInfo } from '../../basecomponentmodel/RuntimeStyleInfo';
import {
IPagedCollectionView,
iuAny,
iuFirstOrDefault,
ObservableCollection,
SimpleList,
} from '../../baseframework/collections';
import { ReflectionHelper } from '../../baseframework/ReflectionSupport';
import { Debugger } from '../../diagnostics/Debugger';
import { AngularComponentId } from '../../helpers/AngularComponentId';
import { transformStyles } from '../../utils/StyleFunctions';
import { SubscriptionEvent } from '../../utils/SubscriptionEvent';
import { XamSelectionMode } from '../enums/SelectionMode';
import { SortDirection } from '../enums/SortDirection';
import { RoutedEventArgs } from '../events/RoutedEventArgs';
import { ActiveCellChangingEventArgs } from './ActiveCellChangingEventArgs';
import { CancellableEventArgs } from './CancellableEventArgs';
import { CellAlignment } from './CellAlignment';
import { CellBase } from './CellBase';
import { ChildBandCell } from './ChildBandCell';
import { ColumnLayout } from './ColumnLayout';
import { ContentControlModel } from './ContentControlModel';
import { ColumnWidth } from './DataGridLengthModel';
import { FilterRow } from './FilterRow';
import { InvokeAction } from './InvokeAction';
import { RowBase } from './RowBase';
import { RowCollection } from './RowCollection';
import { RowsManager } from './RowsManager';
import { ThicknessModel } from './ThicknessModel';
import {
XamGridColumnModel,
XamGridGroupColumnModel,
} from './XamGridColumnModel';
import { XamGridRow } from './XamGridRow';
import { XamGridRowsManager } from './XamGridRowsManager';
export enum RowHoverType {
Cell,
Row,
None,
}
export type XamGridColumnType = 'int' | 'decimal' | 'int?' | 'Nullable<int>';
export class XamGridModel extends Control {
gridComponentInstance: any = null;
PreventClearActiveCell = false;
static SelectedRowProperty = new DependencyProperty(
'SelectedRow',
null,
null
);
public static ActiveItemProperty: DependencyProperty = new DependencyProperty(
'ActiveItem',
null,
null
);
public static AutoGenerateColumnsProperty: DependencyProperty =
new DependencyProperty('AutoGenerateColumns', true, null);
public static CellControlGenerationModeProperty: DependencyProperty =
new DependencyProperty('CellControlGenerationMode', null, null);
public static CellStyleProperty: DependencyProperty = new DependencyProperty(
'CellStyle',
null,
null
);
public static ChildBandHeaderHeightProperty: DependencyProperty =
new DependencyProperty('ChildBandHeaderHeight', null, null);
public static ChildBandHeaderStyleProperty: DependencyProperty =
new DependencyProperty('ChildBandHeaderStyle', null, null);
public static ColumnLayoutHeaderVisibilityProperty: DependencyProperty =
new DependencyProperty('ColumnLayoutHeaderVisibility', null, null);
public static ColumnsFooterTemplateProperty: DependencyProperty =
new DependencyProperty('ColumnsFooterTemplate', null, null);
public static ColumnWidthProperty: DependencyProperty =
new DependencyProperty('ColumnWidth', ColumnWidth.InitialAuto, null);
public static DeleteKeyActionProperty: DependencyProperty =
new DependencyProperty('DeleteKeyAction', null, null);
public static FixedRowSeparatorStyleProperty: DependencyProperty =
new DependencyProperty('FixedRowSeparatorStyle', null, null);
public static FooterRowHeightProperty: DependencyProperty =
new DependencyProperty('FooterRowHeight', null, null);
public static FooterStyleProperty: DependencyProperty =
new DependencyProperty('FooterStyle', null, null);
public static FooterVisibilityProperty: DependencyProperty =
new DependencyProperty('FooterVisibility', false, null);
public static HeaderRowHeightProperty: DependencyProperty =
new DependencyProperty('HeaderRowHeight', null, null);
public static HeaderStyleProperty: DependencyProperty =
new DependencyProperty(
'HeaderStyle',
null,
XamGridModel.TransformStyleCallback
);
public static HeaderTemplateProperty: DependencyProperty =
new DependencyProperty('HeaderTemplate', null, null);
public static HeaderTextHorizontalAlignmentProperty: DependencyProperty =
new DependencyProperty('HeaderTextHorizontalAlignment', null, null);
public static HeaderTextVerticalAlignmentProperty: DependencyProperty =
new DependencyProperty('HeaderTextVerticalAlignment', null, null);
public static HeaderVisibilityProperty: DependencyProperty =
new DependencyProperty('HeaderVisibility', null, null);
public static IndentationProperty: DependencyProperty =
new DependencyProperty('Indentation', null, null);
public static IsAlternateRowsEnabledProperty: DependencyProperty =
new DependencyProperty('IsAlternateRowsEnabled', false, null);
public static IsTouchSupportEnabledProperty: DependencyProperty =
new DependencyProperty('IsTouchSupportEnabled', null, null);
public static ItemsSourceProperty: DependencyProperty =
new DependencyProperty(
'ItemsSource',
null,
XamGridModel.itemsSourceCallback
);
public static KeyboardNavigationProperty: DependencyProperty =
new DependencyProperty('KeyboardNavigation', null, null);
public static MaxDepthProperty: DependencyProperty = new DependencyProperty(
'MaxDepth',
null,
null
);
public static MinimumRowHeightProperty: DependencyProperty =
new DependencyProperty('MinimumRowHeight', null, null);
public static RowHeightProperty: DependencyProperty = new DependencyProperty(
'RowHeight',
null,
null
);
public static RowHoverProperty: DependencyProperty = new DependencyProperty(
'RowHover',
RowHoverType.Cell,
null
);
private readonly _rowsManager: XamGridRowsManager;
public CurrentEditCell: XamGridCell;
public CurrentEditRow: XamGridRow;
virtualHeight: string | null = '100%';
private _activeCell: CellBase;
contextActiveCell: () => void;
private _selectionSettings: SelectionSettings;
public get RowsManager(): XamGridRowsManager {
return this._rowsManager;
}
private static itemsSourceCallback(
sender: DependencyObject,
args: DependencyPropertyChangedEventArgs
) {
if (sender instanceof XamGridModel) {
sender.ItemsSourceAsPagedCollection = null;
if (
args.NewValue &&
ReflectionHelper.isInterfaceIsSupported(
args.NewValue,
'System.ComponentModel.IPagedCollectionView'
)
) {
sender.ItemsSourceAsPagedCollection = args.NewValue;
}
sender.ApplyItemSource(args.NewValue as Iterable<any>);
sender.change.fire(['ItemsSourceChanged', args]);
}
}
ApplyItemSource(itemSource: Iterable<any>) {
if (this._rowsManager.ItemsSource !== itemSource) {
this._rowsManager.ItemsSource = itemSource;
this.SortingSettings.SortedColumns?.clear();
}
}
constructor() {
super();
this._rowsManager = new XamGridRowsManager(this);
}
public NotifyDataUpdate(): void {
this.adjustColumnTypesBasedOnNewData();
this.change.fire(['DataUpdate']);
}
public adjustColumnTypesBasedOnNewData(): void {
if (
!this.dataColumnInfoAdjusted &&
this.ItemsSource &&
this.Columns.count > 0 &&
this.ItemsSource[Symbol.iterator]
) {
const firstRow = iuFirstOrDefault(this.ItemsSource);
if (
firstRow &&
typeof firstRow === 'object' &&
firstRow.constructor !== Object
) {
const typeInfo = ReflectionHelper.getTypeInfo(firstRow);
for (const textColumn of this.Columns) {
if (textColumn.Key in firstRow) {
const propInfo = typeInfo.getProperty(textColumn.Key);
if (propInfo.propertyType?.JSType === Date) {
textColumn.DataType = 'date';
}
}
}
this.dataColumnInfoAdjusted = true;
}
}
}
public AngularComponentId = AngularComponentId.xamGrid;
Rendered = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
Loaded = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
Unloaded = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
CellSelectionChanged = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
RowSelectionChanged = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
RowsCollectionChanged = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
ColumnSelectionChanged = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
ColumnSorted = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
ColumnSorting = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
ColumnFiltered = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
ColumnResized = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
ColumnResizing = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
ColumnFixedStateChanged = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
CellClicked = new SubscriptionEvent<
(s: XamGridModel, e: CellClickedEventArgs) => void
>();
CellControlAttached = new SubscriptionEvent<
(s: XamGridModel, e: CellControlAttachedEventArgs) => void
>();
AfterCellControlAttached = new SubscriptionEvent<
(s: XamGridModel, e: CellControlAttachedEventArgs) => void
>();
CellDoubleClicked = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
KeyDown = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
ActiveCellChanged = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
ActiveCellChanging = new SubscriptionEvent<
(s: XamGridModel, e: any) => void
>();
CellEnteredEditMode = new SubscriptionEvent<
(s: XamGridModel, e: EditingCellEventArgs) => void
>();
SelectedRowsCollectionChanged: SubscriptionEvent<any> =
new SubscriptionEvent<any>();
CellExitingEditMode = new SubscriptionEvent<
(s: XamGridModel, e: ExitEditingCellEventArgs) => void
>();
CellExitedEditMode = new SubscriptionEvent<
(s: XamGridModel, e: CellExitedEditingEventArgs) => void
>();
CellEnteringEditMode = new SubscriptionEvent<
(s: XamGridModel, e: BeginEditingCellEventArgs) => void
>();
CellEditing = new SubscriptionEvent<
(s: XamGridModel, e: EditingCellEventArgs) => void
>();
CellEdited = new SubscriptionEvent<
(s: XamGridModel, e: ExitEditingCellEventArgs) => void
>();
InitializeRow = new SubscriptionEvent<
(s: XamGridModel, e: InitializeRowEventArgs) => void
>();
PageIndexChanged = new SubscriptionEvent<
(s: XamGridModel, e: PageChangedEventArgs) => void
>();
PageIndexChanging = new SubscriptionEvent<
(s: XamGridModel, e: CancellablePageChangingEventArgs) => void
>();
RowAdded = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
RowDeleted = new SubscriptionEvent<(s: XamGridModel, e: any) => void>();
RowExitedEditMode = new SubscriptionEvent<
(s: XamGridModel, e: EditingRowEventArgs) => void
>();
RowEnteredEditMode = new SubscriptionEvent<
(s: XamGridModel, e: EditingRowEventArgs) => void
>();
ScrolledCellIntoView: SubscriptionEvent<(cell: XamGridCell) => void> =
new SubscriptionEvent<(cell: XamGridCell) => void>();
isEditableOnAdd: boolean;
private dataColumnInfoAdjusted = false;
editorTemplateLoading = false;
@Dependency(XamGridModel.AutoGenerateColumnsProperty)
AutoGenerateColumns: boolean;
@Dependency(XamGridModel.ColumnWidthProperty)
ColumnWidth: ColumnWidth;
@Dependency(XamGridModel.IsAlternateRowsEnabledProperty)
IsAlternateRowsEnabled: boolean;
FilteringSettings = new FilteringSettings();
@Dependency(XamGridModel.FooterVisibilityProperty)
FooterVisibility: boolean;
EditingSettings = new EditingSettings();
@Dependency(XamGridModel.HeaderStyleProperty)
HeaderStyle: RuntimeStyleInfo;
RowSelectorSettings = new RowSelectorSettings();
@Dependency(XamGridModel.RowHoverProperty)
RowHover: RowHoverType;
PagerSettings = new PagerSettings();
SortingSettings = new SortingSettings();
FixedColumnSettings = new FixedColumnSettings();
ColumnResizingSettings = new ColumnResizingSettings();
ColumnMovingSettings = new ColumnMovingSettings();
SelectedColumnIndex: any;
BorderThickness: ThicknessModel = new ThicknessModel();
BorderBrush: any;
HeaderVisibility: any = 'visible';
HeaderStylePropertyToApply: any = {};
public static TransformStyleCallback(
sender: XamGridModel,
args: DependencyPropertyChangedEventArgs
) {
const xamGridModel: any = sender;
const newStyle = args.NewValue;
if (newStyle instanceof RuntimeStyleInfo) {
transformStyles(
xamGridModel.HeaderStylePropertyToApply,
newStyle.Setters
);
}
}
public get ActiveCell(): CellBase {
return this._activeCell;
}
public set ActiveCell(value: CellBase) {
this.SetActiveCell(
value,
CellAlignment.NotSet,
InvokeAction.Code,
true,
true,
true
);
if (this._activeCell == null) {
this.contextActiveCell = null;
return;
}
const isOnCellActiveEditingEnabled =
this.EditingSettings?.IsOnCellActiveEditingEnabled;
const isReadOnly = this._activeCell.Column.IsReadOnly;
this.contextActiveCell = () => {
this.gridComponentInstance.processActiveCell(
isOnCellActiveEditingEnabled,
isReadOnly
);
this.contextActiveCell = null;
};
setTimeout(() => {
if (
this.gridComponentInstance &&
!this.gridComponentInstance.callProcessActiveCellFlag
) {
this.gridComponentInstance.processActiveCell(
isOnCellActiveEditingEnabled,
isReadOnly
);
}
}, 200);
}
SetActiveCell(
cell: CellBase,
alignment: CellAlignment,
action: InvokeAction,
allowSelection: boolean,
setFocus: boolean,
scrollIntoView: boolean
) {
if (cell != null) {
if (!cell.Column.Visibility) {
throw new Error('InvalidActiveCellException');
}
} else if (this.ActiveCell == null) {
return;
}
if (cell != null && this.ActiveCell == cell) {
if (cell.Control == null) {
return;
}
if (cell.Control.Content instanceof Control) {
cell.Control.Content.focus?.();
return;
}
}
if (scrollIntoView && cell != null && this.ActiveCell != cell && cell.Row) {
this.ScrollCellIntoView(cell);
}
this.isInEditMode(cell);
return this.ActiveLifeCycle(cell);
}
isInEditMode(cell: CellBase) {
if (this.CurrentEditRow != null) {
if (cell != null && cell.Row != this.CurrentEditRow) {
this.ScrollCellIntoView(this.CurrentEditCell);
return;
}
} else if (this.CurrentEditCell != null) {
const currentEditCell = this.CurrentEditCell;
if (
currentEditCell.Row instanceof FilterRow &&
cell != null &&
!(cell.Row instanceof FilterRow) &&
currentEditCell.Row.RowsManager instanceof RowsManager
) {
const dataManager = currentEditCell.Row.RowsManager.DataManager;
if (dataManager != null) {
if (dataManager.FilterItems.Count == 0) {
return;
}
}
}
}
}
private ActiveLifeCycle(cell: CellBase) {
const cell2 = cell;
if (cell2 == null && !(cell instanceof ChildBandCell)) {
cell = null;
}
const activeCellChangingEventArgs = new ActiveCellChangingEventArgs();
activeCellChangingEventArgs.NewActiveCell = cell;
activeCellChangingEventArgs.PreviousActiveCell = this.ActiveCell;
const activeCellChangingEventArgs2 = activeCellChangingEventArgs;
this.OnActiveCellChanging(activeCellChangingEventArgs);
if (!activeCellChangingEventArgs2.Cancel) {
this._activeCell = cell;
this.OnActiveCellChanged();
}
return cell;
}
OnActiveCellChanged() {
this.ActiveCellChanged?.fire([this, {}]);
}
OnActiveCellChanging(e: ActiveCellChangingEventArgs) {
this.ActiveCellChanging?.fire([this, e]);
}
get IsEditableOnAdd(): boolean {
return this.isEditableOnAdd;
}
set IsEditableOnAdd(value: boolean) {
this.isEditableOnAdd = value;
}
@Dependency(XamGridModel.SelectedRowProperty)
public SelectedRow: any;
public get ItemsSource(): Iterable<any> {
return this._rowsManager.ItemsSource;
}
public set ItemsSource(value: Iterable<any>) {
this.setValue(XamGridModel.ItemsSourceProperty, value);
}
SelectedIndex: any;
SelectedItems: ObservableCollection<any> = new ObservableCollection<any>();
get SelectionSettings(): SelectionSettings {
if (this._selectionSettings == null) {
this._selectionSettings = new SelectionSettings(
this._rowsManager.ColumnLayout
);
}
this._selectionSettings.Grid = this;
return this._selectionSettings;
}
set SelectionSettings(value: SelectionSettings) {
if (value !== this._selectionSettings) {
this._selectionSettings = value;
}
}
get Columns(): ColumnBaseCollection {
return this._rowsManager.ColumnLayout.Columns;
}
get Rows(): RowCollection {
return this._rowsManager.Rows.ActualCollection as any;
}
public addColumn(column: XamGridColumnModel): void {
this.setColumnInfo(column);
this.Columns.add(column);
}
addVisualColumn(column: XamGridColumnModel): void {
this.setColumnInfo(column);
this.Columns.add(column);
}
private setColumnInfo(column: XamGridColumnModel) {
column.ColumnLayout = this._rowsManager.ColumnLayout;
column.Parent = this;
}
public getColumns(): ColumnBaseCollection {
return this.Columns;
}
public ScrollCellIntoView(cell: CellBase): void {
if (cell instanceof XamGridCell && cell.Row.Index !== -1) {
this.ScrolledCellIntoView.fire([cell]);
}
}
public CellSelectionChangeHandler(event: any): void {
this.CellSelectionChanged.fire([this, event]);
}
public ScrollIntoView(...args: any[]): void {
Debugger.Throw('Not implemented');
}
public RowSelectionChangeHandler(event: any): void {
this.RowSelectionChanged.fire([this, event]);
}
public ColumnSelectionChangeHandler(event: any): void {
this.ColumnSelectionChanged.fire([this, event]);
}
public KeyDownHandler(event: any): void {
this.KeyDown.fire([this, event]);
}
public CellDoubleClickHandler(event: any): void {
this.CellDoubleClicked.fire([this, event]);
}
public ItemsSourceAsPagedCollection: IPagedCollectionView = null;
public Dispose(disposing?: boolean) {
Debugger.Throw('Not implemented');
}
public ExitEditMode(cancel: boolean) {
this.change.fire(['triggerExitEditMode', !cancel]);
}
public ExitEditModeInternal(cancel: boolean) {
Debugger.Throw('Not implemented');
}
public OnPropertyChanged(name: string) {
Debugger.Throw('Not implemented');
}
public OnGotFocus(args: RoutedEventArgs): void {
super.OnGotFocus(args);
if (this.CurrentEditCell == null && this.ActiveCell == null) {
if (this.Rows.count > 0 && this.Rows.getItem(0).Cells.count > 0) {
const setFocus = true;
for (let cell of this.Rows.getItem(0).Cells) {
if (cell instanceof CellBase && cell.Column.Visibility) {
this.SetActiveCell(
cell,
CellAlignment.NotSet,
InvokeAction.Code,
true,
setFocus,
false
);
break;
}
}
}
}
}
public SetColumnType(columnName: string, type: XamGridColumnType): void {
this.columnTypes.set(columnName, type);
}
public HasColumnType(columnName: string): boolean {
return this.columnTypes.has(columnName);
}
public GetColumnType(columnName: string): XamGridColumnType {
return this.columnTypes.get(columnName);
}
public ClearSelectedRows(): void {
this.SelectionSettings.SelectedRows.clear();
for (const row of this.Rows) {
row.IsSelected = false;
}
}
public SelectRow(row: XamGridRow): void {
const selectedRows = this.SelectionSettings?.SelectedRows;
let oldRows = selectedRows
? new SelectedRowsCollection(selectedRows.toArray())
: new SelectedRowsCollection();
let isChanged = false;
if (
selectedRows &&
this.SelectionSettings?.RowSelection === XamSelectionMode.Single
) {
if (
selectedRows.count > 1 ||
!iuAny(
selectedRows,
(anotherRow) => anotherRow == row || anotherRow.Data === row.Data
)
) {
selectedRows.clear();
selectedRows.add(row);
isChanged = true;
}
} else if (
selectedRows &&
!iuAny(
selectedRows,
(anotherRow) => anotherRow == row || anotherRow.Data === row.Data
)
) {
selectedRows.add(row);
isChanged = true;
}
if (isChanged && this.SelectedRow != row) {
let newRows = new SelectedRowsCollection(selectedRows.toArray());
const params = new SelectionCollectionChangedEventArgs();
params.NewSelectedItems = new SelectedRowsCollection(newRows);
params.PreviouslySelectedItems = new SelectedRowsCollection(oldRows);
this.SelectedRowsCollectionChanged.fire([this, params]);
this.RowSelectionChangeHandler(params);
}
}
public UnselectRow(row: XamGridRow): void {
const selectedRows = this.SelectionSettings?.SelectedRows;
if (selectedRows == null) {
return;
}
const unSelectedRow = iuFirstOrDefault(
selectedRows,
(each: XamGridRow) => each.Data === row.Data
);
let oldRows = new SelectedRowsCollection(selectedRows.toArray());
if (unSelectedRow != null) {
selectedRows.remove(unSelectedRow);
let newRows = new SelectedRowsCollection(selectedRows.toArray());
const params = new SelectionCollectionChangedEventArgs();
params.NewSelectedItems = new SelectedRowsCollection(newRows);
params.PreviouslySelectedItems = new SelectedRowsCollection(oldRows);
this.SelectedRowsCollectionChanged.fire([this, params]);
}
}
private readonly columnTypes: Map<string, XamGridColumnType> = new Map<
string,
XamGridColumnType
>();
}
export class XamGridRowCollection<T> extends ObservableCollection<any> {
private xamGrid: XamGridModel;
constructor(parentGrid: XamGridModel) {
super();
this.xamGrid = parentGrid;
}
getItem(index: number): any {
const row = super.getItem(index);
return row;
}
insert(index: number, value: XamGridRow): void {
super.insert(index, value);
if (index < 0 || value == null) {
return;
}
const source = this.xamGrid.ItemsSource;
if (source) {
this.xamGrid.change.fire(['ItemsSource']);
}
}
remove(value: XamGridRow): boolean {
const result = super.remove(value);
const source = this.xamGrid.ItemsSource;
if (value != null && source) {
const index = -1;
if (index >= 0) {
this.xamGrid.change.fire(['ItemsSource']);
}
}
return result;
}
}
export class ReadOnlyKeyedColumnBaseCollection<
T extends XamGridColumnModel
> extends ObservableCollection<T> {
getColumnByKey(key: string) {
return findColumn(key, this);
}
}
export class ColumnBaseCollection extends ObservableCollection<XamGridColumnModel> {
private _columnLayout: ColumnLayout;
private _nonLayoutColumns: SimpleList<XamGridColumnModel>;
private _dataColumns: ReadOnlyKeyedColumnBaseCollection<XamGridColumnModel>;
private _rebuildAllDataColumnsCache: boolean;
get ColumnLayout(): ColumnLayout {
return this._columnLayout;
}
get NonLayoutColumns(): SimpleList<XamGridColumnModel> {
return this._nonLayoutColumns;
}
get DataColumns(): ReadOnlyKeyedColumnBaseCollection<XamGridColumnModel> {
return new ReadOnlyKeyedColumnBaseCollection(this.toArray());
}
constructor(columnLayout: ColumnLayout) {
super();
this._columnLayout = columnLayout;
this._nonLayoutColumns = new SimpleList<XamGridColumnModel>();
this._dataColumns = new ReadOnlyKeyedColumnBaseCollection(
this._nonLayoutColumns
);
}
getColumnByKey(key: string): XamGridColumnModel {
return findColumn(key, this);
}
getColumnByKeyDeep(key: string): {
column: XamGridColumnModel;
isRoot: boolean;
} {
const groupColumns = [];
for (const column of this) {
if (column.Key === key) {
return { column, isRoot: true };
}
if (column instanceof XamGridGroupColumnModel) {
groupColumns.push(column);
}
}
for (const columnGroup of groupColumns) {
let { column } = columnGroup.Columns.getColumnByKeyDeep(key);
if (column) {
return { column, isRoot: false };
}
}
return { column: null, isRoot: false };
}
AddItem(item: XamGridColumnModel): void {
this.add(item);
this.ColumnLayout.OnColumnAdded(item);
}
getItem(index: number): XamGridColumnModel {
if (index >= 0 || index < this.count) {
return super.getItem(index);
}
}
InvalidateColumnsCollections(fullInvalidate: boolean) {
this._nonLayoutColumns.clear();
if (this.ColumnLayout?.Grid) {
this.internalArray.forEach((ColumnBase) => {
if (ColumnBase instanceof XamGridColumnModel) {
this._nonLayoutColumns.add(ColumnBase);
}
});
this._rebuildAllDataColumnsCache = true;
}
}
add(value: XamGridColumnModel): void {
value.ColumnLayout = this.ColumnLayout;
if (this.ColumnLayout?.Grid?.gridComponentInstance) {
this.ColumnLayout.Grid.gridComponentInstance.forcedColumnsWidthCalc =
true;
this.ColumnLayout.Grid.gridComponentInstance.detectChangesAction?.();
}
super.add(value);
}
}
export class PageChangedEventArgs {
OldPageIndex = -1;
}
export class CancellablePageChangingEventArgs extends CancellableEventArgs {
NextPageIndex = 0;
}
export class CellClickedEventArgs {
constructor(protected model: XamGridCell) {}
get Cell(): any {
return this.model;
}
}
export class BeginEditingCellEventArgs extends CancellableEventArgs {
constructor(protected model: XamGridCell) {
super();
}
get Cell(): any {
return this.model;
}
}
export class EditingCellEventArgs extends CancellableEventArgs {
constructor(protected model: XamGridCell) {
super();
}
#editor: any = null;
get Cell(): XamGridCell {
return this.model;
}
get Editor(): any {
return this.#editor;
}
set Editor(value: any) {
this.#editor = value;
}
}
export class RowEventArgs {
get Row(): any {
Debugger.Throw('Not implemented');
return undefined;
}
}
export class EditingRowEventArgs extends RowEventArgs {
constructor(row: any) {
super();
this.#row = row;
}
#row: XamGridRow;
get Row(): any {
return this.#row;
}
set Row(value: any) {
this.#row = value;
}
}
export class InitializeRowEventArgs extends RowEventArgs {
constructor(row: any) {
super();
this.#row = row;
}
#row: XamGridRow;
get Row(): any {
return this.#row;
}
set Row(value: any) {
this.#row = value;
}
}
export class CellExitedEditingEventArgs {
constructor(protected model: XamGridCell) {}
get Cell(): XamGridCell {
return this.model;
}
}
export class CellControlAttachedEventArgs {
constructor() {}
Cell: XamGridCell;
}
export enum CellSelectionAction {
SelectRow,
SelectCell,
}
export class SelectionSettings {
Grid: XamGridModel;
RowSelection = XamSelectionMode.Single;
CellSelection = XamSelectionMode.Multiple;
ColumnSelection = XamSelectionMode.None;
HideRowCheckboxes = true;
CellClickAction = CellSelectionAction.SelectCell;
SelectedCells = new ObservableCollection();
SelectedColumns: ColumnBaseCollection;
private _selectedRows: SelectedRowsCollection;
get SelectedRows(): SelectedRowsCollection {
if (this._selectedRows == null) {
this._selectedRows = new SelectedRowsCollection();
this._selectedRows.Grid = this.Grid;
}
return this._selectedRows;
}
set SelectedRows(value) {
this._selectedRows = value;
}
constructor(columnLayout: ColumnLayout) {
this.SelectedColumns = new ColumnBaseCollection(columnLayout);
}
}
export enum PagingLocation {
Both,
Bottom,
Hidden,
None,
Top,
}
export class PagerSettings extends Control {
static AllowPagingProperty = new DependencyProperty(
'AllowPaging',
PagingLocation.None,
null
);
static CurrentPageIndexProperty = new DependencyProperty(
'CurrentPageIndex',
0,
null
);
static PageSizeProperty = new DependencyProperty('PageSize', 10, null);
protected _currentPageIndex = 0;
protected _pageSize = 10;
@Dependency(PagerSettings.AllowPagingProperty)
public AllowPaging: PagingLocation;
@Dependency(PagerSettings.CurrentPageIndexProperty)
public CurrentPageIndex: number;
@Dependency(PagerSettings.PageSizeProperty)
public PageSize: number;
}
export class ColumnResizingSettings {
AllowColumnResizing = true;
}
export class ColumnMovingSettings {
AllowColumnMoving = false;
}
export class RowSelectorSettings {
EnableRowNumbering = true;
}
export enum FilteringScope {
ChildBand,
ColumnLayout,
}
export class SortingSettings {
AllowSorting = true;
AllowMultipleColumnSorting = true;
FirstSortDirection = SortDirection.Ascending;
SortedColumns = new ObservableCollection<XamGridColumnModel>();
}
export interface IRecordFilter {
Conditions: any;
FieldName: string;
}
export enum XamGridEditingType {
None,
Cell,
Row,
Hover,
}
export enum MouseEditingAction {
DoubleClick,
None,
SingleClick,
}
export class FilteringSettings extends Control {
static AllowFilteringProperty = new DependencyProperty(
'AllowFiltering',
0,
null
);
protected _allowFiltering = FilterUIType.None;
@Dependency(FilteringSettings.AllowFilteringProperty)
public AllowFiltering: FilterUIType;
FilteringScope = FilteringScope.ChildBand;
RowFiltersCollection = new RowFiltersCollection();
internalXamGrid: XamGridModel;
}
export class RowFiltersCollection extends ObservableCollection<IRecordFilter> {
getItemByKey(key: string): IRecordFilter {
return this.GetRowFilterByColumnKey(key);
}
GetRowFilterByColumnKey(columnKey: string): IRecordFilter {
for (const recordFilter of this.internalArray) {
if (recordFilter.FieldName === columnKey) {
return recordFilter;
}
}
return null;
}
}
export class FixedColumnSettings {
AllowFixedColumns = false;
FixedColumnsLeft = new ObservableCollection<XamGridColumnModel>();
FixedColumnsRight = new ObservableCollection<XamGridColumnModel>();
}
export class EditingSettings {
AllowEditing: XamGridEditingType;
IsOnCellActiveEditingEnabled = false;
IsMouseActionEditingEnabled = MouseEditingAction.DoubleClick;
IsEnterKeyEditingEnabled = false;
IsF2EditingEnabled = false;
}
export class ExitEditingCellEventArgs extends CancellableEventArgs {
constructor(protected model: XamGridCell) {
super();
}
#editor: any = null;
get Cell(): XamGridCell {
return this.model;
}
get Editor(): any {
return this.#editor;
}
set Editor(value: any) {
this.#editor = value;
}
}
export enum FilterUIType {
None,
FilterRowTop,
FilterRowBottom,
FilterMenu,
}
export class XamGridCell extends CellBase {
#IsActive = false;
#IsSelected = false;
_style: RuntimeStyleInfo = null;
key: string;
get gridComponent(): any {
return this.Row.ColumnLayout.Grid?.gridComponentInstance?.grid;
}
private visibleIndex(): number {
return (
this.gridComponent.getColumnByName(this.Column?.Key)?.visibleIndex ?? -1
);
}
EditorStyleResolved: RuntimeStyleInfo = null;
get IsActive(): boolean {
return this.Row.ColumnLayout.Grid.ActiveCell == this;
}
set IsActive(value: boolean) {
if (value) {
this.Row.ColumnLayout.Grid.ActiveCell = this;
} else {
this.Row.ColumnLayout.Grid.ActiveCell = null;
this.Row.ColumnLayout.Grid.gridComponentInstance?.cleanActiveFromIgxGrid?.();
}
}
get IsSelected() {
return this.#IsSelected;
}
set IsSelected(value: boolean) {
if (value === this.#IsSelected) {
return;
}
this.#IsSelected = value;
const node = {
row: this.Row?.Index,
column: this.gridComponent?.getColumnByName(this.Column?.Key)
?.visibleIndex,
};
value
? this.gridComponent?.selectionService.add(node)
: this.gridComponent?.grid?.selectionService.remove(node);
}
get Style() {
return this._style;
}
set Style(val: RuntimeStyleInfo) {
if (this._style !== val) {
this._style = val;
if (
this.Column.ColumnLayout.Grid.gridComponentInstance?.cellStyleEnabled
) {
this.Column.ColumnLayout.Grid.gridComponentInstance.cellChanged();
}
}
}
get Value(): any {
if (this.Row.Data == null) {
return null;
}
if (this.Column.Key == null) {
return null;
}
return this.Row.Data[this.Column.Key];
}
constructor(row?: RowBase, column?: XamGridColumnModel) {
super();
this.Row = row;
this.Column = column;
}
}
export class XamGridCellControl extends ContentControlModel {
UnboundDataContextResolver: UnboundColumnDataContext;
set LazyLoadContent(value: any) {
this.lazyLoadContent = value;
this.isLazyLoad = value ? true : false;
}
onDemandLoadDataContext: any;
Column: any = null;
Cell: any = null;
set Content(value: any) {
this.setValue(XamGridCellControl.ContentProperty, value);
}
get Content(): any {
if (this.isLazyLoad) {
this.setValue(XamGridCellControl.ContentProperty, this.lazyLoadContent());
}
return this.getValue(XamGridCellControl.ContentProperty);
}
set DataContext(value: any) {
this.setValue(XamGridCellControl.DataContextProperty, value);
}
get DataContext(): any {
this.refreshDataContext();
return this.getValue(XamGridCellControl.DataContextProperty);
}
private lazyLoadContent: any;
private isLazyLoad = false;
refreshDataContext(): void {
if (this.onDemandLoadDataContext) {
this.setValue(
XamGridCellControl.DataContextProperty,
this.onDemandLoadDataContext()
);
}
}
public ContentChangeHandler(args: DependencyPropertyChangedEventArgs) {
super.ContentChangeHandler(args);
}
}
export class UnboundColumnDataContext implements INotifyPropertyChanged {
public PropertyChanged: SubscriptionEvent<
(e: any, args: { PropertyName: string }) => void
> = new SubscriptionEvent();
private columnKey: string;
private rowData: any;
private value: any;
private valueConverter: IValueConverter;
public get ColumnKey() {
return this.columnKey;
}
public set ColumnKey(value: string) {
this.columnKey = value;
this.onPropertyChanged({ PropertyName: 'ColumnKey' });
}
public get RowData() {
return this.rowData;
}
public set RowData(value: any) {
this.rowData = value;
this.onPropertyChanged({ PropertyName: 'RowData' });
}
public get Value() {
return this.valueConverter
? this.valueConverter.Convert(this.value, null, null, null)
: this.value;
}
public set Value(value: any) {
this.value = value;
this.onPropertyChanged({ PropertyName: 'Value' });
}
constructor(
columnKey: string,
rowData: any,
value: any,
converter?: IValueConverter
) {
this.columnKey = columnKey;
this.rowData = rowData;
this.value = value;
this.valueConverter = converter;
}
protected onPropertyChanged(info: { PropertyName: string }): void {
this.PropertyChanged.fire([this, info]);
}
}
export class SelectedRowsCollection extends ObservableCollection<XamGridRow> {
Grid: XamGridModel;
constructor(initial?: Iterable<XamGridRow>) {
super(initial);
}
remove(value: XamGridRow): boolean {
value.SetSelected(false);
const newEventArgs =
new SelectionCollectionChangedEventArgs<SelectedRowsCollection>();
newEventArgs.NewSelectedItems = new SelectedRowsCollection();
newEventArgs.PreviouslySelectedItems = new SelectedRowsCollection(
this.toArray()
);
const result = super.remove(value);
this.gridTriggerChange(newEventArgs);
return result;
}
removeAt(index: number): void {
this.getItem(index).SetSelected(false);
const newEventArgs =
new SelectionCollectionChangedEventArgs<SelectedRowsCollection>();
newEventArgs.NewSelectedItems = new SelectedRowsCollection();
newEventArgs.PreviouslySelectedItems = new SelectedRowsCollection(
this.toArray()
);
super.removeAt(index);
this.gridTriggerChange(newEventArgs);
}
private gridTriggerChange(
eventArgs?: SelectionCollectionChangedEventArgs<SelectedRowsCollection>
): void {
if (eventArgs) {
this.Grid?.SelectedRowsCollectionChanged.fire([this.Grid, eventArgs]);
}
this.Grid?.change.fire(['SelectedRowsChanged']);
}
clear(): void {
this.forEach((item) => item.SetSelected(false));
let newEventArgs = null;
if (this.count > 0) {
newEventArgs =
new SelectionCollectionChangedEventArgs<SelectedRowsCollection>();
newEventArgs.NewSelectedItems = new SelectedRowsCollection();
newEventArgs.PreviouslySelectedItems = new SelectedRowsCollection(
this.toArray()
);
}
super.clear();
this.gridTriggerChange(newEventArgs);
}
add(value: XamGridRow): void {
value.SetSelected(true);
const newEventArgs =
new SelectionCollectionChangedEventArgs<SelectedRowsCollection>();
newEventArgs.NewSelectedItems = new SelectedRowsCollection([value]);
newEventArgs.PreviouslySelectedItems = new SelectedRowsCollection(
this.toArray()
);
super.add(value);
this.gridTriggerChange(newEventArgs);
}
addRange(values: Iterable<XamGridRow>): void {
const newEventArgs =
new SelectionCollectionChangedEventArgs<SelectedRowsCollection>();
newEventArgs.NewSelectedItems = new SelectedRowsCollection([...values]);
newEventArgs.PreviouslySelectedItems = new SelectedRowsCollection(
this.toArray()
);
super.addRange(values);
this.forEach((item) => item.SetSelected(true));
this.gridTriggerChange(newEventArgs);
}
}
export class SelectionCollectionChangedEventArgs<T> {
NewSelectedItems: T;
PreviouslySelectedItems: T;
}
export class CancellableColumnResizingEventArgs extends CancellableEventArgs {}
function findColumn(key: string, data): XamGridColumnModel {
for (const column of data) {
if (column.Key === key) {
return column;
}
}
return null;
}