Browse Source

Added row argument to DynamicTemplate columns

Kenric Nugteren 1 năm trước cách đây
mục cha
commit
000e4c6757

+ 2 - 2
inabox.wpf/DynamicGrid/Columns/DynamicTemplateColumn.cs

@@ -6,9 +6,9 @@ namespace InABox.DynamicGrid;
 
 public class DynamicTemplateColumn : DynamicActionColumn
 {
-    public Func<FrameworkElement> Template { get; protected set; }
+    public Func<CoreRow, FrameworkElement> Template { get; protected set; }
     
-    public DynamicTemplateColumn(Func<FrameworkElement> template)
+    public DynamicTemplateColumn(Func<CoreRow, FrameworkElement> template)
     {
         Template = template;
         VerticalHeader = false;

+ 1 - 1
inabox.wpf/DynamicGrid/DynamicDocumentGrid.cs

@@ -98,7 +98,7 @@ namespace InABox.DynamicGrid
             }
         }
 
-        private FrameworkElement DocumentTemplate()
+        private FrameworkElement DocumentTemplate(CoreRow row)
         {
             return SimpleTemplate
                 ? CreateSimpleTemplate()

+ 225 - 226
inabox.wpf/DynamicGrid/DynamicManyToManyCrossTab.cs

@@ -10,297 +10,296 @@ using System.Threading.Tasks;
 using System.Windows.Controls;
 using System.Windows.Media.Imaging;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public abstract class DynamicManyToManyCrossTab<TManyToMany, TRow, TColumn> : DynamicGrid<TRow>
+    where TManyToMany : Entity, IRemotable, IPersistent, new()
+    where TRow : Entity, IRemotable, IPersistent, new()
+    where TColumn : Entity, IRemotable, IPersistent, new()
 {
-    public abstract class DynamicManyToManyCrossTab<TManyToMany, TRow, TColumn> : DynamicGrid<TRow>
-        where TManyToMany : Entity, IRemotable, IPersistent, new()
-        where TRow : Entity, IRemotable, IPersistent, new()
-        where TColumn : Entity, IRemotable, IPersistent, new()
+    private static readonly BitmapImage tick = Wpf.Resources.tick.AsBitmapImage();
+
+    /// <summary>
+    /// Property on <typeparamref name="TManyToMany"/> which is an <see cref="EntityLink{T}"/> for <typeparamref name="TRow"/>.
+    /// </summary>
+    private readonly PropertyInfo rowProperty;
+    /// <summary>
+    /// Property on <typeparamref name="TManyToMany"/> which is an <see cref="EntityLink{T}"/> for <typeparamref name="TColumn"/>.
+    /// </summary>
+    private readonly PropertyInfo columnProperty;
+
+    private CoreTable? ColumnData;
+    /// <summary>
+    /// {ColumnID : { RowID }}
+    /// </summary>
+    private Dictionary<Guid, Dictionary<Guid, TManyToMany>>? ManyToManyData;
+
+    public DynamicManyToManyCrossTab()
     {
-        private static readonly BitmapImage tick = Wpf.Resources.tick.AsBitmapImage();
-
-        /// <summary>
-        /// Property on <typeparamref name="TManyToMany"/> which is an <see cref="EntityLink{T}"/> for <typeparamref name="TRow"/>.
-        /// </summary>
-        private readonly PropertyInfo rowProperty;
-        /// <summary>
-        /// Property on <typeparamref name="TManyToMany"/> which is an <see cref="EntityLink{T}"/> for <typeparamref name="TColumn"/>.
-        /// </summary>
-        private readonly PropertyInfo columnProperty;
-
-        private CoreTable? ColumnData;
-        /// <summary>
-        /// {ColumnID : { RowID }}
-        /// </summary>
-        private Dictionary<Guid, Dictionary<Guid, TManyToMany>>? ManyToManyData;
-
-        public DynamicManyToManyCrossTab()
-        {
-            rowProperty = CoreUtils.GetManyToManyThisProperty(typeof(TManyToMany), typeof(TRow));
-            columnProperty = CoreUtils.GetManyToManyThisProperty(typeof(TManyToMany), typeof(TColumn));
-
-            HeaderHeight = 125;
-        }
+        rowProperty = CoreUtils.GetManyToManyThisProperty(typeof(TManyToMany), typeof(TRow));
+        columnProperty = CoreUtils.GetManyToManyThisProperty(typeof(TManyToMany), typeof(TColumn));
 
-        protected override void Init()
-        {
-        }
+        HeaderHeight = 125;
+    }
 
-        protected override void DoReconfigure(FluentList<DynamicGridOption> options)
-        {
-            options.Clear();
-        }
+    protected override void Init()
+    {
+    }
 
-        /// <summary>
-        /// Load the required columns for <typeparamref name="TRow"/>.
-        /// </summary>
-        protected abstract DynamicGridColumns LoadRowColumns();
+    protected override void DoReconfigure(FluentList<DynamicGridOption> options)
+    {
+        options.Clear();
+    }
 
-        protected abstract Columns<TColumn>? LoadColumnColumns();
+    /// <summary>
+    /// Load the required columns for <typeparamref name="TRow"/>.
+    /// </summary>
+    protected abstract DynamicGridColumns LoadRowColumns();
 
-        protected abstract SortOrder<TColumn>? LoadColumnSort();
+    protected abstract Columns<TColumn>? LoadColumnColumns();
 
-        protected abstract string FormatColumnHeader(CoreRow row);
+    protected abstract SortOrder<TColumn>? LoadColumnSort();
 
-        protected virtual Filter<TRow>? RowFilter() => null;
+    protected abstract string FormatColumnHeader(CoreRow row);
 
-        protected virtual Filter<TColumn>? ColumnFilter() => null;
+    protected virtual Filter<TRow>? RowFilter() => null;
 
-        protected override DynamicGridColumns LoadColumns()
-        {
-            var columns = LoadRowColumns();
+    protected virtual Filter<TColumn>? ColumnFilter() => null;
 
-            var client = Client.Create(typeof(TColumn));
+    protected override DynamicGridColumns LoadColumns()
+    {
+        var columns = LoadRowColumns();
 
-            var columnColumns = new Columns<TColumn>(x => x.ID);
-            if(LoadColumnColumns() is Columns<TColumn> extra)
-            {
-                foreach(var col in extra.GetColumns())
-                {
-                    columnColumns.Add(col);
-                }
-            }
+        var client = Client.Create(typeof(TColumn));
 
-            ColumnData = Client.Query(ColumnFilter(), columnColumns, LoadColumnSort());
-            ActionColumns.Clear();
-            foreach(var columnRow in ColumnData.Rows)
+        var columnColumns = new Columns<TColumn>(x => x.ID);
+        if(LoadColumnColumns() is Columns<TColumn> extra)
+        {
+            foreach(var col in extra.GetColumns())
             {
-                var colID = columnRow.Get<TColumn, Guid>(x => x.ID);
-                ActionColumns.Add(new DynamicImageColumn(
-                    (row) =>
-                    {
-                        if (row is null || ManyToManyData is null) return null;
-                        if(ManyToManyData.TryGetValue(colID, out var rowSet))
-                        {
-                            var rowID = row.Get<TRow, Guid>(x => x.ID);
-                            if (rowSet.ContainsKey(rowID))
-                            {
-                                return tick;
-                            }
-                        }
-                        return null;
-                    },
-                    (row) =>
-                    {
-                        if (row is null) return false;
-                        var rowID = row.Get<TRow, Guid>(x => x.ID);
-                        return CellClick(colID, rowID);
-                    }
-                )
-                {
-                    HeaderText = FormatColumnHeader(columnRow),
-                    ContextMenu = (rows) =>
-                    {
-                        var row = rows?.FirstOrDefault();
-                        if (row is null) return null;
-                        var rowID = row.Get<TRow, Guid>(x => x.ID);
-                        return CellMenu(colID, rowID);
-                    }
-                });
+                columnColumns.Add(col);
             }
-
-            return columns;
         }
 
-        private ContextMenu? CellMenu(Guid colID, Guid rowID)
+        ColumnData = Client.Query(ColumnFilter(), columnColumns, LoadColumnSort());
+        ActionColumns.Clear();
+        foreach(var columnRow in ColumnData.Rows)
         {
-            if (ManyToManyData is null) return null;
-
-            var menu = new ContextMenu();
-
-            if (ManyToManyData.TryGetValue(colID, out var rowSet)
-                && rowSet.TryGetValue(rowID, out var obj))
-            {
-                if (Security.CanEdit<TManyToMany>() && CanEditCell(obj))
+            var colID = columnRow.Get<TColumn, Guid>(x => x.ID);
+            ActionColumns.Add(new DynamicImageColumn(
+                (row) =>
                 {
-                    menu.AddItem("Edit Item", Wpf.Resources.pencil, obj, (obj) =>
+                    if (row is null || ManyToManyData is null) return null;
+                    if(ManyToManyData.TryGetValue(colID, out var rowSet))
                     {
-                        if (EditCell(obj))
+                        var rowID = row.Get<TRow, Guid>(x => x.ID);
+                        if (rowSet.ContainsKey(rowID))
                         {
-                            Refresh(false, true);
+                            return tick;
                         }
-                    });
-                }
-                if (Security.CanDelete<TManyToMany>())
+                    }
+                    return null;
+                },
+                (row) =>
                 {
-                    menu.AddItem("Delete Item", Wpf.Resources.delete, obj, DeleteCell);
+                    if (row is null) return false;
+                    var rowID = row.Get<TRow, Guid>(x => x.ID);
+                    return CellClick(colID, rowID);
                 }
-            }
-            else
+            )
             {
-                if (Security.CanEdit<TManyToMany>())
+                HeaderText = FormatColumnHeader(columnRow),
+                ContextMenu = (rows) =>
                 {
-                    menu.AddItem("Create Item", Wpf.Resources.add, (colID, rowID), CreateCell);
+                    var row = rows?.FirstOrDefault();
+                    if (row is null) return null;
+                    var rowID = row.Get<TRow, Guid>(x => x.ID);
+                    return CellMenu(colID, rowID);
                 }
-            }
+            });
+        }
+
+        return columns;
+    }
+
+    private ContextMenu? CellMenu(Guid colID, Guid rowID)
+    {
+        if (ManyToManyData is null) return null;
+
+        var menu = new ContextMenu();
 
-            if(menu.Items.Count > 0)
+        if (ManyToManyData.TryGetValue(colID, out var rowSet)
+            && rowSet.TryGetValue(rowID, out var obj))
+        {
+            if (Security.CanEdit<TManyToMany>() && CanEditCell(obj))
             {
-                return menu;
+                menu.AddItem("Edit Item", Wpf.Resources.pencil, obj, (obj) =>
+                {
+                    if (EditCell(obj))
+                    {
+                        Refresh(false, true);
+                    }
+                });
             }
-            else
+            if (Security.CanDelete<TManyToMany>())
             {
-                return null;
+                menu.AddItem("Delete Item", Wpf.Resources.delete, obj, DeleteCell);
             }
         }
-
-        private void CreateCell((Guid colID, Guid rowID) obj)
+        else
         {
-            var manyToMany = CreateManyToMany(obj.rowID, obj.colID);
-            if (SaveManyToMany(manyToMany))
+            if (Security.CanEdit<TManyToMany>())
             {
-                Refresh(false, true);
+                menu.AddItem("Create Item", Wpf.Resources.add, (colID, rowID), CreateCell);
             }
         }
 
-        private void DeleteCell(TManyToMany obj)
+        if(menu.Items.Count > 0)
         {
-            if (DeleteManyToMany(obj))
-            {
-                Refresh(false, true);
-            }
+            return menu;
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    private void CreateCell((Guid colID, Guid rowID) obj)
+    {
+        var manyToMany = CreateManyToMany(obj.rowID, obj.colID);
+        if (SaveManyToMany(manyToMany))
+        {
+            Refresh(false, true);
         }
+    }
 
-        protected virtual bool CanEditCell(TManyToMany obj) => false;
-
-        /// <summary>
-        /// Code to edit a <typeparamref name="TManyToMany"/> cell; note that this <b>must not</b> allow for changing either
-        /// the <typeparamref name="TColumn"/> or the <typeparamref name="TRow"/>, otherwise we would easily get duplicate <typeparamref name="TManyToMany"/>s.
-        /// </summary>
-        /// <remarks>
-        /// This method should also save the object.
-        /// </remarks>
-        /// <param name="obj"></param>
-        protected virtual bool EditCell(TManyToMany obj)
+    private void DeleteCell(TManyToMany obj)
+    {
+        if (DeleteManyToMany(obj))
         {
-            return false;
+            Refresh(false, true);
         }
+    }
 
-        private bool CellClick(Guid columnID, Guid rowID)
+    protected virtual bool CanEditCell(TManyToMany obj) => false;
+
+    /// <summary>
+    /// Code to edit a <typeparamref name="TManyToMany"/> cell; note that this <b>must not</b> allow for changing either
+    /// the <typeparamref name="TColumn"/> or the <typeparamref name="TRow"/>, otherwise we would easily get duplicate <typeparamref name="TManyToMany"/>s.
+    /// </summary>
+    /// <remarks>
+    /// This method should also save the object.
+    /// </remarks>
+    /// <param name="obj"></param>
+    protected virtual bool EditCell(TManyToMany obj)
+    {
+        return false;
+    }
+
+    private bool CellClick(Guid columnID, Guid rowID)
+    {
+        if (ManyToManyData is null) return false;
+        if (ManyToManyData.TryGetValue(columnID, out var rowSet)
+            && rowSet.TryGetValue(rowID, out var obj))
         {
-            if (ManyToManyData is null) return false;
-            if (ManyToManyData.TryGetValue(columnID, out var rowSet)
-                && rowSet.TryGetValue(rowID, out var obj))
+            if (Security.CanDelete<TManyToMany>())
             {
-                if (Security.CanDelete<TManyToMany>())
-                {
-                    return DeleteManyToMany(obj);
-                }
-                else
-                {
-                    return false;
-                }
+                return DeleteManyToMany(obj);
             }
             else
             {
-                if (Security.CanEdit<TManyToMany>())
-                {
-                    obj = CreateManyToMany(rowID, columnID);
-                    return SaveManyToMany(obj);
-                }
-                else
-                {
-                    return false;
-                }
+                return false;
             }
         }
-
-        protected virtual TManyToMany CreateManyToMany(Guid rowID, Guid columnID)
+        else
         {
-            var item = new TManyToMany();
-            (rowProperty.GetValue(item) as IEntityLink)!.ID = rowID;
-            (columnProperty.GetValue(item) as IEntityLink)!.ID = columnID;
-            return item;
+            if (Security.CanEdit<TManyToMany>())
+            {
+                obj = CreateManyToMany(rowID, columnID);
+                return SaveManyToMany(obj);
+            }
+            else
+            {
+                return false;
+            }
         }
+    }
 
-        protected virtual bool SaveManyToMany(TManyToMany obj)
-        {
-            Client.Save(obj, "Edited by user");
-            return true;
-        }
+    protected virtual TManyToMany CreateManyToMany(Guid rowID, Guid columnID)
+    {
+        var item = new TManyToMany();
+        (rowProperty.GetValue(item) as IEntityLink)!.ID = rowID;
+        (columnProperty.GetValue(item) as IEntityLink)!.ID = columnID;
+        return item;
+    }
 
-        protected virtual bool DeleteManyToMany(TManyToMany obj)
-        {
-            Client.Delete(obj, "Deleted by user");
-            return true;
-        }
+    protected virtual bool SaveManyToMany(TManyToMany obj)
+    {
+        Client.Save(obj, "Edited by user");
+        return true;
+    }
 
-        protected override void Reload(Filters<TRow> criteria, Columns<TRow> columns, ref SortOrder<TRow>? sort, Action<CoreTable?, Exception?> action)
-        {
-            var filter = criteria.Add(RowFilter()).Combine();
+    protected virtual bool DeleteManyToMany(TManyToMany obj)
+    {
+        Client.Delete(obj, "Deleted by user");
+        return true;
+    }
 
-            var manyToManyColumns = new Columns<TManyToMany>(x => x.ID);
-            manyToManyColumns.Add(rowProperty.Name + ".ID").Add(columnProperty.Name + ".ID");
+    protected override void Reload(Filters<TRow> criteria, Columns<TRow> columns, ref SortOrder<TRow>? sort, Action<CoreTable?, Exception?> action)
+    {
+        var filter = criteria.Add(RowFilter()).Combine();
+
+        var manyToManyColumns = new Columns<TManyToMany>(x => x.ID);
+        manyToManyColumns.Add(rowProperty.Name + ".ID").Add(columnProperty.Name + ".ID");
 
-            Client.QueryMultiple(
-                (results, e) =>
+        Client.QueryMultiple(
+            (results, e) =>
+            {
+                if(e is not null)
+                {
+                    action(null, e);
+                }
+                else
                 {
-                    if(e is not null)
+                    var manyToManyTable = results!.Get<TManyToMany>();
+
+                    ManyToManyData = new Dictionary<Guid, Dictionary<Guid, TManyToMany>>();
+                    foreach(var row in manyToManyTable.Rows)
                     {
-                        action(null, e);
+                        var obj = row.ToObject<TManyToMany>();
+                        var rowID = (rowProperty.GetValue(obj) as IEntityLink)!.ID;
+                        var colID = (columnProperty.GetValue(obj) as IEntityLink)!.ID;
+                        var rowSet = ManyToManyData.GetValueOrAdd(colID);
+                        rowSet[rowID] = obj;
                     }
-                    else
-                    {
-                        var manyToManyTable = results!.Get<TManyToMany>();
 
-                        ManyToManyData = new Dictionary<Guid, Dictionary<Guid, TManyToMany>>();
-                        foreach(var row in manyToManyTable.Rows)
-                        {
-                            var obj = row.ToObject<TManyToMany>();
-                            var rowID = (rowProperty.GetValue(obj) as IEntityLink)!.ID;
-                            var colID = (columnProperty.GetValue(obj) as IEntityLink)!.ID;
-                            var rowSet = ManyToManyData.GetValueOrAdd(colID);
-                            rowSet[rowID] = obj;
-                        }
-
-                        action(results!.Get<TRow>(), null);
-                    }
-                },
-                new KeyedQueryDef<TRow>(filter, columns, sort),
-                new KeyedQueryDef<TManyToMany>(
-                    new Filter<TManyToMany>(rowProperty.Name + ".ID").InQuery(filter, x => x.ID)
-                        .And(columnProperty.Name + ".ID").InQuery(ColumnFilter(), x => x.ID),
-                    manyToManyColumns));
-        }
+                    action(results!.Get<TRow>(), null);
+                }
+            },
+            new KeyedQueryDef<TRow>(filter, columns, sort),
+            new KeyedQueryDef<TManyToMany>(
+                new Filter<TManyToMany>(rowProperty.Name + ".ID").InQuery(filter, x => x.ID)
+                    .And(columnProperty.Name + ".ID").InQuery(ColumnFilter(), x => x.ID),
+                manyToManyColumns));
+    }
 
-        public override void SaveItem(TRow item)
-        {
-            // Never should get called.
-        }
+    public override void SaveItem(TRow item)
+    {
+        // Never should get called.
+    }
 
-        public override void DeleteItems(params CoreRow[] rows)
-        {
-            // Never should get called.
-        }
+    public override void DeleteItems(params CoreRow[] rows)
+    {
+        // Never should get called.
+    }
 
-        public override TRow LoadItem(CoreRow row)
-        {
-            var id = row.Get<TRow, Guid>(x => x.ID);
-            return Client.Query(
-                new Filter<TRow>(x => x.ID).IsEqualTo(id),
-                DynamicGridUtils.LoadEditorColumns(DataColumns()))
-                .ToObjects<TRow>()
-                .FirstOrDefault() ?? throw new Exception($"No {typeof(TRow).Name} with ID {id}");
-        }
+    public override TRow LoadItem(CoreRow row)
+    {
+        var id = row.Get<TRow, Guid>(x => x.ID);
+        return Client.Query(
+            new Filter<TRow>(x => x.ID).IsEqualTo(id),
+            DynamicGridUtils.LoadEditorColumns(DataColumns()))
+            .ToObjects<TRow>()
+            .FirstOrDefault() ?? throw new Exception($"No {typeof(TRow).Name} with ID {id}");
     }
 }

+ 59 - 8
inabox.wpf/DynamicGrid/UIComponent/DynamicGridGridUIComponent.cs

@@ -747,9 +747,10 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                 else if (column is DynamicTemplateColumn tmplCol)
                 {
                     var newcol = new GridTemplateColumn();
-                    newcol.CellTemplateSelector = new TemplateColumnSelector() { DataTemplate = tmplCol.Template };
+                    newcol.CellTemplateSelector = new TemplateColumnSelector(this, tmplCol.Template);
                     newcol.AllowEditing = false;
                     newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
+                    newcol.MappingName = sColName;
                     
                     newcol.Width = tmplCol.Width;
                     newcol.ColumnSizer = GridLengthUnitType.None;
@@ -769,10 +770,31 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                     headstyle.Setters.Add(new Setter(Control.BackgroundProperty, new SolidColorBrush(Colors.Gainsboro)));
                     headstyle.Setters.Add(new Setter(Control.ForegroundProperty, new SolidColorBrush(Colors.Black)));
                     headstyle.Setters.Add(new Setter(Control.FontSizeProperty, 12D));
-                    headstyle.Setters.Add(new Setter(Control.MarginProperty, new Thickness(0, -0.75, 0, 0.75)));
-                    headstyle.Setters.Add(new Setter(Control.BorderThicknessProperty, new Thickness(0.75)));
+                    headstyle.Setters.Add(new Setter(Control.MarginProperty, new Thickness(0, 0, 0.75, 0.75)));
+                    headstyle.Setters.Add(new Setter(Control.BorderThicknessProperty, new Thickness(0.0)));
                     newcol.HeaderStyle = headstyle;
 
+                    var cellstyle = new Style();
+                    cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
+                        new Binding()
+                        {
+                            Path = new PropertyPath("."), Converter = CellBackgroundConverter,
+                            ConverterParameter = column
+                        }));
+                    cellstyle.Setters.Add(new Setter(Control.ForegroundProperty,
+                        new Binding()
+                            { Converter = CellForegroundConverter, ConverterParameter = column }));
+                    cellstyle.Setters.Add(new Setter(Control.FontSizeProperty,
+                        new Binding()
+                            { Converter = CellFontSizeConverter, ConverterParameter = column }));
+                    cellstyle.Setters.Add(new Setter(Control.FontStyleProperty,
+                        new Binding()
+                            { Converter = CellFontStyleConverter, ConverterParameter = column }));
+                    cellstyle.Setters.Add(new Setter(Control.FontWeightProperty,
+                        new Binding()
+                            { Converter = CellFontWeightConverter, ConverterParameter = column }));
+                    newcol.CellStyle = cellstyle;
+
                     DataGrid.Columns.Add(newcol);
                     ColumnList.Add(column);
                 }
@@ -780,12 +802,41 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         }
     }
 
-    public class TemplateColumnSelector : DataTemplateSelector
+    public class TemplateColumnSelector(DynamicGridGridUIComponent<T> parent, Func<CoreRow, FrameworkElement> dataTemplate) : DataTemplateSelector
     {
-        public Func<FrameworkElement> DataTemplate { get; init; }
-        
-        public override DataTemplate SelectTemplate(object item, DependencyObject container) 
-            => TemplateGenerator.CreateDataTemplate(DataTemplate);
+        public Func<CoreRow, FrameworkElement> DataTemplate { get; init; } = dataTemplate;
+
+        public DynamicGridGridUIComponent<T> Parent { get; init; } = parent;
+
+        public override DataTemplate? SelectTemplate(object item, DependencyObject container)
+        {
+            if (item is not DataRowView) return null;
+
+            CoreRow? row;
+            if(item is DataRowView view && Parent.DataGridItems is DataTable table)
+            {
+                var rowIdx = table.Rows.IndexOf(view.Row);
+                if (rowIdx < 0)
+                {
+                    row = null;
+                }
+                else
+                {
+                    row = Parent.Parent.Data.Rows[rowIdx];
+                }
+            }
+            else
+            {
+                row = null;
+            }
+
+            if (row is null) return null;
+
+            return TemplateGenerator.CreateDataTemplate(() =>
+            {
+                return DataTemplate(row);
+            });
+        }
     }
 
     private void ApplyFilterStyle(GridColumn column, bool filtering, bool isactioncolumn)

+ 21 - 8
inabox.wpf/DynamicGrid/UIComponent/DynamicGridTreeUIComponent.cs

@@ -628,12 +628,25 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         }
     }
 
-    public class TemplateColumnSelector : DataTemplateSelector
+    public class TemplateColumnSelector(DynamicGridTreeUIComponent<T> parent, Func<CoreRow, FrameworkElement> dataTemplate) : DataTemplateSelector
     {
-        public Func<FrameworkElement> DataTemplate { get; init; }
-        
-        public override DataTemplate SelectTemplate(object item, DependencyObject container) 
-            => TemplateGenerator.CreateDataTemplate(DataTemplate);
+        public Func<CoreRow, FrameworkElement> DataTemplate { get; init; } = dataTemplate;
+
+        public DynamicGridTreeUIComponent<T> Parent { get; init; } = parent;
+
+        public override DataTemplate? SelectTemplate(object item, DependencyObject container)
+        {
+            if (item is not CoreTreeNode node) return null;
+
+            var row = Parent.MapRow(node.Row);
+
+            if (row is null) return null;
+
+            return TemplateGenerator.CreateDataTemplate(() =>
+            {
+                return DataTemplate(row);
+            });
+        }
     }
 
     private void LoadActionColumns(DynamicActionColumnPosition position)
@@ -649,7 +662,7 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                 {
                     var newcol = new TreeGridTemplateColumn();
 
-                    newcol.CellTemplateSelector = new TemplateColumnSelector() { DataTemplate = () =>
+                    newcol.CellTemplateSelector = new TemplateColumnSelector(this, row =>
                     {
                         var image = new Image
                         {
@@ -658,7 +671,7 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                         };
                         image.SetBinding(Image.SourceProperty, new Binding(sColName));
                         return image;
-                    } };
+                    });
 
                     newcol.AllowEditing = false;
                     newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
@@ -759,7 +772,7 @@ public class DynamicGridTreeUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                 else if (column is DynamicTemplateColumn tmplCol)
                 {
                     var newcol = new TreeGridTemplateColumn();
-                    newcol.CellTemplateSelector = new TemplateColumnSelector() { DataTemplate = tmplCol.Template };
+                    newcol.CellTemplateSelector = new TemplateColumnSelector(this, tmplCol.Template);
                     newcol.AllowEditing = false;
                     newcol.UpdateTrigger = UpdateSourceTrigger.PropertyChanged;
                     

+ 2 - 2
inabox.wpf/DynamicGrid/UIComponent/IDynamicGridGridUIComponent.cs

@@ -172,9 +172,9 @@ internal static class DynamicGridGridUIComponentExtension
     private static bool FilterByPredicate(CoreRow row, string column, FilterPredicate predicate)
     {
         var value = row[column];
-        var vStr = value?.ToString() ?? "";
+        var vStr = value?.ToString()?.ToLower() ?? "";
         var pValue = predicate.FilterValue;
-        var pStr = pValue?.ToString() ?? "";
+        var pStr = pValue?.ToString()?.ToLower() ?? "";
         return predicate.FilterType switch
         {
             FilterType.Contains => vStr.Contains(pStr),