| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 | 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 static InABox.DynamicGrid.IDynamicGrid;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<T> : BaseDynamicGrid, IDynamicGrid where T : BaseObject, new()    {        public delegate void ValidateEvent(object sender, T[] items, List<string> 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<T>? OnCustomiseEditor;        public virtual event OnCustomiseColumns? OnCustomiseColumns;        public abstract event OnDoubleClick? OnDoubleClick;        public OnGetDynamicGridRowStyle? OnGetRowStyle { get; set; }                public ValidateEvent? OnValidate;                protected DynamicGridRowStyleSelector<T> RowStyleSelector;        public event IDynamicGrid.ReconfigureEvent? OnReconfigure;                private bool _hasLoadedOptions = false;                public BaseDynamicGrid()        {            Options = new FluentList<DynamicGridOption>();            Options.OnChanged += (sender, args) =>            {                _hasLoadedOptions = true;                OptionsChanged();            };                        RowStyleSelector = GetRowStyleSelector();            RowStyleSelector.GetStyle += (row, style) => GetRowStyle(row, style);                        HiddenColumns = new HiddenColumnsList();        }        /// <summary>        /// Initialise things like custom buttons; called once during construction.        /// </summary>        protected abstract void Init();        protected abstract void DoReconfigure(FluentList<DynamicGridOption> options);        /// <summary>        /// Configure custom buttons and options.        /// </summary>        private void Reconfigure(FluentList<DynamicGridOption> options)        {            options.BeginUpdate().Clear();            DoReconfigure(options);            OnReconfigure?.Invoke(options);            options.EndUpdate();            if (!_hasLoadedOptions)            {                _hasLoadedOptions = true;                OptionsChanged();            }        }        public void Reconfigure()        {            Reconfigure(Options);        }        public void Reconfigure(ReconfigureEvent onReconfigure)        {            OnReconfigure += onReconfigure;            Reconfigure();        }        public bool HasOption(DynamicGridOption option, IEnumerable<DynamicGridOption>? options = null) => (options ?? Options).Contains(option);        bool IDynamicGrid.HasOption(InABox.DynamicGrid.DynamicGridOption option) => HasOption(option, null);        public class HiddenColumnsList        {            private List<string> Columns { get; set; } = new();            public IEnumerable<string> ColumnNames => Columns;            public void Add(Expression<Func<T, object?>> column)            {                Columns.Add(CoreUtils.GetFullPropertyName(column, "."));            }            public void Add(IColumn column)            {                Columns.Add(column.Property);            }        }        public HiddenColumnsList HiddenColumns { get; }        public void InitialiseEditorForm(IDynamicEditorForm editor, object[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false)        {            InitialiseEditorForm(editor, items.Cast<T>().ToArray(), pageDataHandler, preloadPages);        }        public virtual bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)        {            var values = items.Cast<T>().ToArray();            return EditItems(values, PageDataHandler, PreloadPages);        }        //public abstract bool DirectEdit(CoreTable data);        private FluentList<DynamicGridOption> 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<Button, CoreRow[], bool> action,            DynamicGridButtonPosition position = DynamicGridButtonPosition.Left);        public Button AddButton(string? caption, BitmapImage? image, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)        {            var result = AddButton(caption, image, null, action, position);            return result;        }        public abstract void UpdateButton(Button button, BitmapImage? image, string? text, string? tooltip = null);        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<T>(column);            HiddenColumns.Add(expression);        }        public abstract int DesiredWidth();        public abstract void Refresh(bool reloadcolumns, bool reloaddata);        public abstract void UpdateRow<TType>(CoreRow row, string column, TType value, bool refresh = true);        public abstract void UpdateRow<TRow, TType>(CoreRow row, Expression<Func<TRow, TType>> column, TType value, bool refresh = true);                protected abstract DynamicGridRowStyleSelector<T> 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<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false);        public abstract bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false);        public Filter<T>? DefineFilter()        {            if (OnDefineFilter is null)                return null;            var result = OnDefineFilter.Invoke(typeof(T)) as Filter<T>;            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();                public IEnumerable<TType> ExtractValues<TType>(Expression<Func<T, TType>> 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;        }    }}
 |