Ver código fonte

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

frogsoftware 11 meses atrás
pai
commit
0b0bbff042

+ 21 - 8
InABox.Core/CoreTable/CoreTable.cs

@@ -441,20 +441,30 @@ namespace InABox.Core
 
         #region Extract Values
         
-        public IEnumerable<TValue> ExtractValues<TSource, TValue>(Expression<Func<TSource, TValue>> column, bool distinct = true)
+        public TValue[] ExtractValues<TSource, TValue>(Expression<Func<TSource, TValue>> column, bool distinct = true)
         {
-            var result = Rows.Select(r => r.Get(column));
+            var columnIdx = GetColumnIndex(column);
             if (distinct)
-                result = result.Distinct();
-            return result;
+            {
+                return Rows.Select(r => r.Get<TValue>(columnIdx)).Distinct().ToArray();
+            }
+            else
+            {
+                return Rows.ToArray(r => r.Get<TValue>(columnIdx));
+            }
         }
 
-        public IEnumerable<TValue> ExtractValues<TValue>(string column, bool distinct = true)
+        public TValue[] ExtractValues<TValue>(string column, bool distinct = true)
         {
-            var result = Rows.Select(r => r.Get<TValue>(column));
+            var columnIdx = GetColumnIndex(column);
             if (distinct)
-                result = result.Distinct();
-            return result;
+            {
+                return Rows.Select(r => r.Get<TValue>(columnIdx)).Distinct().ToArray();
+            }
+            else
+            {
+                return Rows.ToArray(r => r.Get<TValue>(columnIdx));
+            }
         }
 
         #endregion
@@ -475,6 +485,9 @@ namespace InABox.Core
         public int GetColumnIndex<T>(Expression<Func<T, object>> column)
             => GetColumnIndex(CoreUtils.GetFullPropertyName(column, "."));
 
+        public int GetColumnIndex<T, TValue>(Expression<Func<T, TValue>> column)
+            => GetColumnIndex(CoreUtils.GetFullPropertyName(column, "."));
+
         public int GetColumnIndex(string columnname)
         {
             for (var i = 0; i < Columns.Count; i++)

+ 2 - 2
InABox.Core/ICoreTable.cs

@@ -15,8 +15,8 @@ namespace InABox.Core
 
         void CopyTo(CoreTable table);
         void CopyTo(DataTable table);
-        IEnumerable<TValue> ExtractValues<TSource, TValue>(Expression<Func<TSource, TValue>> column, bool distinct = true);
-        IEnumerable<TValue> ExtractValues<TValue>(string column, bool distinct = true);
+        TValue[] ExtractValues<TSource, TValue>(Expression<Func<TSource, TValue>> column, bool distinct = true);
+        TValue[] ExtractValues<TValue>(string column, bool distinct = true);
         void Filter(Func<CoreRow, bool> predicate);
         void LoadColumns(Type T);
         void LoadDictionary<T, TKey, TValue>(Dictionary<TKey, TValue> dictionary, Expression<Func<T, TKey>> key, Expression<Func<T, TValue>> value);

+ 44 - 0
inabox.wpf/Converters/MultiConverters/MultiFuncConverter.cs

@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace InABox.Wpf;
+
+public class MultiFuncConverter(Func<object?[], object?> convert, Func<object?, object?[]?>? convertBack = null, IValueConverter? wrappedConverter = null) : IMultiValueConverter
+{
+    public Func<object?[], object?> ConvertFunc { get; set; } = convert;
+
+    public Func<object?, object?[]?>? ConvertBackFunc { get; set; } = convertBack;
+
+    public IValueConverter? wrappedConverter = wrappedConverter;
+
+    public object? Convert(object?[] values, Type targetType, object parameter, CultureInfo culture)
+    {
+        var val = ConvertFunc(values);
+        if(wrappedConverter is not null)
+        {
+            return wrappedConverter.Convert(val, targetType, parameter, culture);
+        }
+        else
+        {
+            return val;
+        }
+    }
+
+    public object?[]? ConvertBack(object? value, Type[] targetTypes, object parameter, CultureInfo culture)
+    {
+        if(wrappedConverter is not null)
+        {
+            value = wrappedConverter.Convert(value, typeof(object), parameter, culture);
+        }
+        if(ConvertBackFunc is not null)
+        {
+            return ConvertBackFunc(value);
+        }
+        return null;
+    }
+}

+ 13 - 8
inabox.wpf/DynamicGrid/DynamicDataGrid.cs

@@ -82,7 +82,7 @@ public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid w
 
         ColumnsComponent = new DynamicGridCustomColumnsComponent<TEntity>(this, GetTag());
 
-        MergeBtn = AddButton("Merge", Wpf.Resources.merge.AsBitmapImage(Color.White), DoMerge);
+        MergeBtn = AddButton("Merge", Wpf.Resources.merge.AsBitmapImage(Color.White), MergeClick);
     }
     protected override void DoReconfigure(DynamicGridOptions options)
     {
@@ -587,15 +587,20 @@ public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid w
         return grid.EditItems(new[] { item }, t => children.ContainsKey(t) ? children[t] : null, true);
     }
 
-    private bool DoMerge(Button arg1, CoreRow[] arg2)
+    private bool MergeClick(Button arg1, CoreRow[] rows)
     {
-        if (arg2 == null || arg2.Length <= 1)
+        if (rows == null || rows.Length <= 1)
             return false;
-        var targetid = arg2.Last().Get<TEntity, Guid>(x => x.ID);
-        var target = arg2.Last().ToObject<TEntity>().ToString();
-        var otherids = arg2.Select(r => r.Get<TEntity, Guid>(x => x.ID)).Where(x => x != targetid).ToArray();
-        string[] others = arg2.Where(r => otherids.Contains(r.Get<Guid>("ID"))).Select(x => x.ToObject<TEntity>().ToString()!).ToArray();
-        var rows = arg2.Length;
+        return DoMerge(rows);
+    }
+
+    protected virtual bool DoMerge(CoreRow[] rows)
+    {
+        var targetid = rows.Last().Get<TEntity, Guid>(x => x.ID);
+        var target = rows.Last().ToObject<TEntity>().ToString();
+        var otherids = rows.Select(r => r.Get<TEntity, Guid>(x => x.ID)).Where(x => x != targetid).ToArray();
+        string[] others = rows.Where(r => otherids.Contains(r.Get<Guid>("ID"))).Select(x => x.ToObject<TEntity>().ToString()!).ToArray();
+        var nRows = rows.Length;
         if (MessageBox.Show(
                 string.Format(
                     "This will merge the following items:\n\n- {0}\n\n into:\n\n- {1}\n\nAfter this, the items will be permanently removed.\nAre you sure you wish to do this?",

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

@@ -1022,7 +1022,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
         UIComponent.BeforeRefresh();
 
-        var cursor = UseWaitCursor ? new WaitCursor() : null;
+        using var cursor = UseWaitCursor ? new WaitCursor() : null;
 
         Loading.Visibility = Visibility.Visible;
         Loading.BeginAnimation(Label.OpacityProperty, LoadingFader);
@@ -1103,12 +1103,6 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
             Loading.BeginAnimation(Label.OpacityProperty, null);
             Loading.Visibility = Visibility.Collapsed;
         }
-
-        if (cursor != null)
-        {
-            cursor.Dispose();
-            cursor = null;
-        }
     }
 
     public void Shutdown()

+ 67 - 132
inabox.wpf/DynamicGrid/UIComponent/DynamicGridGridUIComponent.cs

@@ -1,5 +1,7 @@
 using InABox.Clients;
 using InABox.Core;
+using InABox.Scripting;
+using InABox.Wpf;
 using InABox.WPF;
 using org.omg.PortableInterceptor;
 using Syncfusion.Data;
@@ -883,6 +885,40 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
     private ObservableCollection<ISummaryColumn> Summaries = new();
 
+    private void AddCellStyleConverters(Style cellstyle, DynamicColumnBase column, string sColName)
+    {
+        cellstyle.Setters.Add(new Setter(Control.BackgroundProperty,
+            WPFUtils.CreateMultiBinding(
+                CellBackgroundConverter.WrapConverter(x => x[0]),
+                parameter: new DynamicGridCellStyleParameters(column, DependencyProperty.UnsetValue))
+                .AddBinding(new Binding("."))
+                .AddBinding(new Binding(sColName))));
+        cellstyle.Setters.Add(new Setter(Control.ForegroundProperty,
+            WPFUtils.CreateMultiBinding(
+                CellForegroundConverter.WrapConverter(x => x[0]),
+                parameter: new DynamicGridCellStyleParameters(column, DependencyProperty.UnsetValue))
+                .AddBinding(new Binding("."))
+                .AddBinding(new Binding(sColName))));
+        cellstyle.Setters.Add(new Setter(Control.FontSizeProperty,
+            WPFUtils.CreateMultiBinding(
+                CellFontSizeConverter.WrapConverter(x => x[0]),
+                parameter: new DynamicGridCellStyleParameters(column, DependencyProperty.UnsetValue))
+                .AddBinding(new Binding("."))
+                .AddBinding(new Binding(sColName))));
+        cellstyle.Setters.Add(new Setter(Control.FontStyleProperty,
+            WPFUtils.CreateMultiBinding(
+                CellFontStyleConverter.WrapConverter(x => x[0]),
+                parameter: new DynamicGridCellStyleParameters(column, DependencyProperty.UnsetValue))
+                .AddBinding(new Binding("."))
+                .AddBinding(new Binding(sColName))));
+        cellstyle.Setters.Add(new Setter(Control.FontWeightProperty,
+            WPFUtils.CreateMultiBinding(
+                CellFontWeightConverter.WrapConverter(x => x[0]),
+                parameter: new DynamicGridCellStyleParameters(column, DependencyProperty.UnsetValue))
+                .AddBinding(new Binding("."))
+                .AddBinding(new Binding(sColName))));
+    }
+
     private void LoadActionColumns(DynamicActionColumnPosition position)
     {
         for (var i = 0; i < ActionColumns.Count; i++)
@@ -968,38 +1004,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                     newcol.HeaderStyle = GetHeaderCellStyle(column);
                     
                     var cellstyle = new Style();
-                    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)
-                        }));
+                    AddCellStyleConverters(cellstyle, column, sColName);
                     newcol.CellStyle = cellstyle;
 
                     DataGrid.Columns.Add(newcol);
@@ -1008,7 +1013,27 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                 else if (column is DynamicTemplateColumn tmplCol)
                 {
                     var newcol = new GridTemplateColumn();
-                    newcol.CellTemplateSelector = new TemplateColumnSelector(this, tmplCol.Template);
+                    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;
@@ -1031,37 +1056,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                     newcol.HeaderStyle = GetHeaderCellStyle(column);
 
                     var cellstyle = new Style();
-                    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)
-                        }));
+                    AddCellStyleConverters(cellstyle, column, sColName);
                     newcol.CellStyle = cellstyle;
 
                     DataGrid.Columns.Add(newcol);
@@ -1098,43 +1093,6 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         }
     }
 
-    public class TemplateColumnSelector(DynamicGridGridUIComponent<T> parent, Func<CoreRow, FrameworkElement?> dataTemplate) : DataTemplateSelector
-    {
-        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)
     {
         var filterstyle = new Style();
@@ -1215,36 +1173,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
                 }
                 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)
-                        }));
+                    AddCellStyleConverters(cellstyle, column, newColumn.MappingName);
                     newColumn.CellStyle = cellstyle;
                 }
                 
@@ -1416,11 +1345,17 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         foreach (var ac in ActionColumns)
             rowdata.Add(ac.Data(row));
 
+        //DataGridItems.Rows.RemoveAt(row.Index);
+
+        //var datarow = DataGridItems.NewRow();
         var datarow = DataGridItems.Rows[row.Index];
+
         for (var i = 0; i < rowdata.Count; i++)
             datarow[i] = rowdata[i] ?? DBNull.Value;
+
+        //DataGridItems.Rows.InsertAt(datarow, row.Index);
+
         _invalidating = false;
-        //datarow.ItemArray = rowdata.ToArray(); 
     }
 
     private void CoreRowToDataRow(DataRow newrow, CoreRow row, List<object?> defaults)

+ 28 - 0
inabox.wpf/WPFUtils.cs

@@ -7,6 +7,7 @@ using System.Windows.Controls;
 using System.Windows.Data;
 using System.Windows.Media;
 using InABox.Core;
+using InABox.Wpf;
 using Image = System.Windows.Controls.Image;
 
 namespace InABox.WPF;
@@ -59,6 +60,25 @@ public static class WPFUtils
         return new SolidColorBrush(color) { Opacity = opacity };
     }
 
+    #region Multi-Binding
+
+    public static MultiBinding CreateMultiBinding(IMultiValueConverter? converter = null, string? format = null, object? parameter = null)
+    {
+        return new MultiBinding
+        {
+            Converter = converter,
+            ConverterParameter = parameter,
+            StringFormat = format
+        };
+    }
+    public static MultiBinding AddBinding(this MultiBinding multi, BindingBase binding)
+    {
+        multi.Bindings.Add(binding);
+        return multi;
+    }
+
+    #endregion
+
     #region Binding
 
     public static Binding CreateBinding<T, TProperty>(
@@ -170,6 +190,14 @@ public static class WPFUtils
 
     #endregion
 
+    #region Converters
+
+    public static IMultiValueConverter WrapConverter(this IValueConverter converter, Func<object?[], object?> convert, Func<object?, object?[]?>? convertBack = null)
+    {
+        return new MultiFuncConverter(convert, convertBack, converter);
+    }
+
+    #endregion
 
     public static T? FindLogicalParent<T>(this DependencyObject dependencyObject)
         where T : DependencyObject