Browse Source

Popup Grid Edits - NOT TO PULL

Kenric Nugteren 1 year ago
parent
commit
144482414f

+ 174 - 18
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -14,15 +14,19 @@ using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Data;
+using System.Windows.Documents;
 using System.Windows.Input;
 using System.Windows.Media;
 using System.Windows.Media.Animation;
 using System.Windows.Media.Imaging;
 using System.Windows.Threading;
+using FastReport.DevComponents.AdvTree;
 using InABox.Clients;
 using InABox.Core;
 using InABox.Scripting;
 using InABox.WPF;
+using NPOI.SS.Formula.Functions;
+using Org.BouncyCastle.Crypto;
 using Syncfusion.Data;
 using Syncfusion.UI.Xaml.Grid;
 using Syncfusion.UI.Xaml.Grid.Cells;
@@ -526,6 +530,8 @@ namespace InABox.DynamicGrid
             DataGrid.RowStyleSelector = RowStyleSelector;
             DataGrid.TableSummaryCellStyleSelector = new DynamicGridSummaryStyleSelector(this);
 
+            DataGrid.CellRenderers.Add("PopupRenderer", new DynamicGridPopupColumnRenderer(this));
+
             //DataGrid.MouseMove += DataGrid_MouseMove;
             DataGrid.CellToolTipOpening += DataGrid_CellToolTipOpening;
 
@@ -993,7 +999,7 @@ namespace InABox.DynamicGrid
                 bChanged = true;
         }
 
-        protected void UpdateCell(int row, string colname, object value)
+        protected void UpdateCell(int row, string colname, object? value)
         {
             var datacolname = colname.Replace(".", "_");
             var table = DataGridItems;
@@ -1033,10 +1039,9 @@ namespace InABox.DynamicGrid
             var corerow = Data.Rows[iRow];
             corerow[corecol] = value;
 
-            Dictionary<String, object> changes = new Dictionary<string, object>();
+            var changes = new Dictionary<string, object?>();
             if (DataGrid.Columns[colname] is GridComboBoxColumn combo)
             {
-
                 var prefix = String.Join(".", corecol.Split(".").Reverse().Skip(1).Reverse());
                 var field = corecol.Split(".").Last();
                 var lookups = (combo.ItemsSource as DataView)?.Table;
@@ -1050,14 +1055,29 @@ namespace InABox.DynamicGrid
                             var prop = String.IsNullOrWhiteSpace(prefix)
                                 ? lookupcol.ColumnName
                                 : String.Join(".", new String[] { prefix, lookupcol.ColumnName });
-                            DynamicGridUtils.UpdateEditorValue(new BaseObject[] { inplaceeditor }, prop, lookuprow[lookupcol], changes);
+                            DynamicGridUtils.UpdateEditorValue(new BaseObject[] { obj }, prop, lookuprow[lookupcol], changes);
                             //CoreUtils.SetPropertyValue(obj, prop, lookuprow[lookupcol]);
                         }
                     }
                 }
             }
+            else if (DataGrid.Columns[colname] is DynamicGridPopupColumn popup)
+            {
+                var prefix = String.Join(".", corecol.Split(".").SkipLast(1));
+                var field = corecol.Split(".").Last();
+
+                DynamicGridUtils.UpdateEditorValue(new BaseObject[] { obj }, corecol, value, changes);
+
+                foreach (var column in popup.Editor.OtherColumns.Keys)
+                {
+                    var prop = String.IsNullOrWhiteSpace(prefix)
+                        ? column
+                        : String.Join(".", prefix, column);
+                    DynamicGridUtils.UpdateEditorValue(new BaseObject[] { obj }, prop, corerow[column], changes);
+                }
+            }
             else
-                DynamicGridUtils.UpdateEditorValue(new BaseObject[] { inplaceeditor }, corecol, value, changes);
+                DynamicGridUtils.UpdateEditorValue(new BaseObject[] { obj }, corecol, value, changes);
             //CoreUtils.SetPropertyValue(obj, corecol, value);
 
 
@@ -1601,6 +1621,134 @@ namespace InABox.DynamicGrid
             return !IsSequenced;
         }
 
+        private class DynamicGridPopupColumnRenderer : GridVirtualizingCellRenderer<DynamicGridPopupColumnCell, DynamicGridPopupColumnCell>
+        {
+            public delegate void SelectEvent();
+            public delegate void ClearEvent();
+
+            public event SelectEvent? OnSelect;
+            public event ClearEvent? OnClear;
+
+            public DynamicGrid<T> Grid { get; set; }
+
+            public DynamicGridPopupColumnRenderer(DynamicGrid<T> grid)
+            {
+                Grid = grid;
+            }
+
+            protected override void SetFocus(FrameworkElement uiElement, bool needToFocus)
+            {
+                base.SetFocus(uiElement, needToFocus);
+            }
+
+            private void SetDisplay(DynamicGridPopupColumnCell cell, CoreRow row, DynamicGridPopupColumn col, string columnName)
+            {
+                var linkName = string.Join('.', columnName.Split('.').SkipLast(1));
+                var values = new Dictionary<string, object?>();
+                foreach (var column in row.Table.Columns)
+                {
+                    if (column.ColumnName.StartsWith(linkName + "."))
+                    {
+                        var name = column.ColumnName[(linkName.Length + 1)..];
+                        if (name != "ID")
+                        {
+                            values[name] = row[column.ColumnName];
+                        }
+                    }
+                }
+                cell.Display = LookupFactory.FormatLookup(col.Editor.Type, values, Enumerable.Empty<string>());
+            }
+
+            private void InitializeElement(DataColumnBase dataColumn, DynamicGridPopupColumnCell cell, object dataContext)
+            {
+                if (dataColumn.GridColumn is DynamicGridPopupColumn col && dataContext is DataRowView rowview && Grid.DataGridItems is not null)
+                {
+                    var row = Grid.GetRowFromIndex(dataColumn.RowIndex);
+                    var mapName = dataColumn.GridColumn.MappingName;
+                    var colName = Grid.Data.Columns[Grid.DataGridItems.Columns.IndexOf(mapName)].ColumnName;
+
+                    SetDisplay(cell, row, col, colName);
+
+                    var binding = new Binding
+                    {
+                        Source = dataContext,
+                        Path = new PropertyPath(mapName),
+                        UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
+                    };
+                    cell.SetBinding(DynamicGridPopupColumnCell.ValueProperty, binding);
+
+                    cell.OnValueChanged += (value) =>
+                    {
+                        SetDisplay(cell, row, col, colName);
+                    };
+                    cell.OnClear = () =>
+                    {
+                        var columns = LookupFactory.DefineColumns(col.Editor.Type);
+                        row[colName] = Guid.Empty;
+                        var linkName = string.Join('.', colName.Split('.').SkipLast(1));
+                        foreach (var column in columns.ColumnNames())
+                        {
+                            if(column != "ID")
+                            {
+                                row[linkName + "." + column] = null;
+                            }
+                        }
+                        Grid.InvalidateRow(row);
+
+                        var data = Grid.LoadItem(row);
+                        Grid.UpdateData(data, dataColumn.ColumnIndex);
+                        Grid.UpdateCell(row.Index, colName, Guid.Empty);
+                    };
+                    cell.OnSelect = () =>
+                    {
+                        var columns = LookupFactory.DefineColumns(col.Editor.Type);
+                        var data = Grid.LoadItem(row);
+                        var popupList = new PopupList(col.Editor.Type, (Guid)(row[colName] ?? Guid.Empty), columns.ColumnNames().ToArray());
+                        popupList.OnDefineFilter += t => { return Grid.DefineFilter(t, new T[] { data }); };
+                        if (popupList.ShowDialog() == true)
+                        {
+                            row[colName] = popupList.ID;
+                            var linkName = string.Join('.', colName.Split('.').SkipLast(1));
+                            foreach (var column in columns.ColumnNames())
+                            {
+                                if (column != "ID")
+                                {
+                                    row[linkName + "." + column] = popupList.OtherValues[column];
+                                }
+                            }
+                            Grid.InvalidateRow(row);
+
+                            data = Grid.LoadItem(row);
+                            Grid.UpdateData(data, dataColumn.ColumnIndex);
+                            Grid.UpdateCell(row.Index, colName, Guid.Empty);
+                        }
+                    };
+                }
+            }
+
+            public override void OnInitializeDisplayElement(DataColumnBase dataColumn, DynamicGridPopupColumnCell cell, object dataContext)
+            {
+                base.OnInitializeDisplayElement(dataColumn, cell, dataContext);
+                InitializeElement(dataColumn, cell, dataContext);
+            }
+
+            public override void OnInitializeEditElement(DataColumnBase dataColumn, DynamicGridPopupColumnCell cell, object dataContext)
+            {
+                base.OnInitializeEditElement(dataColumn, cell, dataContext);
+            }
+        }
+
+        private class DynamicGridPopupColumn : GridColumn
+        {
+            public DataLookupEditor Editor { get; set; }
+
+            public DynamicGridPopupColumn(DataLookupEditor editor)
+            {
+                Editor = editor;
+                SetCellType("PopupRenderer");
+            }
+        }
+
         private void ReloadColumns()
         {
 
@@ -1790,23 +1938,31 @@ namespace InABox.DynamicGrid
                     }
                     else if (prop.Editor is ILookupEditor lookupEditor)
                     {
-                        var lookupcol = new GridComboBoxColumn();
-
-                        //var lookups = editor.Values(column.ColumnName).ToDictionary(column.ColumnName, "Display");
-                        //lookupcol.SelectedValuePath = "Key";
-                        //lookupcol.DisplayMemberPath = "Value";
-                        //lookupcol.ItemsSource = lookups;
-
-                        var table = lookupEditor.Values(column.ColumnName).ToDataTable();
-                        lookupcol.SelectedValuePath = table.Columns[0].ColumnName;
-                        lookupcol.DisplayMemberPath = "Display";
-                        lookupcol.ItemsSource = table.DefaultView;
-                        newcol = lookupcol;
+                        if (Options.Contains(DynamicGridOption.DirectEdit) && lookupEditor is PopupEditor popup)
+                        {
+                            var popupcol = new DynamicGridPopupColumn(popup);
+                            newcol = popupcol;
+                        }
+                        else
+                        {
+                            var lookupcol = new GridComboBoxColumn();
+
+                            //var lookups = editor.Values(column.ColumnName).ToDictionary(column.ColumnName, "Display");
+                            //lookupcol.SelectedValuePath = "Key";
+                            //lookupcol.DisplayMemberPath = "Value";
+                            //lookupcol.ItemsSource = lookups;
+
+                            var table = lookupEditor.Values(column.ColumnName).ToDataTable();
+                            lookupcol.SelectedValuePath = table.Columns[0].ColumnName;
+                            lookupcol.DisplayMemberPath = "Display";
+                            lookupcol.ItemsSource = table.DefaultView;
+                            newcol = lookupcol;
+                        }
                     }
                     else
                     {
                         var textcol = new GridTextColumn();
-                        if (!(prop.Editor is MemoEditor))
+                        if (prop.Editor is not MemoEditor)
                             gridRowResizingOptions.ExcludeColumns.Add(scolname);
                         textcol.TextWrapping = TextWrapping.NoWrap;
                         newcol = textcol;

+ 28 - 0
inabox.wpf/DynamicGrid/DynamicGridPopupColumnCell.xaml

@@ -0,0 +1,28 @@
+<UserControl x:Class="InABox.DynamicGrid.DynamicGridPopupColumnCell"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:InABox.DynamicGrid"
+             mc:Ignorable="d" 
+             x:Name="Cell"
+             d:DesignHeight="450" d:DesignWidth="800">
+    <Grid Margin="5">
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="*"/>
+            <ColumnDefinition Width="30"/>
+            <ColumnDefinition Width="50"/>
+        </Grid.ColumnDefinitions>
+        <TextBlock Text="{Binding ElementName=Cell, Path=Display}" VerticalAlignment="Center"/>
+        <Button Grid.Column="1" Content=".."
+                VerticalAlignment="Stretch" VerticalContentAlignment="Center"
+                HorizontalAlignment="Stretch"
+                Margin="5,0,0,0"
+                Click="Select_Click"/>
+        <Button Grid.Column="2" Content="Clear"
+                VerticalAlignment="Stretch" VerticalContentAlignment="Center"
+                HorizontalAlignment="Stretch"
+                Margin="5,0,0,0"
+                Click="Clear_Click"/>
+    </Grid>
+</UserControl>

+ 75 - 0
inabox.wpf/DynamicGrid/DynamicGridPopupColumnCell.xaml.cs

@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace InABox.DynamicGrid
+{
+    /// <summary>
+    /// Interaction logic for DynamicGridPopupColumnCell.xaml
+    /// </summary>
+    public partial class DynamicGridPopupColumnCell : UserControl, INotifyPropertyChanged
+    {
+        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
+            "Value", typeof(Guid), typeof(DynamicGridPopupColumnCell), new FrameworkPropertyMetadata(
+                propertyChangedCallback: new PropertyChangedCallback(Value_Changed)));
+
+        private string _display;
+        public string Display {
+            get => _display;
+            set
+            {
+                _display = value;
+                NotifyPropertyChanged();
+            }
+        }
+
+        public object? Value { get; set; }
+
+        public delegate void SelectEvent();
+        public delegate void ClearEvent();
+        public delegate void ValueChangedEvent(Guid value);
+
+        public SelectEvent? OnSelect;
+        public ClearEvent? OnClear;
+        public ValueChangedEvent? OnValueChanged;
+        public event PropertyChangedEventHandler? PropertyChanged;
+
+        public DynamicGridPopupColumnCell()
+        {
+            InitializeComponent();
+        }
+
+        private void Select_Click(object sender, RoutedEventArgs e)
+        {
+            OnSelect?.Invoke();
+        }
+
+        private void Clear_Click(object sender, RoutedEventArgs e)
+        {
+            OnClear?.Invoke();
+        }
+        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
+        {
+            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+
+        private static void Value_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            var cell = (DynamicGridPopupColumnCell)d;
+            cell.OnValueChanged?.Invoke((Guid)d.GetValue(ValueProperty));
+        }
+    }
+}

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

@@ -359,7 +359,7 @@ namespace InABox.DynamicGrid
 
         
 
-        public static Dictionary<string, object?> UpdateEditorValue(BaseObject[] items, string name, object value)
+        public static Dictionary<string, object?> UpdateEditorValue(BaseObject[] items, string name, object? value)
         {
             Logger.Send(LogType.Information, "", string.Format("DynamicGridUtils.UpdateEditorValue({0},{1},{2})", items.Length, name, value));
             var sw = new Stopwatch();
@@ -414,7 +414,7 @@ namespace InABox.DynamicGrid
             return changes;
         }
 
-        public static void UpdateEditorValue(BaseObject[] items, string name, object value, Dictionary<string, object?> changes)
+        public static void UpdateEditorValue(BaseObject[] items, string name, object? value, Dictionary<string, object?> changes)
         {
             var results = UpdateEditorValue(items, name, value);
             foreach (var key in results.Keys)

+ 1 - 0
inabox.wpf/DynamicGrid/DynamicOneToManyGrid.cs

@@ -207,6 +207,7 @@ namespace InABox.DynamicGrid
             var result = new TMany();
             var prop = (IEntityLink)property.GetValue(result);
             prop.ID = Item.ID;
+            prop.Synchronise(Item);
             return result;
         }