Explorar el Código

Implemented DynamicEditorGrid.AfterEditorValueChanged and supporting code changes
Added option to Dimensions.CopyFrom to enable or disable observing as required

Frank van den Bos hace 2 años
padre
commit
b197e826bc

+ 78 - 0
InABox.Core/CoreUtils.cs

@@ -2446,5 +2446,83 @@ namespace InABox.Core
             );
         }
         #endregion
+        
+        /// <summary>
+        /// Get a dictionary of values representing the current state of an entity
+        /// </summary>
+        /// <param name="item">The Entity being scanned</param>
+        /// <param name="props">The list of properties to scan, or null for all</param>
+        /// <returns>A dictionary containing the properties and values for the entity</returns>
+        public static Dictionary<string, object?> GetValues(BaseObject item, IEnumerable<IProperty>? props = null)
+        {
+            var result = new Dictionary<string, object?>();
+            props ??= DatabaseSchema.Properties(item.GetType()).Where(x => !(x.Editor is NullEditor));
+            foreach (var prop in props)
+                if (prop is CustomProperty)
+                    try
+                    {
+                        result[prop.Name] = item.UserProperties[prop.Name];
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+                    }
+                else
+                    try
+                    {
+                        object? value;
+                        var getter = prop.Getter();
+                        if (getter != null)
+                            value = getter.Invoke(item);
+                        else
+                            value = CoreUtils.GetPropertyValue(item, prop.Name);
+                        result[prop.Name] = value;
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
+                    }
+
+            return result;
+        }
+        
+        /// <summary>
+        /// Given a certain entity, merge the changes with the current state of the entity into an updated list
+        /// </summary>
+        /// <param name="item">Th Entity being updated</param>
+        /// <param name="previous">The previous set of changes to this entity</param>
+        /// <param name="props">The list of properties to scan, or null for all</param>
+        /// <param name="changes">The resulting updated list of changes</param>
+        public static void MergeChanges(Dictionary<string, object?> previous, Dictionary<string, object?> current, Dictionary<string, object?> changes)
+        {
+            foreach (var key in previous.Keys)
+                if (previous[key] == null)
+                {
+                    if (current[key] != null)
+                        changes[key] = current[key];
+                }
+                else
+                {
+                    if (current[key] == null)
+                        changes[key] = current[key];
+                    else if (!object.Equals(previous[key], current[key]))
+                        changes[key] = current[key];
+                }
+        }
+
+        public static Dictionary<String, object?> MonitorChanges<T>(T item, Action action, Dictionary<String, object?>? changes = null, IEnumerable<IProperty>? props = null) where T : BaseObject
+        {
+            var result = changes == null
+                ? new Dictionary<String, object?>()
+                : changes;
+            var previous = GetValues(item, props);
+            action.Invoke();
+            var current = GetValues(item, props);
+            MergeChanges(previous, current, result);
+            return result;
+        }
+        
+        
+        
     }
 }

+ 3 - 0
InABox.Core/Dimensions/DimensionUnitLink.cs

@@ -5,6 +5,9 @@ namespace InABox.Core
     public abstract class DimensionUnitLink<T> : EntityLink<T>, IDimensionUnit where T : DimensionUnit, new()
     {
         
+        [RequiredColumn]
+        public override Guid ID { get; set; }
+        
         [EditorSequence(1)]
         [CodeEditor(Visible = Visible.Default, Editable = Editable.Hidden)]
         public string Code { get; set; }

+ 5 - 3
InABox.Core/Dimensions/Dimensions.cs

@@ -187,9 +187,10 @@ namespace InABox.Core
             return true;
         }
 
-        public void CopyFrom(IDimensions source)
+        public void CopyFrom(IDimensions source, bool observing = false)
         {
-            SetObserving(false);
+            if (!observing)
+                SetObserving(false);
             Unit.ID = source.GetUnit().ID;
             Unit.Synchronise(source.GetUnit());
             Quantity = source.Quantity;
@@ -199,7 +200,8 @@ namespace InABox.Core
             Weight = source.Weight;
             Value = source.Value;
             UnitSize = source.UnitSize;
-            SetObserving(true);
+            if (!observing)
+                SetObserving(true);
         }
     }
 }

+ 2 - 2
InABox.Core/Dimensions/IDimensions.cs

@@ -13,7 +13,7 @@ namespace InABox.Core
         double Value { get; set; }
         String UnitSize { get; set; }
 
-        public void Set(IDimensionUnit unit, double quantity, double length, double width, double height, double weight);
-        void CopyFrom(IDimensions source);
+        void Set(IDimensionUnit unit, double quantity, double length, double width, double height, double weight);
+        void CopyFrom(IDimensions source, bool observing = false);
     }
 }

+ 6 - 2
InABox.DynamicGrid/DynamicEditorForm.xaml.cs

@@ -123,8 +123,10 @@ namespace InABox.DynamicGrid
             };
 
             //Editor.OnGetPropertyInfo += (o, c) => { return CoreUtils.GetProperty(_item.GetType(), c); };
+            
+            Editor.OnAfterEditorValueChanged += (g,n) => { return OnAfterEditorValueChanged?.Invoke(g, n); };
 
-            Editor.ReconfigureEditors += g => { ReconfigureEditors?.Invoke(g); };
+            Editor.OnReconfigureEditors += g => { OnReconfigureEditors?.Invoke(g); };
 
             Editor.OnGetEditor += c =>
             {
@@ -327,7 +329,9 @@ namespace InABox.DynamicGrid
 
         public event OnFormCustomiseEditor? OnFormCustomiseEditor;
 
-        public event OnReconfigureEditors? ReconfigureEditors;
+        public event OnAfterEditorValueChanged? OnAfterEditorValueChanged;
+        
+        public event OnReconfigureEditors? OnReconfigureEditors;
 
         //public delegate void EditorValueChangedHandler(object sender, String name, object value, List<String> changes);
         //public event EditorValueChangedHandler OnEditorValueChanged;

+ 24 - 13
InABox.DynamicGrid/DynamicEditorGrid.xaml.cs

@@ -140,8 +140,10 @@ namespace InABox.DynamicGrid
 
         public event EditorValueChangedHandler? OnEditorValueChanged;
 
-        public event OnReconfigureEditors? ReconfigureEditors;
+        public event OnAfterEditorValueChanged? OnAfterEditorValueChanged;
 
+        public event OnReconfigureEditors? OnReconfigureEditors;
+        
         public event OnDefineFilter? OnDefineFilter;
 
         public event OnDefineLookup? OnDefineLookups;
@@ -162,7 +164,7 @@ namespace InABox.DynamicGrid
 
             AddPages();
 
-            DoReconfigureEditors();
+            ReconfigureEditors();
 
             //MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
             //MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
@@ -842,7 +844,7 @@ namespace InABox.DynamicGrid
                     ConfigureEditors();
                     LoadEditorValues();
                     AddPages();
-                    DoReconfigureEditors();
+                    ReconfigureEditors();
                 }, DispatcherPriority.Render);
             }
         }
@@ -856,7 +858,7 @@ namespace InABox.DynamicGrid
             CreateLayout();
             LoadEditorValues();
             AddPages();
-            DoReconfigureEditors();
+            ReconfigureEditors();
         }
 
         private void LoadEditor(string columnname, object value)
@@ -865,22 +867,31 @@ namespace InABox.DynamicGrid
 
         private void EditorValueChanged(IDynamicEditorControl sender, Dictionary<string, object> values)
         {
-            //Logger.Send(LogType.Information, "", string.Format("DynamicEditorGrid.EditorValueChanged({0})", values.Keys.Count));
             var changededitors = new Dictionary<string, object?>();
+
+            void ExtractChanged(Dictionary<String, object?>? columns)
+            {
+                if (columns != null)
+                    foreach (var (change, value) in columns)
+                        if (editors.Any(x => x.ColumnName.Equals(change)) && !changededitors.ContainsKey(change) && !change.Equals(sender.ColumnName))
+                            changededitors[change] = value;                
+            }
+            
             foreach (var key in values.Keys)
             {
                 var changedcolumns = OnEditorValueChanged?.Invoke(this, key, values[key]);
-                if (changedcolumns != null)
-                    foreach (var (change, value) in changedcolumns)
-                        if (editors.Any(x => x.ColumnName.Equals(change)) && !changededitors.ContainsKey(change) && !change.Equals(sender.ColumnName))
-                            changededitors[change] = value;
+                ExtractChanged(changedcolumns);
             }
 
+            var afterchanged = OnAfterEditorValueChanged?.Invoke(this, sender.ColumnName);
+            ExtractChanged(afterchanged);
+            
             if (changededitors.Any())
                 LoadEditorValues(changededitors);
-            DoReconfigureEditors();
+            
+            ReconfigureEditors();
         }
-
+        
         private void LoadEditorValues(Dictionary<string, object?>? changededitors = null)
         {
             var columnnames = changededitors != null ? changededitors.Keys.ToArray() : editors.Select(x => x.ColumnName).ToArray();
@@ -919,9 +930,9 @@ namespace InABox.DynamicGrid
             }
         }
 
-        public virtual void DoReconfigureEditors()
+        public virtual void ReconfigureEditors()
         {
-            ReconfigureEditors?.Invoke(this);
+            OnReconfigureEditors?.Invoke(this);
         }
 
         public void Load(string layoutname, DynamicEditorPages? pages = null)

+ 15 - 1
InABox.DynamicGrid/DynamicGrid.cs

@@ -45,6 +45,7 @@ using Point = System.Windows.Point;
 using Resources = InABox.DynamicGrid.Properties.Resources;
 using RowColumnIndex = Syncfusion.UI.Xaml.ScrollAxis.RowColumnIndex;
 using SolidColorBrush = System.Windows.Media.SolidColorBrush;
+using String = System.String;
 using Transform = System.Windows.Media.Transform;
 using VirtualizingCellsControl = Syncfusion.UI.Xaml.Grid.VirtualizingCellsControl;
 
@@ -2435,7 +2436,9 @@ namespace InABox.DynamicGrid
 
             editor.OnEditorValueChanged += (s, n, v) => { return EditorValueChanged(editor, items, n, v); };
 
-            editor.ReconfigureEditors += g => { ReconfigureEditors(g, items); };
+            editor.OnAfterEditorValueChanged += (g, n) => { return AfterEditorValueChanged(g, items, n); }; 
+            
+            editor.OnReconfigureEditors += g => { ReconfigureEditors(g, items); };
 
             editor.OnValidateData += (o, i) => { return ValidateData(items); };
 
@@ -2492,6 +2495,17 @@ namespace InABox.DynamicGrid
             }
         }
 
+        private Dictionary<String, object?> AfterEditorValueChanged(DynamicEditorGrid grid, T[] items, String columnnname)
+        {
+            var changes = new Dictionary<String, object?>();
+            OnAfterEditorValueChanged(grid, items, columnnname, changes);
+            return changes;
+        }
+
+        protected virtual void OnAfterEditorValueChanged(DynamicEditorGrid grid, T[] items, String columnnname, Dictionary<String,object?> changes)
+        {
+        }
+
         protected virtual void ReconfigureEditors(DynamicEditorGrid grid, T[] items)
         {
             if (items.First() is IDimensioned dimensioned)

+ 3 - 0
InABox.DynamicGrid/DynamicGridCommon.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.ComponentModel;
 using InABox.Core;
 
@@ -51,6 +52,8 @@ namespace InABox.DynamicGrid
     public delegate void OnCustomiseEditor<T>(IDynamicEditorForm sender, T[]? items, DynamicGridColumn column, BaseEditor editor);
 
     public delegate void OnReconfigureEditors(DynamicEditorGrid sender);
+    
+    public delegate Dictionary<String,object?>? OnAfterEditorValueChanged(DynamicEditorGrid sender, String columnname);
 
     public delegate void OnGridChanged(IDynamicGrid sender);
 

+ 7 - 51
InABox.DynamicGrid/DynamicGridUtils.cs

@@ -357,50 +357,19 @@ namespace InABox.DynamicGrid
 
         #region Editor Values
 
-        public static Dictionary<string, object?> GetValues(BaseObject item, string name, IEnumerable<IProperty>? props = null)
-        {
-            var result = new Dictionary<string, object?>();
-            props ??= DatabaseSchema.Properties(item.GetType()).Where(x => x.Editor is not NullEditor);
-            foreach (var prop in props)
-                if (prop is CustomProperty)
-                    try
-                    {
-                        result[prop.Name] = item.UserProperties[prop.Name];
-                    }
-                    catch (Exception e)
-                    {
-                        Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-                    }
-                else
-                    try
-                    {
-                        object? value;
-                        var getter = prop.Getter();
-                        if (getter != null)
-                            value = getter.Invoke(item);
-                        else
-                            value = CoreUtils.GetPropertyValue(item, prop.Name);
-                        result[prop.Name] = value;
-                    }
-                    catch (Exception e)
-                    {
-                        Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-                    }
-
-            return result;
-        }
+        
 
         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()).Where(x => x.Editor is not NullEditor);
+            var changes = new Dictionary<String, object?>(); 
+            var props = DatabaseSchema.Properties(items.First().GetType()).Where(x => x.Editor is not NullEditor).ToArray();
             foreach (var item in items)
             {
                 //Dictionary<String, object> previous = new Dictionary<string, object>();
-                var previous = GetValues(item, name, props);
+                var previous = CoreUtils.GetValues(item, props);
 
                 //if (item.OriginalValues != null)
                 //{
@@ -437,24 +406,11 @@ namespace InABox.DynamicGrid
                                 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);
 
-                var current = GetValues(item, name, props);
-
-                foreach (var key in previous.Keys)
-                    if (previous[key] == null)
-                    {
-                        if (current[key] != null)
-                            changes[key] = current[key];
-                    }
-                    else
-                    {
-                        if (current[key] == null)
-                            changes[key] = current[key];
-                        else if (!object.Equals(previous[key], current[key]))
-                            changes[key] = current[key];
-                    }
             }
-
+            
             return changes;
         }