using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Imaging; using FastReport.Editor; using InABox.Core; using Syncfusion.Data; using Selection = InABox.Core.Selection; namespace InABox.DynamicGrid { public abstract class BaseDynamicGrid : ContentControl { public static readonly DependencyProperty UseWaitCursorProperty = DependencyProperty.Register(nameof(UseWaitCursor), typeof(bool), typeof(BaseDynamicGrid)); protected enum ClipAction { Cut, Copy } public BaseDynamicGrid() { UseWaitCursor = true; } public bool UseWaitCursor { get => (bool)GetValue(UseWaitCursorProperty); set => SetValue(UseWaitCursorProperty, value); } public static Brush SelectionBackground { get; set; } public static Brush SelectionForeground { get; set; } public static Brush FilterBackground { get; set; } static BaseDynamicGrid() { SelectionForeground = new SolidColorBrush(Colors.Black); SelectionBackground = new SolidColorBrush(Colors.Silver); FilterBackground = new SolidColorBrush(Color.FromArgb(0xFF, 0xE9, 0xF7, 0xC9)); } } public abstract class BaseDynamicGrid : BaseDynamicGrid, IDynamicGrid where T : BaseObject, new() { public delegate void ValidateEvent(object sender, T[] items, List errors); public event OnPrintData? OnPrintData; public event BeforeRefreshEventHandler? BeforeRefresh; protected void NotifyBeforeRefresh(BeforeRefreshEventArgs args) => BeforeRefresh?.Invoke(this, args); protected abstract bool OnBeforeRefresh(); public event AfterRefreshEventHandler? AfterRefresh; protected void NotifyAfterRefresh(AfterRefreshEventArgs args) => AfterRefresh?.Invoke(this, args); protected abstract void OnAfterRefresh(); public abstract event EntitySaveEvent? OnAfterSave; public abstract event EntitySaveEvent? OnBeforeSave; public event OnDefineFilter? OnDefineFilter; public abstract event OnFilterRecord? OnFilterRecord; public event OnCreateItem? OnCreateItem; public abstract event OnCustomiseEditor? OnCustomiseEditor; public virtual event OnCustomiseColumns? OnCustomiseColumns; public abstract event OnDoubleClick? OnDoubleClick; public OnGetDynamicGridRowStyle? OnGetRowStyle { get; set; } public ValidateEvent? OnValidate; protected DynamicGridRowStyleSelector RowStyleSelector; public BaseDynamicGrid() { Options = new FluentList(); Options.OnChanged += OptionsChanged; RowStyleSelector = GetRowStyleSelector(); RowStyleSelector.GetStyle += (row, style) => GetRowStyle(row, style); HiddenColumns = new List>>(); } public List>> HiddenColumns { get; } public void InitialiseEditorForm(IDynamicEditorForm editor, object[] items, Func? pageDataHandler = null, bool preloadPages = false) { InitialiseEditorForm(editor, items.Cast().ToArray(), pageDataHandler, preloadPages); } public virtual bool EditItems(object[] items, Func? PageDataHandler = null, bool PreloadPages = false) { var values = items.Select(x => (T)x).ToArray(); return EditItems(values, PageDataHandler, PreloadPages); } //public abstract bool DirectEdit(CoreTable data); public FluentList Options { get; } public DynamicGridColumns MasterColumns { get; protected set; } public DynamicGridColumns VisibleColumns { get; protected set; } public CoreTable Data { get; set; } public virtual void ConfigureColumns(DynamicGridColumns columns) { OnCustomiseColumns?.Invoke(this, columns); } public abstract CoreRow[] SelectedRows { get; set; } public abstract void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains); public abstract Button AddButton(string caption, BitmapImage? image, string? tooltip, Func action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left); public virtual double RowHeight { get; set; } public virtual double HeaderHeight { get; set; } public new virtual double FontSize { get; set; } public void AddHiddenColumn(string column) { var expression = CoreUtils.CreateLambdaExpression(column); HiddenColumns.Add(expression); } public abstract int DesiredWidth(); public abstract void Refresh(bool reloadcolumns, bool reloaddata); public abstract void UpdateRow(CoreRow row, string column, TType value, bool refresh = true); public abstract void UpdateRow(CoreRow row, Expression> column, TType value, bool refresh = true); protected abstract DynamicGridRowStyleSelector GetRowStyleSelector(); protected virtual DynamicGridStyle GetRowStyle(CoreRow row, DynamicGridStyle style) { return OnGetRowStyle != null ? OnGetRowStyle(row, style) : style; } public abstract void InitialiseEditorForm(IDynamicEditorForm editor, T[] items, Func? pageDataHandler = null, bool preloadPages = false); public abstract bool EditItems(T[] items, Func? PageDataHandler = null, bool PreloadPages = false); public Filter? DefineFilter() { if (OnDefineFilter is null) return null; var result = OnDefineFilter.Invoke(typeof(T)) as Filter; return result; } protected virtual T CreateItem() { var result = new T(); OnCreateItem?.Invoke(this, result); return result; } protected virtual void DoPrint(object sender) { OnPrintData?.Invoke(sender); } protected abstract void OptionsChanged(object sender, EventArgs args); public IEnumerable ExtractValues(Expression> column, Selection selection) { var result = selection == Selection.None ? new TType[] { } : selection == Selection.Selected ? SelectedRows.Select(r => r.Get(column)).ToArray() : Data.ExtractValues(column); return result; } } }