|
@@ -15,669 +15,668 @@ using Syncfusion.Data.Extensions;
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
using System.Data;
|
|
|
|
|
|
-namespace InABox.DynamicGrid
|
|
|
+namespace InABox.DynamicGrid;
|
|
|
+
|
|
|
+[Caption("Set Default Column Selections")]
|
|
|
+public class CanSetDefaultColumns : EnabledSecurityDescriptor<CoreLicense>
|
|
|
{
|
|
|
- [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;
|
|
|
+[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>? _allo2mtypes;
|
|
|
+ private static IEnumerable<Type>? _allo2mpages;
|
|
|
|
|
|
- private static IEnumerable<Type>? _allcepages;
|
|
|
+ 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();
|
|
|
+ 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; }
|
|
|
+ // 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 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));
|
|
|
- // }
|
|
|
-
|
|
|
- }
|
|
|
+ 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
|
|
|
+ #region Pages
|
|
|
|
|
|
- public static IEnumerable<Type> GetManyToManyTypes(Type type)
|
|
|
- {
|
|
|
- _allm2mtypes ??= CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- x => x.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>))
|
|
|
- );
|
|
|
- return _allm2mtypes.Where(x => x.GetInterfaces().Any(
|
|
|
- i => i.IsGenericType
|
|
|
- && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>)
|
|
|
- && i.GenericTypeArguments[0] == type)
|
|
|
- );
|
|
|
- }
|
|
|
+ public static IEnumerable<Type> GetManyToManyTypes(Type type)
|
|
|
+ {
|
|
|
+ _allm2mtypes ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x => x.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IManyToMany<,>))
|
|
|
+ );
|
|
|
+ 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)
|
|
|
+ public static void LoadManyToManyPages(Type type, DynamicEditorPages pages)
|
|
|
+ {
|
|
|
+ if (!_manytomanytomanypages.TryGetValue(type, out var pageTypes))
|
|
|
{
|
|
|
- if (!_manytomanytomanypages.TryGetValue(type, out var pageTypes))
|
|
|
- {
|
|
|
- pageTypes = new List<Type>();
|
|
|
+ pageTypes = new List<Type>();
|
|
|
|
|
|
- var maps = GetManyToManyTypes(type);
|
|
|
+ var maps = GetManyToManyTypes(type);
|
|
|
|
|
|
- foreach (var map in maps)
|
|
|
+ foreach (var map in maps)
|
|
|
+ {
|
|
|
+ if (ClientFactory.IsSupported(map))
|
|
|
{
|
|
|
- if (ClientFactory.IsSupported(map))
|
|
|
- {
|
|
|
- _allm2mpages ??= CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- x => x.IsClass
|
|
|
- && !x.IsAbstract
|
|
|
- && !x.IsGenericType
|
|
|
- && x.GetInterfaces().Any(
|
|
|
- i => i.IsGenericType
|
|
|
- && i.GetGenericTypeDefinition() == typeof(IDynamicManyToManyGrid<,>)
|
|
|
- )
|
|
|
- );
|
|
|
-
|
|
|
- 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))
|
|
|
+ _allm2mpages ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x => x.IsClass
|
|
|
+ && !x.IsAbstract
|
|
|
+ && !x.IsGenericType
|
|
|
+ && x.GetInterfaces().Any(
|
|
|
+ i => i.IsGenericType
|
|
|
+ && i.GetGenericTypeDefinition() == typeof(IDynamicManyToManyGrid<,>)
|
|
|
+ )
|
|
|
);
|
|
|
|
|
|
- if (subtypes.Any())
|
|
|
- {
|
|
|
- pageTypes.Add(subtypes.First());
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- pageTypes.Add(typeof(DynamicManyToManyGrid<,>).MakeGenericType(map, type));
|
|
|
- }
|
|
|
- }
|
|
|
+ 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)!));
|
|
|
+ _manytomanytomanypages[type] = pageTypes.ToArray();
|
|
|
}
|
|
|
+ pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x) as IDynamicEditorPage)!));
|
|
|
+ }
|
|
|
|
|
|
- public static IEnumerable<Type> GetOneToManyTypes(Type type)
|
|
|
- {
|
|
|
- _allo2mtypes ??= CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- x => x.GetInterfaces().Any(i =>
|
|
|
- i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IOneToMany<>) && x.GetCustomAttribute<ObsoleteAttribute>() == null)
|
|
|
- );
|
|
|
- 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)
|
|
|
+ public static IEnumerable<Type> GetOneToManyTypes(Type type)
|
|
|
+ {
|
|
|
+ _allo2mtypes ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x => x.GetInterfaces().Any(i =>
|
|
|
+ i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IOneToMany<>) && x.GetCustomAttribute<ObsoleteAttribute>() == null)
|
|
|
+ );
|
|
|
+ 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))
|
|
|
{
|
|
|
- if (!_onetomanypages.TryGetValue(type, out var pageTypes))
|
|
|
- {
|
|
|
- pageTypes = new List<Type>();
|
|
|
+ pageTypes = new List<Type>();
|
|
|
|
|
|
- var maps = GetOneToManyTypes(type);
|
|
|
+ var maps = GetOneToManyTypes(type);
|
|
|
|
|
|
- foreach (var map in maps)
|
|
|
+ foreach (var map in maps)
|
|
|
+ {
|
|
|
+ if (ClientFactory.IsSupported(map))
|
|
|
{
|
|
|
- if (ClientFactory.IsSupported(map))
|
|
|
- {
|
|
|
|
|
|
- _allo2mpages ??= CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- x =>
|
|
|
- x.IsClass
|
|
|
- && !x.IsAbstract
|
|
|
- && !x.IsGenericType
|
|
|
- && x.GetInterfaces().Any(i =>
|
|
|
- i.IsGenericType
|
|
|
- && i.GetGenericTypeDefinition() == typeof(IDynamicOneToManyGrid<,>)
|
|
|
- )
|
|
|
- );
|
|
|
-
|
|
|
- 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)
|
|
|
- )
|
|
|
+ _allo2mpages ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x =>
|
|
|
+ x.IsClass
|
|
|
+ && !x.IsAbstract
|
|
|
+ && !x.IsGenericType
|
|
|
+ && x.GetInterfaces().Any(i =>
|
|
|
+ i.IsGenericType
|
|
|
+ && i.GetGenericTypeDefinition() == typeof(IDynamicOneToManyGrid<,>)
|
|
|
+ )
|
|
|
);
|
|
|
|
|
|
- if (subtypes.Any())
|
|
|
- {
|
|
|
- pageTypes.Add(subtypes.First());
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- pageTypes.Add(typeof(DynamicOneToManyGrid<,>).MakeGenericType(type, map));
|
|
|
- }
|
|
|
+ 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)!));
|
|
|
+
|
|
|
+ _onetomanypages[type] = pageTypes.ToArray();
|
|
|
}
|
|
|
+ pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x) as IDynamicEditorPage)!));
|
|
|
+ }
|
|
|
|
|
|
- public static void LoadCustomEditorPages(Type type, DynamicEditorPages pages)
|
|
|
+ public static void LoadCustomEditorPages(Type type, DynamicEditorPages pages)
|
|
|
+ {
|
|
|
+ if (!_customeditorpages.TryGetValue(type, out var pageTypes))
|
|
|
{
|
|
|
- if (!_customeditorpages.TryGetValue(type, out var pageTypes))
|
|
|
- {
|
|
|
- _allcepages ??= CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- x => x.IsClass
|
|
|
- && !x.IsAbstract
|
|
|
- && !x.IsGenericType
|
|
|
- && x.GetInterfaces().Any(i =>
|
|
|
- i.IsGenericType
|
|
|
- && i.GetGenericTypeDefinition() == typeof(IDynamicCustomEditorPage<>)
|
|
|
- )
|
|
|
- );
|
|
|
-
|
|
|
- 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)!));
|
|
|
+ _allcepages ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x => x.IsClass
|
|
|
+ && !x.IsAbstract
|
|
|
+ && !x.IsGenericType
|
|
|
+ && x.GetInterfaces().Any(i =>
|
|
|
+ i.IsGenericType
|
|
|
+ && i.GetGenericTypeDefinition() == typeof(IDynamicCustomEditorPage<>)
|
|
|
+ )
|
|
|
+ );
|
|
|
+
|
|
|
+ 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)
|
|
|
+ public static void LoadEnclosedListPages(Type type, DynamicEditorPages pages)
|
|
|
+ {
|
|
|
+ if (!_enclosedlistpages.TryGetValue(type, out var pageTypes))
|
|
|
{
|
|
|
- if (!_enclosedlistpages.TryGetValue(type, out var pageTypes))
|
|
|
+ pageTypes = new List<Tuple<Type, PropertyInfo>>();
|
|
|
+ foreach (var property in type.GetProperties())
|
|
|
{
|
|
|
- pageTypes = new List<Tuple<Type, PropertyInfo>>();
|
|
|
- foreach (var property in type.GetProperties())
|
|
|
+ if (property.PropertyType.GetInterfaces().Contains(typeof(IList)))
|
|
|
{
|
|
|
- if (property.PropertyType.GetInterfaces().Contains(typeof(IList)))
|
|
|
+ var curtype = property.PropertyType;
|
|
|
+ var gentype = property.PropertyType.GetGenericArguments().FirstOrDefault();
|
|
|
+ while (gentype == null && curtype?.BaseType != null)
|
|
|
{
|
|
|
- var curtype = property.PropertyType;
|
|
|
- var gentype = property.PropertyType.GetGenericArguments().FirstOrDefault();
|
|
|
- while (gentype == null && curtype?.BaseType != null)
|
|
|
- {
|
|
|
- curtype = curtype.BaseType;
|
|
|
- gentype = curtype?.GetGenericArguments().FirstOrDefault();
|
|
|
- }
|
|
|
+ curtype = curtype.BaseType;
|
|
|
+ gentype = curtype?.GetGenericArguments().FirstOrDefault();
|
|
|
+ }
|
|
|
|
|
|
- if (gentype != null)
|
|
|
- if (gentype.IsSubclassOf(typeof(BaseObject)))
|
|
|
+ if (gentype != null)
|
|
|
+ if (gentype.IsSubclassOf(typeof(BaseObject)))
|
|
|
+ {
|
|
|
+ var editor = property.GetCustomAttributes().FirstOrDefault(x => x is BaseEditor);
|
|
|
+ if (editor == null || !(editor is NullEditor))
|
|
|
{
|
|
|
- var editor = property.GetCustomAttributes().FirstOrDefault(x => x is BaseEditor);
|
|
|
- if (editor == null || !(editor is NullEditor))
|
|
|
- {
|
|
|
- _alleltypes ??= CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- x => x.IsClass
|
|
|
- && !x.IsAbstract
|
|
|
- && !x.IsGenericType
|
|
|
- && x.GetInterfaces().Any(i =>
|
|
|
- i.IsGenericType
|
|
|
- && i.GetGenericTypeDefinition() == typeof(IDynamicEnclosedListGrid<,>)
|
|
|
- )
|
|
|
- );
|
|
|
-
|
|
|
- var subtypes = _alleltypes.Where(
|
|
|
- x => x.GetInterfaces().Any(
|
|
|
- i => i.IsGenericType
|
|
|
+ _alleltypes ??= CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ x => x.IsClass
|
|
|
+ && !x.IsAbstract
|
|
|
+ && !x.IsGenericType
|
|
|
+ && x.GetInterfaces().Any(i =>
|
|
|
+ i.IsGenericType
|
|
|
&& i.GetGenericTypeDefinition() == typeof(IDynamicEnclosedListGrid<,>)
|
|
|
- && i.GenericTypeArguments.First().Equals(type)
|
|
|
- && i.GenericTypeArguments.Last().Equals(gentype)
|
|
|
- )
|
|
|
+ )
|
|
|
);
|
|
|
|
|
|
+ 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.Last().Equals(gentype)));
|
|
|
+
|
|
|
if (subtypes.Any())
|
|
|
{
|
|
|
- pageTypes.Add(new(subtypes.First(), property));
|
|
|
+ pageTypes.Add(new(subtypes.First().MakeGenericType(type), property));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- subtypes = _alleltypes.Where(x => x.GetInterfaces().Any(i => i.GenericTypeArguments.Last().Equals(gentype)));
|
|
|
-
|
|
|
- if (subtypes.Any())
|
|
|
+ try
|
|
|
{
|
|
|
- pageTypes.Add(new(subtypes.First().MakeGenericType(type), property));
|
|
|
+ pageTypes.Add(new(typeof(DynamicEnclosedListGrid<,>).MakeGenericType(type, gentype), property));
|
|
|
}
|
|
|
- else
|
|
|
+ catch (Exception e)
|
|
|
{
|
|
|
- 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));
|
|
|
- }
|
|
|
+ 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)!));
|
|
|
+
|
|
|
+ _enclosedlistpages[type] = pageTypes.ToArray();
|
|
|
}
|
|
|
+ pages.AddRange(pageTypes.Select(x => (Activator.CreateInstance(x.Item1, x.Item2) as IDynamicEditorPage)!));
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
+ #endregion
|
|
|
|
|
|
- #region Columns
|
|
|
+ #region Columns
|
|
|
|
|
|
- public static Columns<T> LoadEditorColumns<T>(Columns<T> additional)
|
|
|
- {
|
|
|
- var result = new Columns<T>().Default(
|
|
|
- ColumnType.IncludeOptional,
|
|
|
- ColumnType.IncludeForeignKeys,
|
|
|
- ColumnType.IncludeUserProperties,
|
|
|
- ColumnType.IncludeEditable);
|
|
|
+ public static Columns<T> LoadEditorColumns<T>(Columns<T> additional)
|
|
|
+ {
|
|
|
+ var result = new Columns<T>().Default(
|
|
|
+ ColumnType.IncludeOptional,
|
|
|
+ ColumnType.IncludeForeignKeys,
|
|
|
+ ColumnType.IncludeUserProperties,
|
|
|
+ ColumnType.IncludeEditable);
|
|
|
|
|
|
- foreach (var col in additional.Items)
|
|
|
- if (!result.Items.Any(x => string.Equals(x.Property, col.Property)))
|
|
|
- result.Add(col.Property);
|
|
|
+ foreach (var col in additional.Items)
|
|
|
+ if (!result.Items.Any(x => string.Equals(x.Property, col.Property)))
|
|
|
+ result.Add(col.Property);
|
|
|
|
|
|
- foreach (var col in result.Items)
|
|
|
+ foreach (var col in result.Items)
|
|
|
+ {
|
|
|
+ var prop = DatabaseSchema.Property(typeof(T), col.Property);
|
|
|
+ if (prop?.Editor is DataLookupEditor dataLookup)
|
|
|
{
|
|
|
- var prop = DatabaseSchema.Property(typeof(T), col.Property);
|
|
|
- if (prop?.Editor is DataLookupEditor dataLookup)
|
|
|
+ foreach (var lookupColumn in LookupFactory.DefineFilterColumns<T>(dataLookup.Type).ColumnNames())
|
|
|
{
|
|
|
- foreach (var lookupColumn in LookupFactory.DefineFilterColumns<T>(dataLookup.Type).ColumnNames())
|
|
|
- {
|
|
|
- result.Add(lookupColumn);
|
|
|
- }
|
|
|
+ result.Add(lookupColumn);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- return result;
|
|
|
}
|
|
|
|
|
|
- #endregion
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- #region Editor Values
|
|
|
+ #endregion
|
|
|
|
|
|
- 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();
|
|
|
+ #region Editor Values
|
|
|
|
|
|
- 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);
|
|
|
+ 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();
|
|
|
|
|
|
- //if (item.OriginalValues != null)
|
|
|
- //{
|
|
|
- // foreach (var key in item.OriginalValues.Keys)
|
|
|
- // previous[key] = item.OriginalValues[key];
|
|
|
- //}
|
|
|
+ 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);
|
|
|
|
|
|
- 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);
|
|
|
+ //if (item.OriginalValues != null)
|
|
|
+ //{
|
|
|
+ // foreach (var key in item.OriginalValues.Keys)
|
|
|
+ // previous[key] = item.OriginalValues[key];
|
|
|
+ //}
|
|
|
|
|
|
- item.OnPropertyChanged(name, oldvalue, value);
|
|
|
+ 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);
|
|
|
|
|
|
- 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);
|
|
|
+ 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));
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- return changes;
|
|
|
- }
|
|
|
+ var current = CoreUtils.GetValues(item, props);
|
|
|
+ CoreUtils.MergeChanges(previous, current, 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];
|
|
|
}
|
|
|
+
|
|
|
+ return changes;
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
+ 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];
|
|
|
+ }
|
|
|
|
|
|
- #region Dynamic Grid Creation
|
|
|
+ #endregion
|
|
|
|
|
|
- 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));
|
|
|
- }
|
|
|
+ #region Dynamic Grid Creation
|
|
|
|
|
|
- private static Dictionary<Type, Type[]> _dynamicGrids = new();
|
|
|
+ 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 bool TryFindDynamicGrid(Type gridType, Type entityType, [NotNullWhen(true)] out Type? grid)
|
|
|
- {
|
|
|
- if (!_dynamicGrids.TryGetValue(gridType, out var grids))
|
|
|
- {
|
|
|
- grids = CoreUtils.TypeList(
|
|
|
- AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
- myType =>
|
|
|
- myType.IsClass
|
|
|
- && !myType.IsAbstract
|
|
|
- && !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(BaseDynamicGrid<>));
|
|
|
- return baseGrid?.GenericTypeArguments[0] == entityType;
|
|
|
- }).ToList();
|
|
|
+ private static Dictionary<Type, Type[]> _dynamicGrids = new();
|
|
|
|
|
|
- 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 bool TryFindDynamicGrid(Type gridType, Type entityType, [NotNullWhen(true)] out Type? grid)
|
|
|
+ {
|
|
|
+ if (!_dynamicGrids.TryGetValue(gridType, out var grids))
|
|
|
+ {
|
|
|
+ grids = CoreUtils.TypeList(
|
|
|
+ AppDomain.CurrentDomain.GetAssemblies(),
|
|
|
+ myType =>
|
|
|
+ myType.IsClass
|
|
|
+ && !myType.IsAbstract
|
|
|
+ && !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(BaseDynamicGrid<>));
|
|
|
+ return baseGrid?.GenericTypeArguments[0] == entityType;
|
|
|
+ }).ToList();
|
|
|
|
|
|
- public static Type FindDynamicGrid(Type gridType, Type entityType)
|
|
|
+ var defaults = entityGrids.Where(x => x.IsAssignableTo(typeof(IDefaultGrid))).ToList();
|
|
|
+ if (defaults.Count > 0)
|
|
|
{
|
|
|
- if(TryFindDynamicGrid(gridType, entityType, out var grid))
|
|
|
+ if (defaults.Count > 1)
|
|
|
{
|
|
|
- return grid;
|
|
|
+ Logger.Send(LogType.Information, ClientFactory.UserID, $"Error: {defaults.Count} IDefaultGrid derivations for {gridType.Name} of {entityType.Name}");
|
|
|
}
|
|
|
- return gridType.MakeGenericType(entityType);
|
|
|
+ grid = defaults.First();
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- public static Window CreateGridWindow(string title, BaseDynamicGrid dynamicGrid)
|
|
|
+ grid = entityGrids.FirstOrDefault();
|
|
|
+ return grid is not null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Type FindDynamicGrid(Type gridType, Type entityType)
|
|
|
+ {
|
|
|
+ if(TryFindDynamicGrid(gridType, entityType, out var grid))
|
|
|
{
|
|
|
- dynamicGrid.Margin = new Thickness(5);
|
|
|
+ return grid;
|
|
|
+ }
|
|
|
+ return gridType.MakeGenericType(entityType);
|
|
|
+ }
|
|
|
|
|
|
- var window = new ThemableWindow { Title = title, Content = dynamicGrid };
|
|
|
+ public static Window CreateGridWindow(string title, BaseDynamicGrid dynamicGrid)
|
|
|
+ {
|
|
|
+ dynamicGrid.Margin = new Thickness(5);
|
|
|
|
|
|
- (dynamicGrid as IDynamicGrid)!.Refresh(true, true);
|
|
|
+ var window = new ThemableWindow { Title = title, Content = dynamicGrid };
|
|
|
|
|
|
- return window;
|
|
|
- }
|
|
|
- public static Window CreateGridWindow(string title, Type entityType, Type? gridType = null)
|
|
|
- {
|
|
|
- gridType ??= typeof(DynamicGrid<>);
|
|
|
- var grid = CreateDynamicGrid(gridType, entityType) as BaseDynamicGrid;
|
|
|
- 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));
|
|
|
- }
|
|
|
+ (dynamicGrid as IDynamicGrid)!.Refresh(true, true);
|
|
|
+
|
|
|
+ return window;
|
|
|
+ }
|
|
|
+ public static Window CreateGridWindow(string title, Type entityType, Type? gridType = null)
|
|
|
+ {
|
|
|
+ gridType ??= typeof(DynamicGrid<>);
|
|
|
+ var grid = CreateDynamicGrid(gridType, entityType) as BaseDynamicGrid;
|
|
|
+ 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
|
|
|
+ #endregion
|
|
|
|
|
|
- #region Drag + Drop
|
|
|
+ #region Drag + Drop
|
|
|
|
|
|
- public static string DragFormat => typeof(DynamicGridDragFormat).FullName ?? "";
|
|
|
+ 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)
|
|
|
+ /// <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))
|
|
|
{
|
|
|
- if (e.Data.GetDataPresent(DragFormat))
|
|
|
+ var data = e.Data.GetData(DragFormat) as DynamicGridDragFormat;
|
|
|
+ if (data is not null)
|
|
|
{
|
|
|
- var data = e.Data.GetData(DragFormat) as DynamicGridDragFormat;
|
|
|
- if (data is not null)
|
|
|
+ table = new CoreTable();
|
|
|
+ foreach (var column in data.Table.Columns)
|
|
|
{
|
|
|
- table = new CoreTable();
|
|
|
- foreach (var column in data.Table.Columns)
|
|
|
+ if (column is DataColumn dataColumn)
|
|
|
{
|
|
|
- if (column is DataColumn dataColumn)
|
|
|
- {
|
|
|
- table.Columns.Add(new CoreColumn { ColumnName = dataColumn.ColumnName.Replace('_', '.'), DataType = dataColumn.DataType });
|
|
|
- }
|
|
|
+ table.Columns.Add(new CoreColumn { ColumnName = dataColumn.ColumnName.Replace('_', '.'), DataType = dataColumn.DataType });
|
|
|
}
|
|
|
- foreach (var row in data.Table.Rows)
|
|
|
+ }
|
|
|
+ foreach (var row in data.Table.Rows)
|
|
|
+ {
|
|
|
+ if (row is DataRow dataRow)
|
|
|
{
|
|
|
- if (row is DataRow dataRow)
|
|
|
- {
|
|
|
- var coreRow = table.NewRow();
|
|
|
- coreRow.LoadValues(dataRow.ItemArray);
|
|
|
- table.Rows.Add(coreRow);
|
|
|
- }
|
|
|
+ var coreRow = table.NewRow();
|
|
|
+ coreRow.LoadValues(dataRow.ItemArray);
|
|
|
+ table.Rows.Add(coreRow);
|
|
|
}
|
|
|
-
|
|
|
- type = data.Entity;
|
|
|
- return true;
|
|
|
}
|
|
|
+
|
|
|
+ type = data.Entity;
|
|
|
+ return true;
|
|
|
}
|
|
|
- table = null;
|
|
|
- type = null;
|
|
|
- return false;
|
|
|
}
|
|
|
+ table = null;
|
|
|
+ type = null;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
-
|
|
|
- public static void PopulateFormMenu<TEntityForm, TEntity, TEntityLink>(
|
|
|
- ItemsControl menu,
|
|
|
- Guid entityID,
|
|
|
- Func<TEntity> loadEntity,
|
|
|
- bool editOnAdd = false
|
|
|
- )
|
|
|
- where TEntityForm : EntityForm<TEntity, TEntityLink, TEntityForm>, new()
|
|
|
- where TEntity : Entity
|
|
|
- where TEntityLink : IEntityLink<TEntity>, new()
|
|
|
+ #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(() =>
|
|
|
{
|
|
|
- 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();
|
|
|
- });
|
|
|
+ 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 addForm = new MenuItem { Header = "Add Form" };
|
|
|
+ addForm.Click += (o, e) =>
|
|
|
+ {
|
|
|
+ var entity = loadEntity();
|
|
|
+ var filter = LookupFactory.DefineFilter<TEntity, DigitalForm>(new TEntity[] { entity })
|
|
|
+ ?? LookupFactory.DefineFilter<TEntityForm, DigitalForm>(Array.Empty<TEntityForm>());
|
|
|
+
|
|
|
+ var select = new MultiSelectDialog<DigitalForm>(
|
|
|
+ filter,
|
|
|
+ LookupFactory.DefineColumns<DigitalForm>()
|
|
|
+ .Add(x => x.Description),
|
|
|
+ false);
|
|
|
+ if(select.ShowDialog() == true)
|
|
|
{
|
|
|
- var entity = loadEntity();
|
|
|
- var filter = LookupFactory.DefineFilter<TEntity, DigitalForm>(new TEntity[] { entity })
|
|
|
- ?? LookupFactory.DefineFilter<TEntityForm, DigitalForm>(Array.Empty<TEntityForm>());
|
|
|
-
|
|
|
- var select = new MultiSelectDialog<DigitalForm>(
|
|
|
- filter,
|
|
|
- LookupFactory.DefineColumns<DigitalForm>()
|
|
|
- .Add(x => x.Description),
|
|
|
- false);
|
|
|
- if(select.ShowDialog() == true)
|
|
|
- {
|
|
|
- var digitalForm = select.Data().Rows.FirstOrDefault()?.ToObject<DigitalForm>();
|
|
|
+ var digitalForm = select.Data().Rows.FirstOrDefault()?.ToObject<DigitalForm>();
|
|
|
|
|
|
- if(digitalForm is not null)
|
|
|
+ if(digitalForm is not null)
|
|
|
+ {
|
|
|
+ var form = new TEntityForm
|
|
|
{
|
|
|
- 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))
|
|
|
- {
|
|
|
- dataModel.Update(null);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
+ Description = digitalForm.Description
|
|
|
+ };
|
|
|
+ form.Parent.ID = entityID;
|
|
|
+ form.Form.ID = digitalForm.ID;
|
|
|
+ if (editOnAdd)
|
|
|
+ {
|
|
|
+ if (DynamicFormEditWindow.EditDigitalForm(form, out var dataModel, customise: customiseEditor))
|
|
|
{
|
|
|
- new Client<TEntityForm>().Save(form, "Added by user");
|
|
|
+ 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 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());
|
|
|
+ var grid = new DynamicEntityFormGrid<TEntityForm, TEntity, TEntityLink>(loadEntity());
|
|
|
|
|
|
- grid.Refresh(true, true);
|
|
|
- grid.Margin = new Thickness(5);
|
|
|
+ grid.Refresh(true, true);
|
|
|
+ grid.Margin = new Thickness(5);
|
|
|
|
|
|
- window.Content = grid;
|
|
|
+ window.Content = grid;
|
|
|
|
|
|
- window.ShowDialog();
|
|
|
- };
|
|
|
+ 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());
|
|
|
- menu.Items.Add(new MenuItem() { Header = "Loading...", IsEnabled = false });
|
|
|
- menu.Items.Add(new Separator());
|
|
|
- menu.Items.Add(manageForms);
|
|
|
|
|
|
- task.ContinueWith((task) =>
|
|
|
+ if (entityForms.Any())
|
|
|
{
|
|
|
- var entityForms = task.Result;
|
|
|
- menu.Items.Clear();
|
|
|
- menu.Items.Add(addForm);
|
|
|
- menu.Items.Add(new Separator());
|
|
|
-
|
|
|
- if (entityForms.Any())
|
|
|
+ foreach (var entityForm in entityForms)
|
|
|
{
|
|
|
- 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) =>
|
|
|
{
|
|
|
- var description = entityForm.Description;
|
|
|
- if (string.IsNullOrWhiteSpace(description))
|
|
|
+ if (DynamicFormEditWindow.EditDigitalForm(entityForm, out var dataModel, customise: customiseEditor))
|
|
|
{
|
|
|
- description = entityForm.Form.Description;
|
|
|
+ dataModel.Update(null);
|
|
|
}
|
|
|
- var formItem = new MenuItem { Header = $"{entityForm.Number} : {description}" };
|
|
|
- formItem.Click += (o, e) =>
|
|
|
- {
|
|
|
- if (DynamicFormEditWindow.EditDigitalForm(entityForm, out var dataModel))
|
|
|
- {
|
|
|
- dataModel.Update(null);
|
|
|
- }
|
|
|
- };
|
|
|
+ };
|
|
|
|
|
|
- menu.Items.Add(formItem);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- menu.Items.Add(new MenuItem() { Header = "No Forms", IsEnabled = false });
|
|
|
+ menu.Items.Add(formItem);
|
|
|
}
|
|
|
- menu.Items.Add(new Separator());
|
|
|
- menu.Items.Add(manageForms);
|
|
|
- }, TaskScheduler.FromCurrentSynchronizationContext());
|
|
|
- }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ menu.Items.Add(new MenuItem() { Header = "No Forms", IsEnabled = false });
|
|
|
+ }
|
|
|
+ menu.Items.Add(new Separator());
|
|
|
+ menu.Items.Add(manageForms);
|
|
|
+ }, TaskScheduler.FromCurrentSynchronizationContext());
|
|
|
}
|
|
|
}
|