|
@@ -12,179 +12,190 @@ using FastReport.Utils;
|
|
|
using InABox.Configuration;
|
|
|
using InABox.Core;
|
|
|
|
|
|
-namespace InABox.DynamicGrid
|
|
|
+namespace InABox.DynamicGrid;
|
|
|
+
|
|
|
+public interface IDynamicEnclosedListGrid<TOne, TMany> : IDynamicEditorPage
|
|
|
+{
|
|
|
+ TOne Entity { get; set; }
|
|
|
+ List<TMany> Items { get; }
|
|
|
+ void LoadItems(IEnumerable<TMany> items);
|
|
|
+}
|
|
|
+
|
|
|
+public class DynamicEnclosedListGrid<TOne, TMany> : DynamicGrid<TMany>, IDynamicEditorPage, IDynamicEnclosedListGrid<TOne, TMany>
|
|
|
+ where TMany : BaseObject, new() where TOne : Entity, IRemotable, IPersistent, new()
|
|
|
{
|
|
|
- public interface IDynamicEnclosedListGrid<TOne, TMany> : IDynamicEditorPage
|
|
|
+ private readonly List<TMany> MasterList = new();
|
|
|
+
|
|
|
+ private readonly PropertyInfo property;
|
|
|
+
|
|
|
+ public PageType PageType => PageType.Other;
|
|
|
+
|
|
|
+ public bool ReadOnly { get; set; }
|
|
|
+
|
|
|
+ protected DynamicGridCustomColumnsComponent<TMany> ColumnsComponent;
|
|
|
+
|
|
|
+ public DynamicEnclosedListGrid(PropertyInfo prop)
|
|
|
{
|
|
|
- TOne Entity { get; set; }
|
|
|
- List<TMany> Items { get; }
|
|
|
- void LoadItems(IEnumerable<TMany> items);
|
|
|
+ Items = new List<TMany>();
|
|
|
+ property = prop;
|
|
|
+
|
|
|
+ ColumnsComponent = new(this, null);
|
|
|
}
|
|
|
|
|
|
- public class DynamicEnclosedListGrid<TOne, TMany> : DynamicGrid<TMany>, IDynamicEditorPage, IDynamicEnclosedListGrid<TOne, TMany>
|
|
|
- where TMany : BaseObject, new() where TOne : Entity, IRemotable, IPersistent, new()
|
|
|
+ protected override void Init()
|
|
|
{
|
|
|
- private readonly List<TMany> MasterList = new();
|
|
|
-
|
|
|
- private readonly PropertyInfo property;
|
|
|
+ }
|
|
|
|
|
|
- public PageType PageType => PageType.Other;
|
|
|
+ protected override void DoReconfigure(DynamicGridOptions options)
|
|
|
+ {
|
|
|
+ options.RecordCount = true;
|
|
|
+ options.SelectColumns = true;
|
|
|
+ }
|
|
|
|
|
|
- public bool ReadOnly { get; set; }
|
|
|
+ public DynamicEditorGrid EditorGrid { get; set; }
|
|
|
|
|
|
- protected DynamicGridCustomColumnsComponent<TMany> ColumnsComponent;
|
|
|
+ public bool Ready { get; set; }
|
|
|
|
|
|
- public DynamicEnclosedListGrid(PropertyInfo prop)
|
|
|
- {
|
|
|
- Items = new List<TMany>();
|
|
|
- property = prop;
|
|
|
+ public string Caption()
|
|
|
+ {
|
|
|
+ var caption = typeof(TMany).GetCustomAttribute(typeof(Caption));
|
|
|
+ if (caption != null)
|
|
|
+ return ((Caption)caption).Text;
|
|
|
+ var result = new Inflector.Inflector(new CultureInfo("en")).Pluralize(typeof(TMany).Name);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- ColumnsComponent = new(this, null);
|
|
|
- }
|
|
|
+ public virtual int Order { get; set; } = int.MinValue;
|
|
|
|
|
|
- protected override void Init()
|
|
|
- {
|
|
|
- }
|
|
|
+ public void Load(object item, Func<Type, CoreTable?>? PageDataHandler)
|
|
|
+ {
|
|
|
+ Entity = (TOne)item;
|
|
|
+ MasterList.Clear();
|
|
|
+ if (property.GetValue(item) is IList list)
|
|
|
+ foreach (var entry in list)
|
|
|
+ MasterList.Add((TMany)entry);
|
|
|
+ Items.AddRange(MasterList);
|
|
|
+ Refresh(true, true);
|
|
|
+ Ready = true;
|
|
|
+ }
|
|
|
|
|
|
- protected override void DoReconfigure(DynamicGridOptions options)
|
|
|
+ public void Cancel()
|
|
|
+ {
|
|
|
+ foreach(var item in MasterList)
|
|
|
{
|
|
|
- options.RecordCount = true;
|
|
|
- options.SelectColumns = true;
|
|
|
+ item.CancelChanges();
|
|
|
}
|
|
|
|
|
|
- public DynamicEditorGrid EditorGrid { get; set; }
|
|
|
+ Items.Clear();
|
|
|
+ Items.AddRange(MasterList);
|
|
|
+ Refresh(false, true);
|
|
|
+ }
|
|
|
|
|
|
- public bool Ready { get; set; }
|
|
|
+ public void BeforeSave(object item)
|
|
|
+ {
|
|
|
+ var list = Activator.CreateInstance(property.PropertyType) as IList;
|
|
|
+ foreach (var entry in Items)
|
|
|
+ list.Add(entry);
|
|
|
+ property.SetValue(item, list);
|
|
|
+ }
|
|
|
|
|
|
- public string Caption()
|
|
|
- {
|
|
|
- var caption = typeof(TMany).GetCustomAttribute(typeof(Caption));
|
|
|
- if (caption != null)
|
|
|
- return ((Caption)caption).Text;
|
|
|
- var result = new Inflector.Inflector(new CultureInfo("en")).Pluralize(typeof(TMany).Name);
|
|
|
- return result;
|
|
|
- }
|
|
|
+ public void AfterSave(object item)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
- public virtual int Order { get; set; } = int.MinValue;
|
|
|
+ public Size MinimumSize()
|
|
|
+ {
|
|
|
+ return new Size(400, 400);
|
|
|
+ }
|
|
|
|
|
|
- public void Load(object item, Func<Type, CoreTable?>? PageDataHandler)
|
|
|
- {
|
|
|
- Entity = (TOne)item;
|
|
|
- MasterList.Clear();
|
|
|
- if (property.GetValue(item) is IList list)
|
|
|
- foreach (var entry in list)
|
|
|
- MasterList.Add((TMany)entry);
|
|
|
- Items.AddRange(MasterList);
|
|
|
- Refresh(true, true);
|
|
|
- Ready = true;
|
|
|
- }
|
|
|
+ public List<TMany> Items { get; private set; }
|
|
|
|
|
|
- public void BeforeSave(object item)
|
|
|
- {
|
|
|
- var list = Activator.CreateInstance(property.PropertyType) as IList;
|
|
|
- foreach (var entry in Items)
|
|
|
- list.Add(entry);
|
|
|
- property.SetValue(item, list);
|
|
|
- }
|
|
|
+ public TOne Entity { get; set; }
|
|
|
|
|
|
- public void AfterSave(object item)
|
|
|
- {
|
|
|
- }
|
|
|
+ public void LoadItems(IEnumerable<TMany> items)
|
|
|
+ {
|
|
|
+ Items.Clear();
|
|
|
+ if (items != null)
|
|
|
+ Items.AddRange(items);
|
|
|
+ Refresh(false, true);
|
|
|
+ }
|
|
|
|
|
|
- public Size MinimumSize()
|
|
|
- {
|
|
|
- return new Size(400, 400);
|
|
|
- }
|
|
|
+ public override DynamicGridColumns GenerateColumns()
|
|
|
+ {
|
|
|
+ var cols = new DynamicGridColumns();
|
|
|
+ cols.AddRange(base.GenerateColumns().Where(x => !x.ColumnName.StartsWith(property.Name + ".")));
|
|
|
+ return cols;
|
|
|
+ }
|
|
|
|
|
|
- public List<TMany> Items { get; private set; }
|
|
|
+ protected override DynamicGridColumns LoadColumns()
|
|
|
+ {
|
|
|
+ return ColumnsComponent.LoadColumns();
|
|
|
+ }
|
|
|
|
|
|
- public TOne Entity { get; set; }
|
|
|
+ protected override void SaveColumns(DynamicGridColumns columns)
|
|
|
+ {
|
|
|
+ ColumnsComponent.SaveColumns(columns);
|
|
|
+ }
|
|
|
|
|
|
- public void LoadItems(IEnumerable<TMany> items)
|
|
|
- {
|
|
|
- Items.Clear();
|
|
|
- if (items != null)
|
|
|
- Items.AddRange(items);
|
|
|
- Refresh(false, true);
|
|
|
- }
|
|
|
+ protected override void LoadColumnsMenu(ContextMenu menu)
|
|
|
+ {
|
|
|
+ base.LoadColumnsMenu(menu);
|
|
|
+ ColumnsComponent.LoadColumnsMenu(menu);
|
|
|
+ }
|
|
|
|
|
|
- public override DynamicGridColumns GenerateColumns()
|
|
|
- {
|
|
|
- var cols = new DynamicGridColumns();
|
|
|
- cols.AddRange(base.GenerateColumns().Where(x => !x.ColumnName.StartsWith(property.Name + ".")));
|
|
|
- return cols;
|
|
|
- }
|
|
|
+ public override TMany LoadItem(CoreRow row)
|
|
|
+ {
|
|
|
+ return Items[row.Index];
|
|
|
+ }
|
|
|
|
|
|
- protected override DynamicGridColumns LoadColumns()
|
|
|
- {
|
|
|
- return ColumnsComponent.LoadColumns();
|
|
|
- }
|
|
|
+ public override void SaveItem(TMany item)
|
|
|
+ {
|
|
|
+ if (!Items.Contains(item))
|
|
|
+ Items.Add(item);
|
|
|
|
|
|
- protected override void SaveColumns(DynamicGridColumns columns)
|
|
|
+ if (item is ISequenceable && LookupFactory.DefineSort<TMany>() is SortOrder<TMany> sort)
|
|
|
{
|
|
|
- ColumnsComponent.SaveColumns(columns);
|
|
|
+ Items = Items.AsQueryable().SortBy(sort.Expression).ToList();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- protected override void LoadColumnsMenu(ContextMenu menu)
|
|
|
- {
|
|
|
- base.LoadColumnsMenu(menu);
|
|
|
- ColumnsComponent.LoadColumnsMenu(menu);
|
|
|
- }
|
|
|
+ public override void DeleteItems(params CoreRow[] rows)
|
|
|
+ {
|
|
|
+ foreach (var row in rows.OrderByDescending(x => x.Index))
|
|
|
+ Items.RemoveAt(row.Index);
|
|
|
+ }
|
|
|
|
|
|
- public override TMany LoadItem(CoreRow row)
|
|
|
- {
|
|
|
- return Items[row.Index];
|
|
|
- }
|
|
|
+ protected override void Reload(
|
|
|
+ Filters<TMany> criteria, Columns<TMany> columns, ref SortOrder<TMany>? sort,
|
|
|
+ CancellationToken token, Action<CoreTable?, Exception?> action)
|
|
|
+ {
|
|
|
+ var results = new CoreTable();
|
|
|
+ results.LoadColumns(typeof(TMany));
|
|
|
|
|
|
- public override void SaveItem(TMany item)
|
|
|
+ if (sort != null)
|
|
|
{
|
|
|
- if (!Items.Contains(item))
|
|
|
- Items.Add(item);
|
|
|
-
|
|
|
- if (item is ISequenceable && LookupFactory.DefineSort<TMany>() is SortOrder<TMany> sort)
|
|
|
+ var exp = IQueryableExtensions.ToLambda<TMany>(sort.Expression);
|
|
|
+ var sorted = sort.Direction == SortDirection.Ascending
|
|
|
+ ? Items.AsQueryable().OrderBy(exp)
|
|
|
+ : Items.AsQueryable().OrderByDescending(exp);
|
|
|
+ foreach (var then in sort.Thens)
|
|
|
{
|
|
|
- Items = Items.AsQueryable().SortBy(sort.Expression).ToList();
|
|
|
+ var thexp = IQueryableExtensions.ToLambda<TMany>(then.Expression);
|
|
|
+ sorted = sort.Direction == SortDirection.Ascending ? sorted.ThenBy(exp) : sorted.ThenByDescending(exp);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- public override void DeleteItems(params CoreRow[] rows)
|
|
|
- {
|
|
|
- foreach (var row in rows.OrderByDescending(x => x.Index))
|
|
|
- Items.RemoveAt(row.Index);
|
|
|
+ results.LoadRows(sorted);
|
|
|
}
|
|
|
-
|
|
|
- protected override void Reload(
|
|
|
- Filters<TMany> criteria, Columns<TMany> columns, ref SortOrder<TMany>? sort,
|
|
|
- CancellationToken token, Action<CoreTable?, Exception?> action)
|
|
|
+ else
|
|
|
{
|
|
|
- var results = new CoreTable();
|
|
|
- results.LoadColumns(typeof(TMany));
|
|
|
-
|
|
|
- if (sort != null)
|
|
|
- {
|
|
|
- var exp = IQueryableExtensions.ToLambda<TMany>(sort.Expression);
|
|
|
- var sorted = sort.Direction == SortDirection.Ascending
|
|
|
- ? Items.AsQueryable().OrderBy(exp)
|
|
|
- : Items.AsQueryable().OrderByDescending(exp);
|
|
|
- foreach (var then in sort.Thens)
|
|
|
- {
|
|
|
- var thexp = IQueryableExtensions.ToLambda<TMany>(then.Expression);
|
|
|
- sorted = sort.Direction == SortDirection.Ascending ? sorted.ThenBy(exp) : sorted.ThenByDescending(exp);
|
|
|
- }
|
|
|
-
|
|
|
- results.LoadRows(sorted);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- results.LoadRows(Items);
|
|
|
- }
|
|
|
+ results.LoadRows(Items);
|
|
|
+ }
|
|
|
|
|
|
- //if (sort != null)
|
|
|
- // results.LoadRows(Items.AsQueryable().SortBy(sort.Expression));
|
|
|
- //else
|
|
|
- // results.LoadRows(Items.OrderBy(x => x.Sort));
|
|
|
+ //if (sort != null)
|
|
|
+ // results.LoadRows(Items.AsQueryable().SortBy(sort.Expression));
|
|
|
+ //else
|
|
|
+ // results.LoadRows(Items.OrderBy(x => x.Sort));
|
|
|
|
|
|
- action.Invoke(results, null);
|
|
|
- }
|
|
|
+ action.Invoke(results, null);
|
|
|
}
|
|
|
}
|