Преглед на файлове

wpf: Improvements to DynamicGrid filtering and row indexing

Kenric Nugteren преди 1 месец
родител
ревизия
830676a42b

+ 0 - 69
inabox.wpf/DynamicGrid/DynamicGridStyle.cs

@@ -315,73 +315,4 @@ public class DynamicGridCellStyleParameters
     }
 }
 
-public class DynamicGridGridCellStyleConverter<T> : IValueConverter
-{
-
-    private readonly IBaseDynamicGrid _grid;
-    
-    private readonly Func<CoreRow, DynamicColumnBase, T> _converter;
-    
-    public DynamicGridGridCellStyleConverter(IBaseDynamicGrid grid, Func<CoreRow, DynamicColumnBase, T> converter)
-    {
-        _grid = grid ?? throw new ArgumentNullException(nameof(grid));
-        _converter = converter ?? throw new ArgumentNullException(nameof(converter));
-    }
-
-    private CoreRow? GetRow(object item)
-    {
-        try
-        {
-            if (item is DataRowView row)
-            {
-                var index = row.Row.Table.Rows.IndexOf(row.Row);
-                return _grid.GetVisibleRow(index);
-                
-                //return _grid.Data.Rows[index];
-
-                // var map = _rowMap.FirstOrDefault(x => x.Value.Index == row.Index);
-                // if (!Equals(map,default(KeyValuePair<DataRow,CoreRow>)))
-                // {
-                //     //var datarow = table.Rows[row.Index];
-                //     for (var i = 0; i < rowdata.Count; i++)
-                //         map.Key[i] = rowdata[i] ?? DBNull.Value;
-                // }
-                // else
-                // {
-                //
-                // }
-
-
-
-            }
-            return null;
-        }
-        catch
-        {
-            return null;
-        }
-    }
-    
-    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
-    {
-        var row = GetRow(value);
-        if (row == null)
-            return DependencyProperty.UnsetValue;
-
-        var param = parameter as DynamicGridCellStyleParameters;
-        if (param == null)
-            return DependencyProperty.UnsetValue;
-        
-        //var column = parameter as DynamicColumnBase;
-        //if (column is null)
-        //    return DependencyProperty.UnsetValue;
-        
-        return _converter.Invoke(row,param.Column) ?? param.DefaultValue;
-    }
-    
-    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
-    {
-        throw new NotSupportedException();
-    }
-}
 

+ 0 - 2
inabox.wpf/DynamicGrid/Grids/BaseDynamicGrid.cs

@@ -379,8 +379,6 @@ public abstract class BaseDynamicGrid : ContentControl, IDynamicGridUIComponentP
     {
     }
 
-    public CoreRow GetVisibleRow(int index) => UIComponent.GetVisibleRow(index);
-
     #region IDynamicGridUIComponentParent
 
     protected virtual IDynamicGridUIComponent CreateUIComponent()

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

@@ -98,8 +98,6 @@ public interface IBaseDynamicGrid
     object? GetData(CoreRow row, DynamicColumnBase column);
 
     IDynamicGridColumnFilter? GetColumnFilter(DynamicColumnBase column);
-
-    CoreRow GetVisibleRow(int index);
 }
 
 public interface IDynamicGrid : IBaseDynamicGrid

+ 74 - 54
inabox.wpf/DynamicGrid/UIComponent/DynamicGridGridUIComponent.cs

@@ -58,11 +58,11 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
         {
             _parent = value;
 
-            CellBackgroundConverter = new DynamicGridGridCellStyleConverter<System.Windows.Media.Brush?>(Parent, GetCellBackground);
-            CellForegroundConverter = new DynamicGridGridCellStyleConverter<System.Windows.Media.Brush?>(Parent, GetCellForeground);
-            CellFontSizeConverter = new DynamicGridGridCellStyleConverter<double?>(Parent, GetCellFontSize);
-            CellFontStyleConverter = new DynamicGridGridCellStyleConverter<System.Windows.FontStyle?>(Parent, GetCellFontStyle);
-            CellFontWeightConverter = new DynamicGridGridCellStyleConverter<System.Windows.FontWeight?>(Parent, GetCellFontWeight);
+            CellBackgroundConverter = new CellStyleConverter<System.Windows.Media.Brush?>(this, GetCellBackground);
+            CellForegroundConverter = new CellStyleConverter<System.Windows.Media.Brush?>(this, GetCellForeground);
+            CellFontSizeConverter = new CellStyleConverter<double?>(this, GetCellFontSize);
+            CellFontStyleConverter = new CellStyleConverter<System.Windows.FontStyle?>(this, GetCellFontStyle);
+            CellFontWeightConverter = new CellStyleConverter<System.Windows.FontWeight?>(this, GetCellFontWeight);
 
             DataGrid.RowStyleSelector = Parent.RowStyleSelector;
             DataGrid.TableSummaryRowStyleSelector = new SummaryRowStyleSelector(GetSummaryRowStyle);
@@ -273,8 +273,6 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
 
         return result.ToArray();
     }
-
-    public CoreRow GetVisibleRow(int index) => _rowMap.Values.ToArray()[index];
     
     private void SetSelectedRows(CoreRow[] rows)
     {           
@@ -283,7 +281,6 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
         var table = DataGridItems;
         if(table is null) return;
 
-
         var dataRows = rows.Select(x => _rowMap.FirstOrDefault(y => x == y.Value).Key);
         if (!Parent.Options.MultiSelect)
         {
@@ -689,11 +686,56 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
 
     #region Styles
 
-    private DynamicGridGridCellStyleConverter<System.Windows.Media.Brush?> CellBackgroundConverter = null!;
-    private DynamicGridGridCellStyleConverter<System.Windows.Media.Brush?> CellForegroundConverter = null!;
-    private DynamicGridGridCellStyleConverter<double?> CellFontSizeConverter = null!;
-    private DynamicGridGridCellStyleConverter<System.Windows.FontStyle?> CellFontStyleConverter = null!;
-    private DynamicGridGridCellStyleConverter<System.Windows.FontWeight?> CellFontWeightConverter = null!;
+    private class CellStyleConverter<TValue>(DynamicGridGridUIComponent component, Func<CoreRow, DynamicColumnBase, TValue> converter) : IValueConverter
+    {
+        private readonly DynamicGridGridUIComponent _component = component ?? throw new ArgumentNullException(nameof(component));
+        
+        private readonly Func<CoreRow, DynamicColumnBase, TValue> _converter = converter ?? throw new ArgumentNullException(nameof(converter));
+
+        private CoreRow? GetRow(object item)
+        {
+            try
+            {
+                if (item is DataRowView row)
+                {
+                    return component.GetRow(row.Row);
+                }
+                return null;
+            }
+            catch
+            {
+                return null;
+            }
+        }
+        
+        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            var row = GetRow(value);
+            if (row == null)
+                return DependencyProperty.UnsetValue;
+
+            var param = parameter as DynamicGridCellStyleParameters;
+            if (param == null)
+                return DependencyProperty.UnsetValue;
+            
+            //var column = parameter as DynamicColumnBase;
+            //if (column is null)
+            //    return DependencyProperty.UnsetValue;
+            
+            return _converter.Invoke(row,param.Column) ?? param.DefaultValue;
+        }
+        
+        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
+        {
+            throw new NotSupportedException();
+        }
+    }
+
+    private CellStyleConverter<System.Windows.Media.Brush?> CellBackgroundConverter = null!;
+    private CellStyleConverter<System.Windows.Media.Brush?> CellForegroundConverter = null!;
+    private CellStyleConverter<double?> CellFontSizeConverter = null!;
+    private CellStyleConverter<System.Windows.FontStyle?> CellFontStyleConverter = null!;
+    private CellStyleConverter<System.Windows.FontWeight?> CellFontWeightConverter = null!;
 
     protected virtual Brush? GetCellSelectionForegroundBrush() => DynamicGridUtils.SelectionForeground;
     protected virtual Brush? GetCellSelectionBackgroundBrush() => DynamicGridUtils.SelectionBackground;
@@ -1502,22 +1544,6 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
     {
         AddRows(page, false);
     }
-
-    // public CoreRow DataRowIndexToCoreRow(int index)
-    // {
-    //     var map = _rowMap.FirstOrDefault(x => x.Value.Index == row.Index);
-    //     if (!Equals(map,default(KeyValuePair<DataRow,CoreRow>)))
-    //     {
-    //         //var datarow = table.Rows[row.Index];
-    //         for (var i = 0; i < rowdata.Count; i++)
-    //             map.Key[i] = rowdata[i] ?? DBNull.Value;
-    //     }
-    //     else
-    //     {
-    //         
-    //     }
-    //
-    // }
     
     public void InvalidateRow(CoreRow row)
     {
@@ -1533,17 +1559,13 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
         foreach (var ac in ActionColumns)
             rowdata.Add(ac.Data(row));
 
-
-        var map = _rowMap.FirstOrDefault(x => x.Value.Index == row.Index);
-        if (!Equals(map,default(KeyValuePair<DataRow,CoreRow>)))
-        {
-            //var datarow = table.Rows[row.Index];
-            for (var i = 0; i < rowdata.Count; i++)
-                map.Key[i] = rowdata[i] ?? DBNull.Value;
-        }
-        else
+        var dataRow = GetDataRow(row);
+        if(dataRow is not null)
         {
-            
+            for(var i = 0; i < rowdata.Count; ++i)
+            {
+                dataRow[i] = rowdata[i] ?? DBNull.Value;
+            }
         }
 
         _invalidating = false;
@@ -1605,7 +1627,7 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
 
     protected DirectEditingObject EnsureEditingObject(CoreRow row)
     {
-        _editingObject ??= new(GetEditingObject(row), row, DataGridItems?.Rows[row.Index]);
+        _editingObject ??= new(GetEditingObject(row), row, GetDataRow(row));
         return _editingObject;
     }
 
@@ -1616,7 +1638,14 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
 
     private DataRow? GetDataRow(CoreRow row)
     {
-        return DataGridItems?.Rows[row.Index];
+        foreach(var (key, value) in _rowMap)
+        {
+            if(value == row)
+            {
+                return key;
+            }
+        }
+        return null;
     }
 
     void IDynamicGridUIComponent.UpdateCell(CoreRow row, string column, object? value)
@@ -1701,12 +1730,8 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
         Parent.UpdateData(coreRow, column, updates);
     }
 
-    private void UpdateData(int rowIndex, int columnIndex)
+    private void UpdateData(DataRow row, int columnIndex)
     {
-        var table = DataGridItems;
-        if (table is null)
-            return;
-        
         if (GetColumn(columnIndex) is DynamicGridColumn gridcol)
         {
             var datacol = Parent.Data.Columns.FirstOrDefault(x => x.ColumnName.Equals(gridcol.ColumnName));
@@ -1714,7 +1739,7 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
             {
                 var datacolindex = Parent.Data.Columns.IndexOf(datacol);
 
-                var value = table.Rows[rowIndex][datacolindex];
+                var value = row[datacolindex];
                 if (value is DBNull)
                     value = CoreUtils.GetDefault(datacol.DataType);
 
@@ -1752,9 +1777,9 @@ public class DynamicGridGridUIComponent : IDynamicGridUIComponent, IDynamicGridG
 
     private void DataGrid_CurrentCellEndEdit(object? sender, CurrentCellEndEditEventArgs e)
     {
-        if (_editingObject is not null && bChanged)
+        if (_editingObject is not null && bChanged && _editingObject.DataRow is not null)
         {
-            UpdateData(_editingObject.Row.Index, e.RowColumnIndex.ColumnIndex);
+            UpdateData(_editingObject.DataRow, e.RowColumnIndex.ColumnIndex);
         }
         if (bChanged)
             Parent.DoChanged();
@@ -1953,11 +1978,6 @@ public class DynamicGridGridUIComponent<T> : DynamicGridGridUIComponent, IDynami
         return Parent.LoadItem(row);
     }
 
-    private DataRow? GetDataRow(CoreRow row)
-    {
-        return DataGridItems?.Rows[row.Index];
-    }
-
     protected override void DoEntityChanged(IDynamicColumnBase column, DynamicColumnEntityChangedEventArgs args)
     {
         base.DoEntityChanged(column, args);

+ 25 - 15
inabox.wpf/DynamicGrid/UIComponent/DynamicGridTreeUIComponent.cs

@@ -212,10 +212,13 @@ public class DynamicGridTreeUIComponent<T, TKey> : IDynamicGridUIComponent<T>, I
         SetParentKey = setParentKey;
     }
 
-    public DynamicGridTreeUIComponent(Expression<Func<T, TKey>> idColumn, Expression<Func<T, TKey>> parentIDColumn, TKey nullKey): this()
+    public DynamicGridTreeUIComponent(Expression<Func<T, TKey>> idColumn, Expression<Func<T, TKey>>? parentIDColumn, TKey nullKey): this()
     {
         IDColumn = new Column<T>(CoreUtils.GetFullPropertyName(idColumn, "."));
-        ParentColumn = new Column<T>(CoreUtils.GetFullPropertyName(parentIDColumn, "."));
+        if(parentIDColumn is not null)
+        {
+            ParentColumn = new Column<T>(CoreUtils.GetFullPropertyName(parentIDColumn, "."));
+        }
         NullKey = nullKey;
     }
 
@@ -1004,22 +1007,26 @@ public class DynamicGridTreeUIComponent<T, TKey> : IDynamicGridUIComponent<T>, I
         return MapRow(node?.Row);
     }
 
+    /// <summary>
+    /// Map a row of <see cref="_innerTable"/> to a Data row.
+    /// </summary>
     private CoreRow? MapRow(CoreRow? row)
     {
         if (row is null) return null;
 
         return _rowMap.GetValueOrDefault(row);
     }
-    
-    public CoreRow GetVisibleRow(int index) => _rowMap.Values.ToArray()[index];
 
     private CoreTreeNode<TKey>? GetNode(CoreRow row)
     {
-        if (_innerTable is null || row.Index < 0 || row.Index >= _innerTable.Rows.Count) return null;
-
-        var _innerRow = _innerTable.Rows[row.Index];
-        var node = Nodes.Find(_innerRow);
-        return node;
+        foreach(var (innerRow, dataRow) in _rowMap)
+        {
+            if(row == dataRow)
+            {
+                return Nodes.Find(innerRow);
+            }
+        }
+        return null;
     }
 
     public CoreRow[] GetVisibleRows()
@@ -1669,6 +1676,9 @@ public class DynamicGridTreeUIComponent<T, TKey> : IDynamicGridUIComponent<T>, I
 
     public CoreTreeNodes<TKey> Nodes { get; set; }
 
+    /// <summary>
+    /// Map from _innerTable rows to Data rows.
+    /// </summary>
     private Dictionary<CoreRow, CoreRow> _rowMap = new();
 
     private CoreTable? _innerTable;
@@ -1797,14 +1807,14 @@ public class DynamicGridTreeUIComponent<T, TKey> : IDynamicGridUIComponent<T>, I
 
     public void InvalidateRow(CoreRow row)
     {
-        if (_innerTable is null || row.Index < 0 || row.Index >= _innerTable.Rows.Count) return;
         _invalidating = true;
 
-        var _innerRow = _innerTable.Rows[row.Index];
-        ProcessRow(_innerRow, row);
-
-        var coreTreeNode = Nodes.Find(_innerRow);
-        coreTreeNode?.InvalidateData();
+        var node = GetNode(row);
+        if(node is not null)
+        {
+            ProcessRow(node.Row, row);
+            node.InvalidateData();
+        }
 
         CalculateSummaries();
 

+ 0 - 1
inabox.wpf/DynamicGrid/UIComponent/IDynamicGridUIComponent.cs

@@ -96,7 +96,6 @@ public interface IDynamicGridUIComponent
 
     void ScrollIntoView(CoreRow row);
     CoreRow[] GetVisibleRows();
-    CoreRow GetVisibleRow(int index);
 }
 
 public interface IDynamicGridUIComponent<T> : IDynamicGridUIComponent