123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Reflection;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using InABox.Clients;
- using InABox.Core;
- using InABox.Wpf;
- using InABox.Core.Reports;
- using Syncfusion.Data.Extensions;
- using System.Diagnostics.CodeAnalysis;
- using System.Data;
- using System.Windows.Media;
- namespace InABox.DynamicGrid;
- [Caption("Set Default Column Selections")]
- public class CanSetDefaultColumns : EnabledSecurityDescriptor<CoreLicense>
- {
- }
- [LibraryInitializer]
- public static class DynamicGridUtils
- {
- private static IEnumerable<Type>? _allm2mtypes;
- private static IEnumerable<Type>? _allm2mpages;
- private static IEnumerable<Type>? _allo2mtypes;
- private static IEnumerable<Type>? _allo2mpages;
- private static IEnumerable<Type>? _allcepages;
- private static IEnumerable<Type>? _alleltypes;
-
- private static Dictionary<Type, IList<Type>> _onetomanypages = new();
- private static Dictionary<Type, IList<Type>> _manytomanytomanypages = new();
- private static Dictionary<Type, IList<Tuple<Type, PropertyInfo>>> _enclosedlistpages = new();
- private static Dictionary<Type, IList<Type>> _customeditorpages = new();
- // HACK: These are really dumb
- public static Action<ReportTemplate, DataModel>? PreviewReport { get; set; }
- public static Action<FrameworkElement?, string, DataModel, bool>? PrintMenu { get; set; }
- public static readonly MainResources Resources = new();
- public static void RegisterClasses()
- {
- // String assyname = "_" + Assembly.GetExecutingAssembly().GetName().Name;
- // AssemblyName assemblyName = new AssemblyName(assyname);
- // AppDomain appDomain = Thread.GetDomain();
- //
- // String assyFile = String.Format("{0}.dll", assemblyName.Name);
- // String path = "";
- // if (Assembly.GetEntryAssembly() != null)
- // {
- // path = Path.Combine(
- // Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
- // Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location)
- // );
- // }
- // else
- // {
- // path = Path.Combine(
- // Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
- // Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location)
- // );
- // }
- //
- // if (!Directory.Exists(path))
- // Directory.CreateDirectory(path);
- // AssemblyBuilder assemblyBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, path);
- //
- // ModuleBuilder module = assemblyBuilder.DefineDynamicModule(assyFile); //,true);
- //
- // if (_allm2mtypes == null)
- // {
- // _allm2mtypes = CoreUtils.TypeList(
- // AppDomain.CurrentDomain.GetAssemblies(),
- // x => x.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>))
- // );
- // }
- //
- // var maps = _allm2mtypes.Where(x => x.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>) && i.GenericTypeArguments.Last().Equals(typeof(Document))));
- //
- // foreach (var map in maps)
- // {
- // var intf = map.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>) && i.GenericTypeArguments.Last().Equals(typeof(Document)));
- // Type entity = intf.GenericTypeArguments.First();
- // Type basetype = typeof(DynamicDocumentGrid<,>).MakeGenericType(map, entity);
- // TypeBuilder tbService = module.DefineType(String.Format("{0}", map.EntityName().Replace(".", "_")), TypeAttributes.Public | TypeAttributes.Class);
- // tbService.SetParent(basetype);
- // Type final = tbService.CreateType();
- // }
- //
- // try
- // {
- // assemblyBuilder.Save(assyFile);
- // }
- // catch (Exception e)
- // {
- // Logger.Send(LogType.Error, "", String.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
- // }
-
- }
- #region Pages
- public static IEnumerable<Type> GetManyToManyTypes(Type type)
- {
- _allm2mtypes ??= CoreUtils.Entities.Where(x => x.HasInterface(typeof(IManyToMany<,>))).ToArray();
- return _allm2mtypes.Where(x => x.GetInterfaces().Any(
- i => i.IsGenericType
- && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>)
- && i.GenericTypeArguments[0] == type)
- );
- }
- public static void LoadManyToManyPages(Type type, DynamicEditorPages pages)
- {
- if (!_manytomanytomanypages.TryGetValue(type, out var pageTypes))
- {
- pageTypes = new List<Type>();
- var maps = GetManyToManyTypes(type);
- foreach (var map in maps)
- {
- if (ClientFactory.IsSupported(map))
- {
- _allm2mpages ??= CoreUtils.Entities.Where(
- x => x.IsClass
- && !x.IsGenericType
- && x.HasInterface(typeof(IDynamicManyToManyGrid<,>)))
- .ToArray();
- var subtypes = _allm2mpages.Where(
- x => x.GetInterfaces().Any(i =>
- i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDynamicManyToManyGrid<,>) &&
- i.GenericTypeArguments.First().Equals(map) && i.GenericTypeArguments.Last().Equals(type))
- );
- if (subtypes.Any())
- {
- pageTypes.Add(subtypes.First());
- }
- else
- {
- pageTypes.Add(typeof(DynamicManyToManyGrid<,>).MakeGenericType(map, type));
- }
- }
- }
- _manytomanytomanypages[type] = pageTypes.ToArray();
- }
- pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x) as IDynamicEditorPage)!));
- }
- public static IEnumerable<Type> GetOneToManyTypes(Type type)
- {
- _allo2mtypes ??= CoreUtils.Entities.Where(
- x => x.HasInterface(typeof(IOneToMany<>)) && !x.HasAttribute<ObsoleteAttribute>())
- .ToArray();
- return _allo2mtypes
- .Where(x => x.GetInterfaces().Any(i =>
- i.IsGenericType
- && i.GetGenericTypeDefinition() == typeof(IOneToMany<>)
- && i.GenericTypeArguments.Contains(type)))
- .OrderBy(x => x.EntityName());
- }
-
- public static void LoadOneToManyPages(Type type, DynamicEditorPages pages)
- {
- if (!_onetomanypages.TryGetValue(type, out var pageTypes))
- {
- pageTypes = new List<Type>();
- var maps = GetOneToManyTypes(type);
- foreach (var map in maps)
- {
- if (ClientFactory.IsSupported(map))
- {
- _allo2mpages ??= CoreUtils.Entities.Where(
- x =>
- x.IsClass
- && !x.IsGenericType
- && x.HasInterface(typeof(IDynamicOneToManyGrid<,>))
- && !x.HasInterface<ISpecificGrid>())
- .ToArray();
- var subtypes = _allo2mpages.Where(x => x.GetInterfaces().Any(
- i => i.IsGenericType
- && i.GetGenericTypeDefinition() == typeof(IDynamicOneToManyGrid<,>)
- && i.GenericTypeArguments.First().Equals(type)
- && i.GenericTypeArguments.Last().Equals(map)
- )
- );
- if (subtypes.Any())
- {
- pageTypes.Add(subtypes.First());
- }
- else
- {
- pageTypes.Add(typeof(DynamicOneToManyGrid<,>).MakeGenericType(type, map));
- }
- }
- }
- _onetomanypages[type] = pageTypes.ToArray();
- }
- pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x) as IDynamicEditorPage)!));
- }
- public static void LoadCustomEditorPages(Type type, DynamicEditorPages pages)
- {
- if (!_customeditorpages.TryGetValue(type, out var pageTypes))
- {
- _allcepages ??= CoreUtils.Entities.Where(
- x => x.IsClass
- && !x.IsGenericType
- && x.HasInterface(typeof(IDynamicCustomEditorPage<>)))
- .ToArray();
- pageTypes = _allcepages.Where(x => x.GetInterfaces().Any(i =>
- i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDynamicCustomEditorPage<>) &&
- i.GenericTypeArguments.First().Equals(type))).ToArray();
- _customeditorpages[type] = pageTypes;
- }
- pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x) as IDynamicEditorPage)!));
- }
- public static void LoadEnclosedListPages(Type type, DynamicEditorPages pages)
- {
- if (!_enclosedlistpages.TryGetValue(type, out var pageTypes))
- {
- pageTypes = new List<Tuple<Type, PropertyInfo>>();
- foreach (var property in type.GetProperties())
- {
- if (property.PropertyType.GetInterfaces().Contains(typeof(IList)))
- {
- var curtype = property.PropertyType;
- var gentype = property.PropertyType.GetGenericArguments().FirstOrDefault();
- while (gentype == null && curtype?.BaseType != null)
- {
- curtype = curtype.BaseType;
- gentype = curtype?.GetGenericArguments().FirstOrDefault();
- }
- if (gentype != null)
- if (gentype.IsSubclassOf(typeof(BaseObject)))
- {
- var editor = property.GetCustomAttributes().FirstOrDefault(x => x is BaseEditor);
- if (editor == null || !(editor is NullEditor))
- {
- _alleltypes ??= CoreUtils.Entities.Where(
- x => x.IsClass
- && !x.IsGenericType
- && x.HasInterface(typeof(IDynamicEnclosedListGrid<,>)))
- .ToArray();
- var subtypes = _alleltypes.Where(
- x => x.GetInterfaces().Any(
- i => i.IsGenericType
- && i.GetGenericTypeDefinition() == typeof(IDynamicEnclosedListGrid<,>)
- && i.GenericTypeArguments.First().Equals(type)
- && i.GenericTypeArguments.Last().Equals(gentype)
- )
- );
- if (subtypes.Any())
- {
- pageTypes.Add(new(subtypes.First(), property));
- }
- else
- {
- subtypes = _alleltypes.Where(x => x.GetInterfaces().Any(i => (i.GenericTypeArguments.LastOrDefault()?.Equals(gentype) == true)));
- if (subtypes.Any())
- {
- pageTypes.Add(new(subtypes.First().MakeGenericType(type), property));
- }
- else
- {
- try
- {
- pageTypes.Add(new(typeof(DynamicEnclosedListGrid<,>).MakeGenericType(type, gentype), property));
- }
- catch (Exception e)
- {
- Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
- }
- }
- }
- }
- }
- }
- }
- _enclosedlistpages[type] = pageTypes.ToArray();
- }
- pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x.Item1, x.Item2) as IDynamicEditorPage)!));
- }
- #endregion
- #region Columns
- public static Columns<T> LoadEditorColumns<T>(Columns<T> additional)
- {
- var result = new Columns<T>(ColumnTypeFlags.EditorColumns);
- foreach (var col in additional)
- result.Add(col.Property);
- foreach (var col in result.ToArray())
- {
- var prop = DatabaseSchema.Property(typeof(T), col.Property);
- if (prop?.Editor is DataLookupEditor dataLookup)
- {
- foreach (var lookupColumn in LookupFactory.DefineLookupFilterColumns(typeof(T), prop.Name))
- {
- result.Add(lookupColumn);
- }
- }
- }
- return result;
- }
- #endregion
- #region Editor Values
- public static Dictionary<string, object?> UpdateEditorValue(BaseObject[] items, string name, object? value)
- {
- Logger.Send(LogType.Information, "", string.Format("DynamicGridUtils.UpdateEditorValue({0},{1},{2})", items.Length, name, value));
- var sw = new Stopwatch();
- var changes = new Dictionary<string, object?>();
- var props = DatabaseSchema.Properties(items.First().GetType()).ToArray();
- foreach (var item in items)
- {
- //Dictionary<String, object> previous = new Dictionary<string, object>();
- var previous = CoreUtils.GetValues(item, props);
- //if (item.OriginalValues != null)
- //{
- // foreach (var key in item.OriginalValues.Keys)
- // previous[key] = item.OriginalValues[key];
- //}
- var prop = DatabaseSchema.Property(item.GetType(), name);
- if (prop is CustomProperty)
- {
- if (!item.HasOriginalValue(name))
- item.SetOriginalValue(name, item.UserProperties[name]);
- item.UserProperties[name] = value;
- }
- else
- {
- if (prop != null)
- try
- {
- var getter = prop.Getter();
- var oldvalue = getter != null ? getter.Invoke(item) : CoreUtils.GetPropertyValue(item, name);
- item.OnPropertyChanged(name, oldvalue, value);
- var setter = prop.Setter();
- if (setter != null && value != null)
- setter.Invoke(item, value);
- else
- CoreUtils.SetPropertyValue(item, name, value);
- }
- catch (Exception)
- {
- Logger.Send(LogType.Error, "",
- string.Format("Unable to Set Value for [{0}.{1}] (Value is {2})", item.GetType().Name, name, value));
- }
- }
- var current = CoreUtils.GetValues(item, props);
- CoreUtils.MergeChanges(previous, current, changes);
- }
-
- return changes;
- }
- public static void UpdateEditorValue(BaseObject[] items, string name, object? value, Dictionary<string, object?> changes)
- {
- var results = UpdateEditorValue(items, name, value);
- foreach (var key in results.Keys)
- changes[key] = results[key];
- }
- #endregion
- #region Dynamic Grid Creation
- public static IDynamicGrid CreateDynamicGrid(Type gridType, Type entityType)
- {
- var type = FindDynamicGrid(gridType, entityType);
- return (Activator.CreateInstance(type) as IDynamicGrid)
- ?? throw new ArgumentException("Argument must be a type of IDynamicGrid", nameof(gridType));
- }
- public static DynamicGrid<TEntity> CreateDynamicGrid<TEntity>(Type gridType)
- where TEntity : BaseObject, new()
- {
- var type = FindDynamicGrid(gridType, typeof(TEntity));
- return (Activator.CreateInstance(type) as DynamicGrid<TEntity>)
- ?? throw new ArgumentException("Argument must be a type of IDynamicGrid", nameof(gridType));
- }
- private static Dictionary<Type, Type[]> _dynamicGrids = new();
- public static bool TryFindDynamicGrid(Type gridType, Type entityType, [NotNullWhen(true)] out Type? grid)
- {
- if (!_dynamicGrids.TryGetValue(gridType, out var grids))
- {
- grids = CoreUtils.Entities.Where(
- myType =>
- myType.IsClass
- && !myType.IsGenericType
- && myType.IsAssignableTo(typeof(IDynamicGrid))
- && !myType.IsAssignableTo(typeof(ISpecificGrid))
- ).ToArray();
- _dynamicGrids[gridType] = grids;
- }
- grids = grids.Where(x => x.IsSubclassOfRawGeneric(gridType)).ToArray();
- var entityGrids = grids.Where(x =>
- {
- var baseGrid = x.GetSuperclassDefinition(typeof(DynamicGrid<>));
- return baseGrid?.GenericTypeArguments[0] == entityType;
- }).ToList();
- var defaults = entityGrids.Where(x => x.IsAssignableTo(typeof(IDefaultGrid))).ToList();
- if (defaults.Count > 0)
- {
- if (defaults.Count > 1)
- {
- Logger.Send(LogType.Information, ClientFactory.UserID, $"Error: {defaults.Count} IDefaultGrid derivations for {gridType.Name} of {entityType.Name}");
- }
- grid = defaults.First();
- return true;
- }
- grid = entityGrids.FirstOrDefault();
- return grid is not null;
- }
- public static Type FindDynamicGrid(Type gridType, Type entityType)
- {
- if(TryFindDynamicGrid(gridType, entityType, out var grid))
- {
- return grid;
- }
- return gridType.MakeGenericType(entityType);
- }
- public static Window CreateGridWindow(string title, IDynamicGrid dynamicGrid)
- {
- dynamicGrid.Margin = new Thickness(5);
- var window = new ThemableWindow { Title = title, Content = dynamicGrid };
- dynamicGrid.Refresh(true, true);
- return window;
- }
- public static Window CreateGridWindow(string title, Type entityType, Type? gridType = null)
- {
- gridType ??= typeof(DynamicGrid<>);
- var grid = CreateDynamicGrid(gridType, entityType);
- return CreateGridWindow(title, grid);
- }
- public static Window CreateGridWindow<TGrid, TEntity>(string title)
- where TEntity : BaseObject
- where TGrid : IDynamicGrid
- {
- return CreateGridWindow(title, typeof(TEntity), typeof(TGrid));
- }
- public static Window CreateGridWindow<TEntity>(string title)
- where TEntity : BaseObject
- {
- return CreateGridWindow(title, typeof(TEntity));
- }
- #endregion
- #region Editing BaseObject
- /// <summary>
- /// Edit (using <see cref="DynamicItemsListGrid{T}"/>) a list of <see cref="BaseObject"/>s. Use for objects not saved in the database.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="items"></param>
- /// <param name="pageDataHandler"></param>
- /// <param name="preloadPages"></param>
- /// <returns></returns>
- public static bool EditObjects<T>(T[] items, Func<Type, CoreTable?>? pageDataHandler = null, bool preloadPages = false, Action<DynamicGrid<T>>? customiseGrid = null)
- where T : BaseObject, new()
- {
- var grid = new DynamicItemsListGrid<T>();
- customiseGrid?.Invoke(grid);
- return grid.EditItems(items, PageDataHandler: pageDataHandler, PreloadPages: preloadPages);
- }
- /// <summary>
- /// Edit (using <see cref="DynamicItemsListGrid{T}"/>) a <see cref="BaseObject"/>. Use for objects not saved in the database.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="items"></param>
- /// <param name="pageDataHandler"></param>
- /// <param name="preloadPages"></param>
- /// <returns></returns>
- public static bool EditObject<T>(T item, Func<Type, CoreTable?>? pageDataHandler = null, bool preloadPages = false, Action<DynamicGrid<T>>? customiseGrid = null)
- where T : BaseObject, new()
- {
- var grid = new DynamicItemsListGrid<T>();
- customiseGrid?.Invoke(grid);
- return grid.EditItems(new T[] { item }, PageDataHandler: pageDataHandler, PreloadPages: preloadPages);
- }
- /// <summary>
- /// Edit (using a grid sourced with <see cref="CreateDynamicGrid{T}(Type)"/>) a <typeparamref name="T"/>.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="item"></param>
- /// <param name="pageDataHandler"></param>
- /// <param name="preloadPages"></param>
- /// <param name="customiseGrid"></param>
- /// <returns></returns>
- public static bool EditEntity<T>(T item, Func<Type, CoreTable?>? pageDataHandler = null, bool preloadPages = false, Action<DynamicGrid<T>>? customiseGrid = null)
- where T : Entity, new()
- {
- var grid = CreateDynamicGrid<T>(typeof(DynamicGrid<>));
- customiseGrid?.Invoke(grid);
- return grid.EditItems(new T[] { item }, PageDataHandler: pageDataHandler, PreloadPages: preloadPages);
- }
- /// <summary>
- /// Edit (using a grid sourced with <see cref="CreateDynamicGrid{T}(Type)"/>) a list of <typeparamref name="T"/>.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="item"></param>
- /// <param name="pageDataHandler"></param>
- /// <param name="preloadPages"></param>
- /// <param name="customiseGrid"></param>
- /// <returns></returns>
- public static bool EditEntities<T>(T[] items, Func<Type, CoreTable?>? pageDataHandler = null, bool preloadPages = false, Action<DynamicGrid<T>>? customiseGrid = null)
- where T : Entity, new()
- {
- var grid = CreateDynamicGrid<T>(typeof(DynamicGrid<>));
- customiseGrid?.Invoke(grid);
- return grid.EditItems(items, PageDataHandler: pageDataHandler, PreloadPages: preloadPages);
- }
- #endregion
- #region Drag + Drop
- public static string DragFormat => typeof(DynamicGridDragFormat).FullName ?? "";
- /// <summary>
- /// Try to get data dragged from a <see cref="DynamicGrid{T}"/> from a <see cref="DragEventArgs"/>, returning <see langword="true"/>
- /// if data was present.
- /// </summary>
- /// <param name="e"></param>
- public static bool TryGetDropData(
- DragEventArgs e,
- [NotNullWhen(true)] out Type? type,
- [NotNullWhen(true)] out CoreTable? table)
- {
- if (e.Data.GetDataPresent(DragFormat))
- {
- var data = e.Data.GetData(DragFormat) as DynamicGridDragFormat;
- if (data is not null)
- {
- table = new CoreTable();
- foreach (var column in data.Table.Columns)
- {
- if (column is DataColumn dataColumn)
- {
- table.Columns.Add(new CoreColumn { ColumnName = dataColumn.ColumnName.Replace('_', '.'), DataType = dataColumn.DataType });
- }
- }
- foreach (var row in data.Table.Rows)
- {
- if (row is DataRow dataRow)
- {
- var coreRow = table.NewRow();
- coreRow.LoadValues(dataRow.ItemArray);
- table.Rows.Add(coreRow);
- }
- }
- type = data.Entity;
- return true;
- }
- }
- table = null;
- type = null;
- return false;
- }
- #endregion
- #region Style
-
- public static Brush SelectionBackground { get; set; } = new SolidColorBrush(Colors.Black);
- public static Brush SelectionForeground { get; set; } = new SolidColorBrush(Colors.Silver);
- public static Brush FilterBackground { get; set; } = new SolidColorBrush(System.Windows.Media.Color.FromArgb(0xFF, 0xE9, 0xF7, 0xC9));
- #endregion
- public static void PopulateFormMenu<TEntityForm, TEntity, TEntityLink>(
- ItemsControl menu,
- Guid entityID,
- Func<TEntity> loadEntity,
- bool editOnAdd = false,
- DynamicFormEditWindow.CustomiseDynamicFormEditWindow? customiseEditor = null)
- where TEntityForm : EntityForm<TEntity, TEntityLink, TEntityForm>, new()
- where TEntity : Entity
- where TEntityLink : IEntityLink<TEntity>, new()
- {
- var task = Task.Run(() =>
- {
- return new Client<TEntityForm>().Query(
- new Filter<TEntityForm>(x => x.Parent.ID).IsEqualTo(entityID),
- null).Rows.Select(x => x.ToObject<TEntityForm>()).ToList();
- });
- var addForm = new MenuItem { Header = "Add Form" };
- addForm.Click += (o, e) =>
- {
- var entity = loadEntity();
- var filter = LookupFactory.DefineChildFilter<TEntity, DigitalForm>(new TEntity[] { entity })
- ?? LookupFactory.DefineLookupFilter<TEntityForm, DigitalForm, DigitalFormLink>(x => x.Form, Array.Empty<TEntityForm>());
- var select = new MultiSelectDialog<DigitalForm>(
- filter,
- LookupFactory.DefineLookupColumns<TEntityForm, DigitalForm, DigitalFormLink>(x => x.Form).Add(x => x.Description),
- false);
- if(select.ShowDialog() == true)
- {
- var digitalForm = select.Data().Rows.FirstOrDefault()?.ToObject<DigitalForm>();
- if(digitalForm is not null)
- {
- var form = new TEntityForm
- {
- Description = digitalForm.Description
- };
- form.Parent.ID = entityID;
- form.Form.ID = digitalForm.ID;
- if (editOnAdd)
- {
- if (DynamicFormEditWindow.EditDigitalForm(form, out var dataModel, customise: customiseEditor))
- {
- dataModel.Update(null);
- }
- }
- else
- {
- new Client<TEntityForm>().Save(form, "Added by user");
- }
- }
- };
- };
- var manageForms = new MenuItem { Header = "Manage Forms..." };
- manageForms.Click += (o, e) =>
- {
- var window = new ThemableWindow() { Title = $"Manage {typeof(TEntity).Name} Forms" };
- var grid = new DynamicEntityFormGrid<TEntityForm, TEntity, TEntityLink>(loadEntity());
- grid.Refresh(true, true);
- grid.Margin = new Thickness(5);
- window.Content = grid;
- window.ShowDialog();
- };
- menu.Items.Add(addForm);
- menu.Items.Add(new Separator());
- menu.Items.Add(new MenuItem() { Header = "Loading...", IsEnabled = false });
- menu.Items.Add(new Separator());
- menu.Items.Add(manageForms);
- task.ContinueWith((task) =>
- {
- var entityForms = task.Result;
- menu.Items.Clear();
- menu.Items.Add(addForm);
- menu.Items.Add(new Separator());
- if (entityForms.Any())
- {
- foreach (var entityForm in entityForms)
- {
- var description = entityForm.Description;
- if (string.IsNullOrWhiteSpace(description))
- {
- description = entityForm.Form.Description;
- }
- var formItem = new MenuItem { Header = $"{entityForm.Number} : {description}" };
- formItem.Click += (o, e) =>
- {
- if (DynamicFormEditWindow.EditDigitalForm(entityForm, out var dataModel, customise: customiseEditor))
- {
- dataModel.Update(null);
- }
- };
- menu.Items.Add(formItem);
- }
- }
- else
- {
- menu.Items.Add(new MenuItem() { Header = "No Forms", IsEnabled = false });
- }
- menu.Items.Add(new Separator());
- menu.Items.Add(manageForms);
- }, TaskScheduler.FromCurrentSynchronizationContext());
- }
- }
|