소스 검색

Merge remote-tracking branch 'origin/frank' into kenric

Kenric Nugteren 7 달 전
부모
커밋
57d979f32d

+ 16 - 5
inabox.database.sqlite/SQLiteProvider.cs

@@ -1531,7 +1531,7 @@ public class SQLiteProvider : IProvider
     public object? Decode(object o, Type type)
     {
         if (IsNull(o))
-            return type == typeof(string) ? "" : type.GetDefault();
+            return type == typeof(string) ? ""  : type.GetDefault();
 
         if (type == typeof(string[]))
         {
@@ -1652,15 +1652,24 @@ public class SQLiteProvider : IProvider
         if (type == typeof(Guid) && o.GetType() == typeof(string))
             o = Guid.Parse(o.ToString() ?? "");
 
-        if (o is string[])
-            using (var ms = new MemoryStream())
+        if (o is string[] sArray)
+        {
+
+            if (sArray.Length > 0 && !String.IsNullOrWhiteSpace(sArray[0]))
             {
+
+                using (var ms = new MemoryStream())
+                {
 #pragma warning disable SYSLIB0011
-                new BinaryFormatter().Serialize(ms, o);
+                    new BinaryFormatter().Serialize(ms, sArray);
 #pragma warning restore SYSLIB0011
-                return ms.GetBuffer();
+                    return ms.GetBuffer();
+                }
             }
 
+            return DBNull.Value;
+        }
+
         if (o is IPackable pack)
         {
             using var ms = new MemoryStream();
@@ -1709,6 +1718,8 @@ public class SQLiteProvider : IProvider
         if (o.GetType().IsEnum)
             return o.ToString() ?? "";
 
+
+
         return o;
     }
 

+ 3 - 0
inabox.wpf/DynamicGrid/Columns/DynamicActionColumn.cs

@@ -26,6 +26,9 @@ namespace InABox.DynamicGrid
         public string[]? ExcludeFilters { get; set; }
         public string[]? SelectedFilters { get; set; }
         public string[]? Filters { get; set; } = null;
+
+        public Func<DynamicActionColumn, string>? GetFilterExpression = null;
+        
         public Func<CoreRow, string[], bool>? FilterRecord { get; set; } = null;
 
         public Func<CoreRow[]?, ContextMenu?>? ContextMenu { get; set; }

+ 14 - 6
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -543,8 +543,11 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         
         OnRowsDragStart(rows);
     }
+    
+    public void UIFilterChanged(object sender) => DoFilterChanged();
+    
 
-    void IDynamicGridUIComponentParent<T>.UIFilterChanged(object sender) => DoFilterChanged();
+    //void IDynamicGridUIComponentParent<T>.UIFilterChanged(object sender) => DoFilterChanged();
 
     protected virtual void DoFilterChanged()
     {
@@ -1056,7 +1059,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         var result = OnDefineFilter.Invoke(typeof(T)) as Filter<T>;
         return result;
     }
-
+    
     protected virtual bool FilterRecord(CoreRow row)
     {
         var bOK = ActionColumns.All(x =>
@@ -1580,10 +1583,10 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     {
         InitialiseEditorForm(editor, items.Cast<T>().ToArray(), pageDataHandler, preloadPages);
     }
-    public virtual bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
+    public virtual bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null)
     {
         var values = items.Cast<T>().ToArray();
-        return EditItems(values, PageDataHandler, PreloadPages);
+        return EditItems(values, PageDataHandler, PreloadPages, parent);
     }
 
     public virtual void InitialiseEditorForm(IDynamicEditorForm editor, T[] items, Func<Type, CoreTable?>? pageDataHandler = null, bool preloadPages = false)
@@ -1742,12 +1745,17 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     /// </summary>
     /// <param name="items">List of objects to edit.</param>
     /// <returns><see langword="true"/> if the items were saved.</returns>
-    public virtual bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
+    public virtual bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null)
     {
+        var owner = Window.GetWindow(parent ?? this);
         DynamicEditorForm editor;
         using (var cursor = new WaitCursor())
         {
-            editor = new DynamicEditorForm();
+            editor = new DynamicEditorForm()
+            {
+                WindowStartupLocation = WindowStartupLocation.CenterOwner, 
+                Owner = owner
+            };
             editor.SetValue(Panel.ZIndexProperty, 999);
 
             InitialiseEditorForm(editor, items, PageDataHandler, PreloadPages);

+ 2 - 0
inabox.wpf/DynamicGrid/DynamicGridCommon.cs

@@ -4,6 +4,7 @@ using System.ComponentModel;
 using System.Windows.Controls;
 using InABox.Core;
 using InABox.Wpf;
+using Syncfusion.Data;
 
 namespace InABox.DynamicGrid;
 
@@ -18,6 +19,7 @@ public abstract class DynamicColumnBase : BaseObject, IDynamicColumnBase
     public event DynamicColumnEntityChangedEvent? EntityChanged;
     
     public object? Tag { get; set; }
+    
 }
 
 public enum DynamicGridOption

+ 2 - 2
inabox.wpf/DynamicGrid/IDynamicGrid.cs

@@ -50,7 +50,7 @@ public interface IDynamicGrid
     void DoChanged();
 
     void InitialiseEditorForm(IDynamicEditorForm editor, object[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false);
-    bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false);
+    bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null);
 
     //bool DirectEdit(CoreTable data);
 
@@ -120,5 +120,5 @@ public interface IDynamicGrid<T> : IDynamicGrid
 
     void DeleteItems(CoreRow[] rows);
 
-    bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false);
+    bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null);
 }

+ 32 - 34
inabox.wpf/DynamicGrid/UIComponent/DynamicGridGridUIComponent.cs

@@ -46,8 +46,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
     where T : BaseObject, new()
 {
     private readonly Dictionary<string, string> _filterpredicates = new();
-
-
+    
     private Dictionary<string, CoreTable> Lookups = new();
 
     private IDynamicGridUIComponentParent<T> _parent;
@@ -194,6 +193,8 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         
         DataGrid.SetValue(ScrollViewer.VerticalScrollBarVisibilityProperty, ScrollBarVisibility.Visible);
         
+        DataGrid.FilterChanging += DataGrid_FilterChanging;
+        
         DataGrid.FilterChanged += DataGrid_FilterChanged;
 
         DataGrid.FilterItemsPopulating += DataGrid_FilterItemsPopulating;
@@ -214,6 +215,8 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         //DataGrid.CellRenderers.Add("TextBox", new CustomTextCellRenderer(this));
     }
 
+
+
     public class GridSelectionControllerExt(SfDataGrid datagrid, DynamicGridGridUIComponent<T> grid) : GridSelectionController(datagrid)
     {
         private DynamicGridGridUIComponent<T> Grid = grid;
@@ -573,43 +576,27 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
         return reloadColumns && DataGrid.Columns.Count > 0;
     }
-
+    
+    private void DataGrid_FilterChanging(object? sender, GridFilterEventArgs e)
+    {
+        
+        var col = GetColumn(DataGrid.Columns.IndexOf(e.Column)) as DynamicActionColumn;
+        if (col?.GetFilterExpression != null)
+        {
+            col.SetFilters(e.FilterPredicates);
+            var view = (DataGrid.ItemsSource as DataTable)?.DefaultView;
+            view.ApplyFilters(ColumnList.OfType<DynamicActionColumn>());
+            e.Handled = true;
+        }
+        
+    }
+    
     private void DataGrid_FilterChanged(object? o, GridFilterEventArgs e)
     {
         var col = DataGrid.Columns.IndexOf(e.Column);
         if (GetColumn(col) is DynamicActionColumn column)
         {
-            if (e.FilterPredicates != null)
-            {
-                var filter = e.FilterPredicates.Select(x => x.FilterValue.ToString()!).ToArray();
-                var include = e.FilterPredicates.Any(x => x.FilterType == FilterType.Equals);
-                if (include)
-                {
-                    column.SelectedFilters = filter;
-                    column.ExcludeFilters = null;
-                }
-                else if(column.Filters is not null)
-                {
-                    column.SelectedFilters = column.Filters.Except(filter).ToArray();
-                    column.ExcludeFilters = null;
-                }
-                else
-                {
-                    column.SelectedFilters = null;
-                    column.ExcludeFilters = filter;
-                }
-            }
-            else
-            {
-                column.SelectedFilters = null;
-                column.ExcludeFilters = null;
-            }
-            //DataGrid.ClearFilter(e.Column);
-
-            //e.FilterPredicates?.Clear();
-            //e.FilterPredicates?.Add(new FilterPredicate() { PredicateType = PredicateType.Or, FilterBehavior = Syncfusion.Data.FilterBehavior.StringTyped, FilterMode = ColumnFilter.DisplayText, FilterType = Syncfusion.Data.FilterType.NotEquals, FilterValue = "" });
-            //e.FilterPredicates?.Add(new FilterPredicate() { PredicateType = PredicateType.Or, FilterBehavior = Syncfusion.Data.FilterBehavior.StringTyped, FilterMode = ColumnFilter.DisplayText, FilterType = Syncfusion.Data.FilterType.Equals, FilterValue = "" });
-            //Parent.Refresh(false, false);
+            column.SetFilters(e.FilterPredicates);
             e.Handled = true;
         }
 
@@ -627,6 +614,8 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         UpdateRecordCount();
     }
 
+    
+
     private void UpdateRecordCount()
     {
         var count = DataGrid.View != null ? DataGrid.View.Records.Count : Parent.Data.Rows.Count;
@@ -1326,6 +1315,9 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
     public void RefreshColumns(IEnumerable<DynamicColumnBase> columns, DynamicGridColumnGroupings groupings)
     {
+        if (DataGrid.View != null)
+            DataGrid.View.Filter = null;
+        
         DataGrid.ItemsSource = null;
         DataGrid.Columns.Suspend();
 
@@ -1379,6 +1371,12 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
             // Stock Forecast grid.
             RefreshData(new CoreTable());
         }
+
+        if (DataGrid.View != null)
+            DataGrid.View.Filter = (o) =>
+            {
+                return true;
+            };
     }
 
     #endregion

+ 19 - 27
inabox.wpf/DynamicGrid/UIComponent/DynamicGridTreeUIComponent.cs

@@ -10,6 +10,7 @@ using Syncfusion.UI.Xaml.TreeGrid.Helpers;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Data;
 using System.Linq;
 using System.Linq.Expressions;
 using System.Text;
@@ -233,7 +234,8 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         filterstyle.Setters.Add(new Setter(TreeGridFilterControl.SortOptionVisibilityProperty, Visibility.Collapsed));
         filterstyle.Setters.Add(new Setter(TreeGridFilterControl.ImmediateUpdateColumnFilterProperty, false));
         _tree.FilterPopupStyle = filterstyle;
-        
+
+        _tree.FilterChanging += _tree_FilterChanging;
         _tree.FilterChanged += _tree_FilterChanged;
         _tree.FilterItemsPopulating += _tree_FilterItemsPopulating;
         _tree.FilterLevel = FilterLevel.Extended;
@@ -270,6 +272,8 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         _tree.SizeChanged += _tree_SizeChanged;
     }
 
+
+
     private void _tree_Loaded(object sender, RoutedEventArgs e)
     {
         Application.Current.Dispatcher.BeginInvoke(() =>
@@ -536,38 +540,26 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
             }
         }
     }
+    
+    private void _tree_FilterChanging(object? sender, TreeGridFilterChangingEventArgs e)
+    {
+        var col = GetColumn(_tree.Columns.IndexOf(e.Column)) as DynamicActionColumn;
+        if (col?.GetFilterExpression != null)
+        {
+            col.SetFilters(e.FilterPredicates);
+            var view = (_tree.ItemsSource as DataTable)?.DefaultView;
+            view.ApplyFilters(ColumnList.OfType<DynamicActionColumn>());
+            e.Handled = true;
+        }
+    }
 
-    private void _tree_FilterChanged(object? sender, Syncfusion.UI.Xaml.TreeGrid.Filtering.TreeGridFilterChangedEventArgs e)
+    private void _tree_FilterChanged(object? sender, TreeGridFilterChangedEventArgs e)
     {
         var col = _tree.Columns.IndexOf(e.Column);
         if (GetColumn(col) is DynamicActionColumn column)
         {
-            if (e.FilterPredicates != null)
-            {
-                var filter = e.FilterPredicates.Select(x => x.FilterValue.ToString()!).ToArray();
-                var include = e.FilterPredicates.Any(x => x.FilterType == FilterType.Equals);
-                if (include)
-                {
-                    column.SelectedFilters = filter;
-                    column.ExcludeFilters = null;
-                }
-                else if(column.Filters is not null)
-                {
-                    column.SelectedFilters = column.Filters.Except(filter).ToArray();
-                    column.ExcludeFilters = null;
-                }
-                else
-                {
-                    column.SelectedFilters = null;
-                    column.ExcludeFilters = filter;
-                }
-            }
-            else
-                column.SelectedFilters = Array.Empty<string>();
+            column.SetFilters(e.FilterPredicates);
             _tree.ClearFilter(e.Column);
-            //e.FilterPredicates?.Clear();
-            //e.FilterPredicates?.Add(new FilterPredicate() { PredicateType = PredicateType.Or, FilterBehavior = Syncfusion.Data.FilterBehavior.StringTyped, FilterMode = ColumnFilter.DisplayText, FilterType = Syncfusion.Data.FilterType.NotEquals, FilterValue = "" });
-            //e.FilterPredicates?.Add(new FilterPredicate() { PredicateType = PredicateType.Or, FilterBehavior = Syncfusion.Data.FilterBehavior.StringTyped, FilterMode = ColumnFilter.DisplayText, FilterType = Syncfusion.Data.FilterType.Equals, FilterValue = "" });
             Parent.Refresh(false, false);
         }
 

+ 4 - 3
inabox.wpf/DynamicGrid/UIComponent/IDynamicGridUIComponent.cs

@@ -3,7 +3,6 @@ using Syncfusion.Data;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
-using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
@@ -44,7 +43,7 @@ public interface IDynamicGridUIComponentParent<T> : IDynamicGrid<T>
     void DragOver(object sender, DragEventArgs e);
     void Drop(object sender, DragEventArgs e);
     void DragStart(object? sender, CoreRow[] rows);
-
+    
     void UIFilterChanged(object sender);
     IEnumerable<string>? GetColumnFilterItems(DynamicColumnBase column);
 }
@@ -83,4 +82,6 @@ public interface IDynamicGridUIComponent<T>
 
     void ScrollIntoView(CoreRow row);
     CoreRow[] GetVisibleRows();
-}
+    
+
+}

+ 80 - 0
inabox.wpf/DynamicGrid/UIComponent/IDynamicGridUIComponentExtensions.cs

@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using Syncfusion.Data;
+
+namespace InABox.DynamicGrid;
+
+public static class IDynamicGridUIComponentExtensions
+{
+    public static string CreateFilterExpression(this DynamicActionColumn column, string propertyName)
+    {
+        List<string> criteria = new();
+        
+        var sel = column.SelectedFilters ?? [];
+        var exc = column.ExcludeFilters ?? [];
+
+        if (sel.Any())
+        {
+            var sels = String.Join(", ",sel.Select(x => $"'{x}'"));
+            criteria.Add($"{propertyName} IN ({sels})");
+        }
+        
+        if (exc.Any())
+        {
+            var excs = String.Join(", ",exc.Select(x => $"'{x}'"));
+            criteria.Add($"{propertyName} NOT IN ({excs})");
+        }
+    
+        if (criteria.Any())
+            return $"{string.Join(" AND ", criteria)}";
+
+        return "true";
+    }
+    
+    public static void SetFilters(this DynamicActionColumn column, IEnumerable<FilterPredicate>? predicates)
+    {
+        if (predicates != null)
+        {
+            var filter = predicates.Select(x => x.FilterValue.ToString()!).ToArray();
+            var include = predicates.Any(x => x.FilterType == FilterType.Equals);
+            if (include)
+            {
+                column.SelectedFilters = filter;
+                column.ExcludeFilters = null;
+            }
+            else if(column.Filters is not null)
+            {
+                column.SelectedFilters = column.Filters.Except(filter).ToArray();
+                column.ExcludeFilters = null;
+            }
+            else
+            {
+                column.SelectedFilters = null;
+                column.ExcludeFilters = filter;
+            }
+        }
+        else
+        {
+            column.SelectedFilters = null;
+            column.ExcludeFilters = null;
+        }
+    }
+    
+    public static void ApplyFilters(this DataView? view, IEnumerable<DynamicActionColumn> columns)
+    {
+        List<String> criteria = new();
+        foreach (var column in columns)
+            criteria.Add(column.GetFilterExpression?.Invoke(column) ?? "");
+        var filter = string.Join(" AND ", criteria.Where(x => !string.IsNullOrWhiteSpace(x)));
+        if (view != null)
+        {
+            view.RowStateFilter = DataViewRowState.CurrentRows;
+            view.RowFilter = filter;
+            if (view.Count == 0)
+                view.RowStateFilter = DataViewRowState.None;
+        }
+    }
+    
+}