Selaa lähdekoodia

Allowing for interleaving DynamicActionColumns with DynamicGridColumns

Kenric Nugteren 8 kuukautta sitten
vanhempi
commit
4c96801379

+ 3 - 4
inabox.wpf/DynamicGrid/Columns/DynamicActionColumns.cs

@@ -1,8 +1,7 @@
 using System.Collections.Generic;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public class DynamicActionColumns : List<DynamicActionColumn>
 {
-    public class DynamicActionColumns : List<DynamicActionColumn>
-    {
-    }
 }

+ 30 - 8
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -985,22 +985,39 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     public class ColumnsLoadedEventArgs : EventArgs
     {
-        public DynamicGridColumns VisibleColumns { get; private set; }
-        public DynamicActionColumns ActionColumns { get; private set; }
+        public List<DynamicColumnBase> Columns { get; private set; }
         public DynamicGridColumnGroupings ColumnGroupings { get; private set; }
 
-        public ColumnsLoadedEventArgs(DynamicGridColumns visibleColumns, DynamicActionColumns actionColumns,
-            DynamicGridColumnGroupings columnGroupings)
+        public IEnumerable<DynamicActionColumn> ActionColumns => Columns.OfType<DynamicActionColumn>();
+        public IEnumerable<DynamicGridColumn> DataColumns => Columns.OfType<DynamicGridColumn>();
+
+        public ColumnsLoadedEventArgs(List<DynamicColumnBase> columns, DynamicGridColumnGroupings columnGroupings)
         {
-            VisibleColumns = visibleColumns;
-            ActionColumns = actionColumns;
+            Columns = columns;
             ColumnGroupings = columnGroupings;
         }
+
+        public DynamicGridColumn Add(
+            Expression<Func<T, object?>> member,
+            int? width = null,
+            string? caption = null,
+            string? format = null,
+            Alignment? alignment = null)
+        {
+            var col = DynamicGridColumns.CreateColumn(member, width: width, caption: caption, format: format, alignment: alignment);
+            Columns.Add(col);
+            return col;
+        }
     }
     
     public delegate void ColumnsLoadedEvent(DynamicGrid sender, ColumnsLoadedEventArgs args);
 
     public event ColumnsLoadedEvent ColumnsLoaded;
+
+    protected virtual void OnColumnsLoaded(List<DynamicColumnBase> columns, DynamicGridColumnGroupings groupings)
+    {
+        ColumnsLoaded?.Invoke(this, new ColumnsLoadedEventArgs(columns, groupings));
+    }
     
     private void ReloadColumns()
     {
@@ -1012,9 +1029,14 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         ColumnGroupings.Clear();
         ConfigureColumnGroups();
 
-        ColumnsLoaded?.Invoke(this,new ColumnsLoadedEventArgs(VisibleColumns, ActionColumns, ColumnGroupings));
+        var columns = new List<DynamicColumnBase>();
+        columns.AddRange(ActionColumns.Where(x => x.Position == DynamicActionColumnPosition.Start));
+        columns.AddRange(VisibleColumns);
+        columns.AddRange(ActionColumns.Where(x => x.Position == DynamicActionColumnPosition.End));
+
+        OnColumnsLoaded(columns, ColumnGroupings);
         
-        UIComponent.RefreshColumns(VisibleColumns, ActionColumns, ColumnGroupings);
+        UIComponent.RefreshColumns(columns, ColumnGroupings);
     }
 
     #endregion

+ 14 - 3
inabox.wpf/DynamicGrid/DynamicGridColumns.cs

@@ -57,13 +57,12 @@ public class DynamicGridColumns : List<DynamicGridColumn>, IGlobalConfigurationS
         return result;
     }
 
-    public DynamicGridColumn Add<TType, TProperty>(
+    public static DynamicGridColumn CreateColumn<TType, TProperty>(
         Expression<Func<TType, TProperty>> member,
         int? width = null,
         string? caption = null,
         string? format = null,
-        Alignment? alignment = null
-    )
+        Alignment? alignment = null)
     {
         var prop = DatabaseSchema.Property(member);
         var col = new DynamicGridColumn
@@ -75,6 +74,18 @@ public class DynamicGridColumns : List<DynamicGridColumn>, IGlobalConfigurationS
             Editor = prop.Editor.CloneEditor(),
             Caption = caption ?? prop.Caption
         };
+        return col;
+    }
+
+    public DynamicGridColumn Add<TType, TProperty>(
+        Expression<Func<TType, TProperty>> member,
+        int? width = null,
+        string? caption = null,
+        string? format = null,
+        Alignment? alignment = null
+    )
+    {
+        var col = CreateColumn(member, width: width, caption: caption, format: format, alignment: alignment);
         Add(col);
         return col;
     }

+ 211 - 214
inabox.wpf/DynamicGrid/UIComponent/DynamicGridGridUIComponent.cs

@@ -966,144 +966,31 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                 .AddBinding(new Binding(sColName))));
     }
 
-    private void LoadActionColumns(DynamicActionColumnPosition position)
+    private void ApplyFilterStyle(GridColumn column, bool filtering, bool isactioncolumn)
     {
-        for (var i = 0; i < ActionColumns.Count; i++)
+        var filterstyle = new Style();
+        if (filtering)
         {
-            var column = ActionColumns[i];
-            if (column.Position == position)
-            {
-                //String sColName = String.Format("ActionColumn{0}{1}", i, position == DynamicActionColumnPosition.Start ? "L" : "R");
-                var sColName = string.Format("ActionColumn{0}", i);
-                gridRowResizingOptions.ExcludeColumns.Add(sColName);
-
-                var summary = ConvertSummary(column.Summary());
-                if (summary != null)
-                {
-                    summary.Name = sColName;
-                    summary.MappingName = sColName;
-                    Summaries.Add(summary);
-                }
-
-                if (column is DynamicImageColumn imgcol)
-                {
-                    var newcol = new GridImageColumn();
-                    newcol.MappingName = sColName;
-                    //newcol.Stretch = Stretch.Uniform;
-                    newcol.Width = column.Width == 0 ? DataGrid.RowHeight : column.Width;
-                    newcol.Padding = new Thickness(4);
-                    newcol.ImageHeight = DataGrid.RowHeight - 8;
-                    newcol.ImageWidth = DataGrid.RowHeight - 8;
-                    newcol.ColumnSizer = GridLengthUnitType.None;
-                    newcol.HeaderText = column.HeaderText;
-                    newcol.AllowEditing = false;
-
-                    ApplyFilterStyle(newcol, true, true);
-
-                    newcol.ShowToolTip = column.ToolTip != null;
-                    newcol.ShowHeaderToolTip = column.ToolTip != null;
-
-                    var style = new Style();
-                    style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
-                    style.Setters.Add(new Setter(Control.IsEnabledProperty, false));
-                    newcol.FilterRowCellStyle = style;
-
-                    newcol.HeaderStyle = GetHeaderCellStyle(column);
-
-                    DataGrid.Columns.Add(newcol);
-                    ColumnList.Add(column);
-                }
-                else if (column is DynamicTextColumn txtCol)
-                {
-
-                    var newcol = new GridTextColumn();
-                    gridRowResizingOptions.ExcludeColumns.Add(sColName);
-                    newcol.TextWrapping = TextWrapping.NoWrap;
-
-                    newcol.TextAlignment = txtCol.Alignment.TextAlignment(typeof(string));
-
-                    newcol.AllowEditing = false;
-                    newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
-                    newcol.MappingName = sColName;
-                    newcol.Width = column.Width;
-                    newcol.ColumnSizer = GridLengthUnitType.None;
-                    newcol.HeaderText = column.HeaderText;
-                    newcol.AllowFiltering = (column.Filters != null && column.Filters.Length != 0) || column.FilterRecord is not null;
-                    newcol.AllowSorting = false;
-                    newcol.FilterRowOptionsVisibility = Visibility.Collapsed;
-                    newcol.ShowHeaderToolTip = column.ToolTip != null;
-                    
-                    newcol.ShowToolTip = column.ToolTip != null;
-                    newcol.ShowHeaderToolTip = column.ToolTip != null;
-
-                    var style = new Style();
-                    style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
-                    style.Setters.Add(new Setter(Control.IsEnabledProperty, false));
-                    newcol.FilterRowCellStyle = style;
-
-                    newcol.HeaderStyle = GetHeaderCellStyle(column);
-                    
-                    var cellstyle = new Style();
-                    AddCellStyleConverters(cellstyle, column, sColName);
-                    newcol.CellStyle = cellstyle;
-
-                    DataGrid.Columns.Add(newcol);
-                    ColumnList.Add(column);
-                }
-                else if (column is DynamicTemplateColumn tmplCol)
-                {
-                    var newcol = new GridTemplateColumn();
-                    newcol.CellTemplate = TemplateGenerator.CreateDataTemplate(() =>
-                    {
-                        var content = new ContentControl();
-                        content.SetBinding(ContentControl.ContentProperty,
-                            WPFUtils.CreateMultiBinding(new MultiFuncConverter(x =>
-                            {
-                                if(x[0] is DataRowView view && DataGridItems is DataTable table)
-                                {
-                                    var rowIdx = table.Rows.IndexOf(view.Row);
-                                    if (rowIdx >= 0)
-                                    {
-                                        return tmplCol.Template(Parent.Data.Rows[rowIdx]);
-                                    }
-                                }
-                                return null;
-                            }))
-                                .AddBinding(new Binding("."))
-                                .AddBinding(new Binding(sColName)));
-                        return content;
-                    });
-
-                    newcol.AllowEditing = false;
-                    newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
-                    newcol.MappingName = sColName;
-                    
-                    newcol.Width = tmplCol.Width;
-                    newcol.ColumnSizer = GridLengthUnitType.None;
-                    newcol.HeaderText = column.HeaderText;
-                    newcol.AllowFiltering = false;
-                    newcol.AllowSorting = false;
-                    newcol.FilterRowOptionsVisibility = Visibility.Collapsed;
-                    
-                    newcol.ShowToolTip = column.ToolTip != null;
-                    newcol.ShowHeaderToolTip = column.ToolTip != null;
-
-                    var style = new Style();
-                    style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
-                    style.Setters.Add(new Setter(Control.IsEnabledProperty, false));
-                    newcol.FilterRowCellStyle = style;
-
-                    newcol.HeaderStyle = GetHeaderCellStyle(column);
-
-                    var cellstyle = new Style();
-                    AddCellStyleConverters(cellstyle, column, sColName);
-                    newcol.CellStyle = cellstyle;
-
-                    DataGrid.Columns.Add(newcol);
-                    ColumnList.Add(column);
-                }
-            }
+            filterstyle.Setters.Add(new Setter(Control.BackgroundProperty, DynamicGridUtils.FilterBackground));
+            column.ImmediateUpdateColumnFilter = true;
+            column.ColumnFilter = ColumnFilter.Value;
+            column.FilterRowCondition = FilterRowCondition.Contains;
+            column.FilterRowOptionsVisibility = Visibility.Collapsed;
+            column.AllowBlankFilters = true;
+            column.AllowSorting = !isactioncolumn && Parent.CanSort();
+        }
+        else
+        {
+            filterstyle.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
+            filterstyle.Setters.Add(new Setter(Control.IsEnabledProperty, false));
+            column.ColumnFilter = ColumnFilter.Value;
+            column.AllowFiltering = false;
+            column.AllowSorting = false;
+            column.FilterRowEditorType = "TextBox";
+            column.FilterRowOptionsVisibility = Visibility.Collapsed;
         }
+
+        column.FilterRowCellStyle = filterstyle;
     }
 
     #region Summaries
@@ -1218,99 +1105,201 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
     #endregion
 
-    private void ApplyFilterStyle(GridColumn column, bool filtering, bool isactioncolumn)
+    private void LoadActionColumn(DynamicActionColumn column)
     {
-        var filterstyle = new Style();
-        if (filtering)
+        var i = ActionColumns.Count;
+        var sColName = string.Format("ActionColumn{0}", i);
+        ActionColumns.Add(column);
+        gridRowResizingOptions.ExcludeColumns.Add(sColName);
+
+        var summary = ConvertSummary(column.Summary());
+        if (summary != null)
         {
-            filterstyle.Setters.Add(new Setter(Control.BackgroundProperty, DynamicGridUtils.FilterBackground));
-            column.ImmediateUpdateColumnFilter = true;
-            column.ColumnFilter = ColumnFilter.Value;
-            column.FilterRowCondition = FilterRowCondition.Contains;
-            column.FilterRowOptionsVisibility = Visibility.Collapsed;
-            column.AllowBlankFilters = true;
-            column.AllowSorting = !isactioncolumn && Parent.CanSort();
+            summary.Name = sColName;
+            summary.MappingName = sColName;
+            Summaries.Add(summary);
         }
-        else
+
+        if (column is DynamicImageColumn imgcol)
         {
-            filterstyle.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
-            filterstyle.Setters.Add(new Setter(Control.IsEnabledProperty, false));
-            column.ColumnFilter = ColumnFilter.Value;
-            column.AllowFiltering = false;
-            column.AllowSorting = false;
-            column.FilterRowEditorType = "TextBox";
-            column.FilterRowOptionsVisibility = Visibility.Collapsed;
+            var newcol = new GridImageColumn();
+            newcol.MappingName = sColName;
+            newcol.Width = column.Width == 0 ? DataGrid.RowHeight : column.Width;
+            newcol.Padding = new Thickness(4);
+            newcol.ImageHeight = DataGrid.RowHeight - 8;
+            newcol.ImageWidth = DataGrid.RowHeight - 8;
+            newcol.ColumnSizer = GridLengthUnitType.None;
+            newcol.HeaderText = column.HeaderText;
+            newcol.AllowEditing = false;
+
+            ApplyFilterStyle(newcol, true, true);
+
+            newcol.ShowToolTip = column.ToolTip != null;
+            newcol.ShowHeaderToolTip = column.ToolTip != null;
+
+            var style = new Style();
+            style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
+            style.Setters.Add(new Setter(Control.IsEnabledProperty, false));
+            newcol.FilterRowCellStyle = style;
+
+            newcol.HeaderStyle = GetHeaderCellStyle(column);
+
+            DataGrid.Columns.Add(newcol);
+            ColumnList.Add(column);
         }
+        else if (column is DynamicTextColumn txtCol)
+        {
 
-        column.FilterRowCellStyle = filterstyle;
+            var newcol = new GridTextColumn();
+            gridRowResizingOptions.ExcludeColumns.Add(sColName);
+            newcol.TextWrapping = TextWrapping.NoWrap;
+
+            newcol.TextAlignment = txtCol.Alignment.TextAlignment(typeof(string));
+
+            newcol.AllowEditing = false;
+            newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
+            newcol.MappingName = sColName;
+            newcol.Width = column.Width;
+            newcol.ColumnSizer = GridLengthUnitType.None;
+            newcol.HeaderText = column.HeaderText;
+            newcol.AllowFiltering = (column.Filters != null && column.Filters.Length != 0) || column.FilterRecord is not null;
+            newcol.AllowSorting = false;
+            newcol.FilterRowOptionsVisibility = Visibility.Collapsed;
+            newcol.ShowHeaderToolTip = column.ToolTip != null;
+            
+            newcol.ShowToolTip = column.ToolTip != null;
+            newcol.ShowHeaderToolTip = column.ToolTip != null;
+
+            var style = new Style();
+            style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
+            style.Setters.Add(new Setter(Control.IsEnabledProperty, false));
+            newcol.FilterRowCellStyle = style;
+
+            newcol.HeaderStyle = GetHeaderCellStyle(column);
+            
+            var cellstyle = new Style();
+            AddCellStyleConverters(cellstyle, column, sColName);
+            newcol.CellStyle = cellstyle;
+
+            DataGrid.Columns.Add(newcol);
+            ColumnList.Add(column);
+        }
+        else if (column is DynamicTemplateColumn tmplCol)
+        {
+            var newcol = new GridTemplateColumn();
+            newcol.CellTemplate = TemplateGenerator.CreateDataTemplate(() =>
+            {
+                var content = new ContentControl();
+                content.SetBinding(ContentControl.ContentProperty,
+                    WPFUtils.CreateMultiBinding(new MultiFuncConverter(x =>
+                    {
+                        if(x[0] is DataRowView view && DataGridItems is DataTable table)
+                        {
+                            var rowIdx = table.Rows.IndexOf(view.Row);
+                            if (rowIdx >= 0)
+                            {
+                                return tmplCol.Template(Parent.Data.Rows[rowIdx]);
+                            }
+                        }
+                        return null;
+                    }))
+                        .AddBinding(new Binding("."))
+                        .AddBinding(new Binding(sColName)));
+                return content;
+            });
+
+            newcol.AllowEditing = false;
+            newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
+            newcol.MappingName = sColName;
+            
+            newcol.Width = tmplCol.Width;
+            newcol.ColumnSizer = GridLengthUnitType.None;
+            newcol.HeaderText = column.HeaderText;
+            newcol.AllowFiltering = false;
+            newcol.AllowSorting = false;
+            newcol.FilterRowOptionsVisibility = Visibility.Collapsed;
+            
+            newcol.ShowToolTip = column.ToolTip != null;
+            newcol.ShowHeaderToolTip = column.ToolTip != null;
+
+            var style = new Style();
+            style.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
+            style.Setters.Add(new Setter(Control.IsEnabledProperty, false));
+            newcol.FilterRowCellStyle = style;
+
+            newcol.HeaderStyle = GetHeaderCellStyle(column);
+
+            var cellstyle = new Style();
+            AddCellStyleConverters(cellstyle, column, sColName);
+            newcol.CellStyle = cellstyle;
+
+            DataGrid.Columns.Add(newcol);
+            ColumnList.Add(column);
+        }
     }
 
-    private void LoadDataColumns(DynamicGridColumns columns)
+    private void LoadDataColumn(DynamicGridColumn column)
     {
-        foreach (var column in columns)
+        if (this.CreateEditorColumn(column, out var newcol, out var prop))
         {
-            if (this.CreateEditorColumn(column, out var newcol, out var prop))
-            {
-                newcol.GetEntity = () => _editingObject?.Object;
-                newcol.EntityChanged += DoEntityChanged;
-                if (!newcol.VariableHeight)
-                    gridRowResizingOptions.ExcludeColumns.Add(newcol.MappingName);
+            newcol.GetEntity = () => _editingObject?.Object;
+            newcol.EntityChanged += DoEntityChanged;
+            if (!newcol.VariableHeight)
+                gridRowResizingOptions.ExcludeColumns.Add(newcol.MappingName);
 
-                var newColumn = newcol.CreateGridColumn();
+            var newColumn = newcol.CreateGridColumn();
 
-                var summary = ConvertSummary(newcol.Summary());
-                if (summary != null)
-                {
-                    summary.Name = newcol.MappingName;
-                    summary.MappingName = newcol.MappingName;
-                    Summaries.Add(summary);
-                }
-                
-                ApplyFilterStyle(newColumn, newcol.Filtered, false);
-                
-                newColumn.HeaderStyle = GetHeaderCellStyle(column);
+            var summary = ConvertSummary(newcol.Summary());
+            if (summary != null)
+            {
+                summary.Name = newcol.MappingName;
+                summary.MappingName = newcol.MappingName;
+                Summaries.Add(summary);
+            }
+            
+            ApplyFilterStyle(newColumn, newcol.Filtered, false);
+            
+            newColumn.HeaderStyle = GetHeaderCellStyle(column);
 
-                var cellstyle = new Style();
-                if (Parent.IsDirectEditMode())
+            var cellstyle = new Style();
+            if (Parent.IsDirectEditMode())
+            {
+                var editor = Parent.CustomiseEditor(column, column.Editor);
+                if (editor is null || !editor.Editable.IsDirectEditable())
                 {
-                    var editor = Parent.CustomiseEditor(column, column.Editor);
-                    if (editor is null || !editor.Editable.IsDirectEditable())
-                    {
-                        cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
-                            new Binding()
-                            {
-                                Path = new PropertyPath("."), Converter = CellBackgroundConverter,
-                                ConverterParameter = new DynamicGridCellStyleParameters(column,new SolidColorBrush(Colors.WhiteSmoke))
-                            }));
-                        newColumn.AllowEditing = false;
-                    }
-                    else
-                    {
-                        cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
-                            new Binding()
-                            {
-                                Path = new PropertyPath("."), Converter = CellBackgroundConverter,
-                                ConverterParameter = new DynamicGridCellStyleParameters(column,new SolidColorBrush(Colors.LightYellow))
-                            }));
-                        newColumn.AllowEditing = true;
-                    }
-
-                    cellstyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(Colors.Black)));
-                    newColumn.CellStyle = cellstyle;
+                    cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
+                        new Binding()
+                        {
+                            Path = new PropertyPath("."), Converter = CellBackgroundConverter,
+                            ConverterParameter = new DynamicGridCellStyleParameters(column,new SolidColorBrush(Colors.WhiteSmoke))
+                        }));
+                    newColumn.AllowEditing = false;
                 }
                 else
                 {
-                    AddCellStyleConverters(cellstyle, column, newColumn.MappingName);
-                    newColumn.CellStyle = cellstyle;
+                    cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
+                        new Binding()
+                        {
+                            Path = new PropertyPath("."), Converter = CellBackgroundConverter,
+                            ConverterParameter = new DynamicGridCellStyleParameters(column,new SolidColorBrush(Colors.LightYellow))
+                        }));
+                    newColumn.AllowEditing = true;
                 }
-                
-                DataGrid.Columns.Add(newColumn);
-                ColumnList.Add(column);
-                foreach (var extra in newcol.ExtraColumns)
-                    Parent.AddHiddenColumn(extra);
+
+                cellstyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(Colors.Black)));
+                newColumn.CellStyle = cellstyle;
             }
+            else
+            {
+                AddCellStyleConverters(cellstyle, column, newColumn.MappingName);
+                newColumn.CellStyle = cellstyle;
+            }
+            
+            DataGrid.Columns.Add(newColumn);
+            ColumnList.Add(column);
+            foreach (var extra in newcol.ExtraColumns)
+                Parent.AddHiddenColumn(extra);
         }
-
     }
 
     private void LoadSummaries()
@@ -1329,23 +1318,31 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         }
     }
 
-    public void RefreshColumns(DynamicGridColumns columns, DynamicActionColumns actionColumns, DynamicGridColumnGroupings groupings)
+    public void RefreshColumns(IEnumerable<DynamicColumnBase> columns, DynamicGridColumnGroupings groupings)
     {
         DataGrid.ItemsSource = null;
         DataGrid.Columns.Suspend();
 
         ColumnList.Clear();
+        ActionColumns.Clear();
         DataGrid.Columns.Clear();
         DataGrid.TableSummaryRows.Clear();
 
         gridRowResizingOptions.ExcludeColumns = new List<string>();
+        Summaries.Clear();
 
-        ActionColumns = actionColumns.ToList();
+        foreach(var column in columns)
+        {
+            if(column is DynamicActionColumn ac)
+            {
+                LoadActionColumn(ac);
+            }
+            else if(column is DynamicGridColumn gc)
+            {
+                LoadDataColumn(gc);
+            }
+        }
 
-        Summaries.Clear();
-        LoadActionColumns(DynamicActionColumnPosition.Start);
-        LoadDataColumns(columns);
-        LoadActionColumns(DynamicActionColumnPosition.End);
         LoadSummaries();
         LoadStackedHeaders(groupings);
 

+ 170 - 177
inabox.wpf/DynamicGrid/UIComponent/DynamicGridTreeUIComponent.cs

@@ -980,192 +980,184 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         }
     }
 
-    private void LoadActionColumns(DynamicActionColumnPosition position)
+    private void LoadActionColumn(DynamicActionColumn column)
     {
-        for (var i = 0; i < ActionColumns.Count; i++)
+        var i = ActionColumns.Count;
+        var sColName = $"[_ActionColumn{i}]";
+        ActionColumns.Add(column);
+
+        var summary = column.Summary();
+        if(summary is not null)
         {
-            var column = ActionColumns[i];
-            if (column.Position == position)
-            {
-                var sColName = $"[_ActionColumn{i}]";
+            Summaries.Add(new(column, summary, null, null));
+        }
 
-                var summary = column.Summary();
-                if(summary is not null)
-                {
-                    Summaries.Add(new(column, summary, null, null));
-                }
+        if (column is DynamicImageColumn imgcol)
+        {
+            var newcol = new TreeGridTemplateColumn();
 
-                if (column is DynamicImageColumn imgcol)
+            newcol.CellTemplateSelector = new TemplateColumnSelector(this, row =>
+            {
+                var image = new Image
                 {
-                    var newcol = new TreeGridTemplateColumn();
+                    Width = _tree.RowHeight - 8,
+                    Height = _tree.RowHeight - 8,
+                };
+                image.SetBinding(Image.SourceProperty, new Binding(sColName));
+                return image;
+            });
 
-                    newcol.CellTemplateSelector = new TemplateColumnSelector(this, row =>
-                    {
-                        var image = new Image
-                        {
-                            Width = _tree.RowHeight - 8,
-                            Height = _tree.RowHeight - 8,
-                        };
-                        image.SetBinding(Image.SourceProperty, new Binding(sColName));
-                        return image;
-                    });
-
-                    newcol.AllowEditing = false;
-                    newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
-                    newcol.Width = column.Width == 0 ? _tree.RowHeight : column.Width;
-                    newcol.Padding = new Thickness(4);
-                    newcol.ColumnSizer = TreeColumnSizer.None;
-                    newcol.HeaderText = column.HeaderText;
-                    newcol.MappingName = sColName;
-
-                    ApplyFilterStyle(newcol, false, true);
-
-                    newcol.ShowToolTip = column.ToolTip != null;
-                    newcol.ShowHeaderToolTip = column.ToolTip != null;
-
-                    var headstyle = GetHeaderCellStyle(column);
-                    headstyle.Setters.Add(new EventSetter(Control.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderCell_LeftMouseButtonEvent)));
-                    newcol.HeaderStyle = headstyle;
-
-                    _tree.Columns.Add(newcol);
-                    ColumnList.Add(column);
-                }
-                else if (column is DynamicTextColumn txtCol)
-                {
-                    var newcol = new TreeGridTextColumn();
-                    newcol.TextWrapping = TextWrapping.NoWrap;
-
-                    newcol.TextAlignment = txtCol.Alignment.TextAlignment(typeof(string));
-
-                    newcol.AllowEditing = false;
-                    newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
-                    newcol.MappingName = sColName;
-                    newcol.Width = column.Width;
-                    newcol.ColumnSizer = TreeColumnSizer.None;
-                    newcol.HeaderText = column.HeaderText;
-                    //newcol.AllowFiltering = column.Filters != null && column.Filters.Any();
-                    newcol.AllowSorting = false;
-                    newcol.ShowHeaderToolTip = column.ToolTip != null;
-                    
-                    ApplyFilterStyle(newcol, false, true);
-
-                    var headstyle = GetHeaderCellStyle(column);
-                    headstyle.Setters.Add(new EventSetter(Control.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderCell_LeftMouseButtonEvent)));
-                    newcol.HeaderStyle = headstyle;
-
-                    _tree.Columns.Add(newcol);
-                    ColumnList.Add(column);
-                }
-                else if (column is DynamicTemplateColumn tmplCol)
-                {
-                    var newcol = new TreeGridTemplateColumn();
-                    newcol.CellTemplateSelector = new TemplateColumnSelector(this, tmplCol.Template);
-                    newcol.AllowEditing = false;
-                    newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
-                    
-                    newcol.Width = tmplCol.Width;
-                    newcol.ColumnSizer = TreeColumnSizer.None;
-                    newcol.HeaderText = column.HeaderText;
-                    //newcol.AllowFiltering = false;
-                    newcol.AllowSorting = false;
-                    newcol.ShowToolTip = false;
-                    newcol.ShowHeaderToolTip = false;
-                    newcol.MappingName = sColName;
-                    
-                    ApplyFilterStyle(newcol, false, true);
-
-                    var headstyle = GetHeaderCellStyle(column);
-                    headstyle.Setters.Add(new EventSetter(Control.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderCell_LeftMouseButtonEvent)));
-                    newcol.HeaderStyle = headstyle;
-
-                    _tree.Columns.Add(newcol);
-                    ColumnList.Add(column);
-                }
-            }
+            newcol.AllowEditing = false;
+            newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
+            newcol.Width = column.Width == 0 ? _tree.RowHeight : column.Width;
+            newcol.Padding = new Thickness(4);
+            newcol.ColumnSizer = TreeColumnSizer.None;
+            newcol.HeaderText = column.HeaderText;
+            newcol.MappingName = sColName;
+
+            ApplyFilterStyle(newcol, false, true);
+
+            newcol.ShowToolTip = column.ToolTip != null;
+            newcol.ShowHeaderToolTip = column.ToolTip != null;
+
+            var headstyle = GetHeaderCellStyle(column);
+            headstyle.Setters.Add(new EventSetter(Control.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderCell_LeftMouseButtonEvent)));
+            newcol.HeaderStyle = headstyle;
+
+            _tree.Columns.Add(newcol);
+            ColumnList.Add(column);
+        }
+        else if (column is DynamicTextColumn txtCol)
+        {
+            var newcol = new TreeGridTextColumn();
+            newcol.TextWrapping = TextWrapping.NoWrap;
+
+            newcol.TextAlignment = txtCol.Alignment.TextAlignment(typeof(string));
+
+            newcol.AllowEditing = false;
+            newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
+            newcol.MappingName = sColName;
+            newcol.Width = column.Width;
+            newcol.ColumnSizer = TreeColumnSizer.None;
+            newcol.HeaderText = column.HeaderText;
+            //newcol.AllowFiltering = column.Filters != null && column.Filters.Any();
+            newcol.AllowSorting = false;
+            newcol.ShowHeaderToolTip = column.ToolTip != null;
+            
+            ApplyFilterStyle(newcol, false, true);
+
+            var headstyle = GetHeaderCellStyle(column);
+            headstyle.Setters.Add(new EventSetter(Control.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderCell_LeftMouseButtonEvent)));
+            newcol.HeaderStyle = headstyle;
+
+            _tree.Columns.Add(newcol);
+            ColumnList.Add(column);
+        }
+        else if (column is DynamicTemplateColumn tmplCol)
+        {
+            var newcol = new TreeGridTemplateColumn();
+            newcol.CellTemplateSelector = new TemplateColumnSelector(this, tmplCol.Template);
+            newcol.AllowEditing = false;
+            newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
+            
+            newcol.Width = tmplCol.Width;
+            newcol.ColumnSizer = TreeColumnSizer.None;
+            newcol.HeaderText = column.HeaderText;
+            //newcol.AllowFiltering = false;
+            newcol.AllowSorting = false;
+            newcol.ShowToolTip = false;
+            newcol.ShowHeaderToolTip = false;
+            newcol.MappingName = sColName;
+            
+            ApplyFilterStyle(newcol, false, true);
+
+            var headstyle = GetHeaderCellStyle(column);
+            headstyle.Setters.Add(new EventSetter(Control.MouseLeftButtonUpEvent, new MouseButtonEventHandler(HeaderCell_LeftMouseButtonEvent)));
+            newcol.HeaderStyle = headstyle;
+
+            _tree.Columns.Add(newcol);
+            ColumnList.Add(column);
         }
     }
 
-    private void LoadDataColumns(DynamicGridColumns columns)
+    private void LoadDataColumn(DynamicGridColumn column)
     {
-        foreach (var column in columns)
+        if(this.CreateEditorColumn(column, out var newcol, out var prop))
         {
-            if(this.CreateEditorColumn(column, out var newcol, out var prop))
-            {
-                newcol.GetEntity = () => _editingObject?.Object;
-                newcol.EntityChanged += DoEntityChanged;
+            newcol.GetEntity = () => _editingObject?.Object;
+            newcol.EntityChanged += DoEntityChanged;
 
-                var newColumn = newcol.CreateTreeGridColumn();
+            var newColumn = newcol.CreateTreeGridColumn();
 
-                var summary = newcol.Summary();
-                if(summary is not null)
-                {
-                    Summaries.Add(new(column, summary, null, null));
-                }
+            var summary = newcol.Summary();
+            if(summary is not null)
+            {
+                Summaries.Add(new(column, summary, null, null));
+            }
 
-                ApplyFilterStyle(newColumn, newcol.Filtered, false);
-                
-                newColumn.HeaderStyle = GetHeaderCellStyle(column);
+            ApplyFilterStyle(newColumn, newcol.Filtered, false);
+            
+            newColumn.HeaderStyle = GetHeaderCellStyle(column);
 
-                var cellstyle = new Style();
-                if (Parent.IsDirectEditMode())
+            var cellstyle = new Style();
+            if (Parent.IsDirectEditMode())
+            {
+                var editor = Parent.CustomiseEditor(column, column.Editor);
+                if (editor is null || !editor.Editable.IsDirectEditable())
                 {
-                    var editor = Parent.CustomiseEditor(column, column.Editor);
-                    if (editor is null || !editor.Editable.IsDirectEditable())
-                    {
-                        cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
-                            new SolidColorBrush(Colors.WhiteSmoke)));
-                        newColumn.AllowEditing = false;
-                    }
-                    else
-                    {
-                        cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
-                            new SolidColorBrush(Colors.LightYellow)));
-                        newColumn.AllowEditing = true;
-                    }
-
-                    cellstyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(Colors.Black)));
-                    newColumn.CellStyle = cellstyle;
+                    cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
+                        new SolidColorBrush(Colors.WhiteSmoke)));
+                    newColumn.AllowEditing = false;
                 }
                 else
                 {
                     cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
-                        new Binding()
-                        {
-                            Path = new PropertyPath("."), Converter = CellBackgroundConverter,
-                            ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
-                        }));
-                    cellstyle.Setters.Add(new Setter(Control.ForegroundProperty,
-                        new Binding()
-                        {
-                            Converter = CellForegroundConverter, 
-                            ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
-                        }));
-                    cellstyle.Setters.Add(new Setter(Control.FontSizeProperty,
-                        new Binding()
-                        {
-                            Converter = CellFontSizeConverter, 
-                            ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
-                        }));
-                    cellstyle.Setters.Add(new Setter(Control.FontStyleProperty,
-                        new Binding()
-                        {
-                            Converter = CellFontStyleConverter, 
-                            ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
-                        }));
-                    cellstyle.Setters.Add(new Setter(Control.FontWeightProperty,
-                        new Binding()
-                        {
-                            Converter = CellFontWeightConverter, 
-                            ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
-                        }));
-                    newColumn.CellStyle = cellstyle;
+                        new SolidColorBrush(Colors.LightYellow)));
+                    newColumn.AllowEditing = true;
                 }
-                
-                _tree.Columns.Add(newColumn);
-                ColumnList.Add(column);
-                foreach (var extra in newcol.ExtraColumns)
-                    Parent.AddHiddenColumn(extra);
+
+                cellstyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(Colors.Black)));
+                newColumn.CellStyle = cellstyle;
             }
+            else
+            {
+                cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
+                    new Binding()
+                    {
+                        Path = new PropertyPath("."), Converter = CellBackgroundConverter,
+                        ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
+                    }));
+                cellstyle.Setters.Add(new Setter(Control.ForegroundProperty,
+                    new Binding()
+                    {
+                        Converter = CellForegroundConverter, 
+                        ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
+                    }));
+                cellstyle.Setters.Add(new Setter(Control.FontSizeProperty,
+                    new Binding()
+                    {
+                        Converter = CellFontSizeConverter, 
+                        ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
+                    }));
+                cellstyle.Setters.Add(new Setter(Control.FontStyleProperty,
+                    new Binding()
+                    {
+                        Converter = CellFontStyleConverter, 
+                        ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
+                    }));
+                cellstyle.Setters.Add(new Setter(Control.FontWeightProperty,
+                    new Binding()
+                    {
+                        Converter = CellFontWeightConverter, 
+                        ConverterParameter = new DynamicGridCellStyleParameters(column,DependencyProperty.UnsetValue)
+                    }));
+                newColumn.CellStyle = cellstyle;
+            }
+            
+            _tree.Columns.Add(newColumn);
+            ColumnList.Add(column);
+            foreach (var extra in newcol.ExtraColumns)
+                Parent.AddHiddenColumn(extra);
         }
     }
 
@@ -1209,7 +1201,7 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         }
     }
 
-    public void RefreshColumns(DynamicGridColumns columns, DynamicActionColumns actionColumns, DynamicGridColumnGroupings groupings)
+    public void RefreshColumns(IEnumerable<DynamicColumnBase> columns, DynamicGridColumnGroupings groupings)
     {
         _tree.ItemsSource = null;
         _tree.Columns.Suspend();
@@ -1218,19 +1210,20 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         _tree.Columns.Clear();
         Summaries.Clear();
 
-        ActionColumns = actionColumns.ToList();
+        ActionColumns.Clear();
+
+        foreach(var column in columns)
+        {
+            if(column is DynamicActionColumn ac)
+            {
+                LoadActionColumn(ac);
+            }
+            else if(column is DynamicGridColumn gc)
+            {
+                LoadDataColumn(gc);
+            }
+        }
         
-        //_tree.Columns.Add(new TreeGridTextColumn()
-        //    {
-        //        MappingName = "Number",
-        //        Width = _shownumbers ? 50 : 0,
-        //        TextAlignment = TextAlignment.Right
-        //    }
-        //);
-
-        LoadActionColumns(DynamicActionColumnPosition.Start);
-        LoadDataColumns(columns);
-        LoadActionColumns(DynamicActionColumnPosition.End);
         LoadStackedHeaders(groupings);
 
         _tree.Columns.Resume();

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

@@ -76,7 +76,7 @@ public interface IDynamicGridUIComponent<T>
     List<Tuple<string, Func<CoreRow, bool>>> GetFilterPredicates();
 
     void BeforeRefresh();
-    void RefreshColumns(DynamicGridColumns columns, DynamicActionColumns actionColumns, DynamicGridColumnGroupings groupings);
+    void RefreshColumns(IEnumerable<DynamicColumnBase> columns, DynamicGridColumnGroupings groupings);
     void RefreshData(CoreTable data);
     void AddPage(IEnumerable<CoreRow> page);
     void InvalidateRow(CoreRow row);