using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using System.Threading.Tasks; using System.Windows; using InABox.Configuration; using InABox.Core; namespace InABox.DynamicGrid { public interface IDynamicEnclosedListGrid : IDynamicEditorPage { TOne Entity { get; set; } List Items { get; } void LoadItems(IEnumerable items); } public class DynamicEnclosedListGrid : DynamicGrid, IDynamicEditorPage, IDynamicEnclosedListGrid where TMany : BaseObject, new() where TOne : Entity, IRemotable, IPersistent, new() { private readonly List MasterList = new(); private readonly PropertyInfo property; public PageType PageType => PageType.Other; public DynamicEnclosedListGrid(PropertyInfo prop) { Items = new List(); property = prop; Options.AddRange(DynamicGridOption.RecordCount, DynamicGridOption.SelectColumns); } public DynamicEditorGrid EditorGrid { get; set; } public bool Ready { get; set; } 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 virtual int Order() { return int.MinValue; } public void Load(object item, Func? PageDataHandler) { Entity = (TOne)item; MasterList.Clear(); var list = property.GetValue(item) as IList; if (list != null) foreach (var entry in list) MasterList.Add((TMany)entry); Items.AddRange(MasterList); Refresh(true, true); Ready = true; } 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 void AfterSave(object item) { } public Size MinimumSize() { return new Size(400, 400); } public List Items { get; private set; } public TOne Entity { get; set; } public void LoadItems(IEnumerable items) { Items.Clear(); if (items != null) Items.AddRange(items); Refresh(false, true); } protected override DynamicGridColumns LoadColumns() { var tag = typeof(TMany).Name; var global = Task.Run(() => new GlobalConfiguration(tag).Load()); var user = Task.Run(() => new UserConfiguration(tag).Load()); Task.WaitAll(global, user); var columns = user.Result.Any() ? user.Result : global.Result; if (columns.Count == 0) columns.AddRange(base.LoadColumns().Where(x => !x.ColumnName.StartsWith(property.Name))); return columns; } protected override void SaveColumns(DynamicGridColumns columns) { var tag = typeof(TMany).Name; new UserConfiguration(tag).Save(columns); } protected override TMany LoadItem(CoreRow row) { return Items[row.Index]; } protected override TMany[] LoadItems(CoreRow[] rows) { var result = new List(); foreach (var row in rows) result.Add(Items[row.Index]); return result.ToArray(); } public override void SaveItem(TMany item) { if (!Items.Contains(item)) Items.Add(item); if (item is ISequenceable) { //var exp = BaseObject.DefaultSortOrder().Expression; var exp = LookupFactory.DefineSort().Expression; Items = Items.AsQueryable().SortBy(exp).ToList(); } } protected override void DeleteItems(params CoreRow[] rows) { foreach (var row in rows.OrderByDescending(x => x.Index)) Items.RemoveAt(row.Index); } protected override void Reload(Filters criteria, Columns columns, ref SortOrder? sort, Action action) { var results = new CoreTable(); results.LoadColumns(typeof(TMany)); if (sort != null) { var exp = IQueryableExtensions.ToLambda(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(then.Expression); sorted = sort.Direction == SortDirection.Ascending ? sorted.ThenBy(exp) : sorted.ThenByDescending(exp); } results.LoadRows(sorted); } else { results.LoadRows(Items); } //if (sort != null) // results.LoadRows(Items.AsQueryable().SortBy(sort.Expression)); //else // results.LoadRows(Items.OrderBy(x => x.Sort)); action.Invoke(results, null); } } }