Pārlūkot izejas kodu

Implemented DynamicGrid drag-and-drop; changed ExpressionEditor single-click to double-click

Kenric Nugteren 2 gadi atpakaļ
vecāks
revīzija
24c0ed95a0

+ 45 - 26
InABox.Core/DataTable.cs

@@ -33,10 +33,28 @@ namespace InABox.Core
     [Serializable]
     public class CoreRow : ICoreRow
     {
+        #region Fields
+
+        [NonSerialized]
         private static Dictionary<int, string> _accessedcolumns = new Dictionary<int, string>();
 
+        [NonSerialized]
         private Dictionary<string, int> _columnindexes = new Dictionary<string, int>();
 
+        #endregion
+
+        #region Properties
+
+        [DoNotSerialize]
+        [field: NonSerialized]
+        public CoreTable Table { get; private set; }
+        public List<object?> Values { get; private set; }
+
+        [DoNotSerialize]
+        public int Index => Table.Rows.IndexOf(this);
+
+        #endregion
+
         protected internal CoreRow(CoreTable owner)
         {
             Table = owner;
@@ -48,11 +66,7 @@ namespace InABox.Core
             get { return new CoreRow[] { }; }
         }
 
-        [DoNotSerialize]
-        public CoreTable Table { get; private set; }
-
         //private DynamicObject rowObject;
-        public List<object?> Values { get; private set; }
 
         public Dictionary<string, object> ToDictionary(string[] exclude)
         {
@@ -62,9 +76,6 @@ namespace InABox.Core
             return result;
         }
 
-        [DoNotSerialize]
-        public int Index => Table.Rows.IndexOf(this);
-
         [DoNotSerialize]
         public object? this[string columnName]
         {
@@ -275,6 +286,33 @@ namespace InABox.Core
     public class CoreTable : ICoreTable //: IEnumerable, INotifyCollectionChanged
     {
 
+        #region Fields
+
+        private List<CoreRow>? rows;
+        private List<CoreColumn> columns = new List<CoreColumn>();
+
+        #endregion
+
+        #region Properties
+
+        public string TableName { get; set; }
+
+        public IList<CoreColumn> Columns { get => columns; }
+        public IList<CoreRow> Rows
+        {
+            get
+            {
+                rows ??= new List<CoreRow>();
+                //this.rows.CollectionChanged += OnRowsCollectionChanged;
+                return rows;
+            }
+        }
+
+        [field: NonSerialized]
+        public Dictionary<string, IList<Action<object, object>?>> Setters { get; } = new Dictionary<string, IList<Action<object, object>?>>();
+
+        #endregion
+
         public CoreTable() : base()
         {
             TableName = "";
@@ -285,12 +323,6 @@ namespace InABox.Core
             LoadColumns(type);
         }
         
-        private IList<CoreRow>? rows;
-
-        public string TableName { get; set; }
-
-        public IList<CoreColumn> Columns { get; } = new List<CoreColumn>();
-
         public void AddColumn<T>(Expression<Func<T, object>> column)
         {
             Columns.Add(
@@ -302,19 +334,6 @@ namespace InABox.Core
             );
         }
         
-        public Dictionary<string, IList<Action<object, object>?>> Setters { get; } = new Dictionary<string, IList<Action<object, object>?>>();
-
-        public IList<CoreRow> Rows
-        {
-            get
-            {
-                rows ??= new List<CoreRow>();
-                //this.rows.CollectionChanged += OnRowsCollectionChanged;
-                return rows;
-            }
-        }
-
-
         public CoreRow NewRow(bool populate = false)
         {
             var result = new CoreRow(this);

+ 52 - 7
InABox.DynamicGrid/DynamicDocumentGrid.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Data;
 using System.Diagnostics;
 using System.IO;
 using System.Linq;
@@ -15,9 +16,10 @@ namespace InABox.DynamicGrid
 
     public delegate String OnGetWatermark(CoreRow row);
     
-    public class DynamicDocumentGrid<TDocument, TEntity> : DynamicManyToManyGrid<TDocument, TEntity>
+    public class DynamicDocumentGrid<TDocument, TEntity, TEntityLink> : DynamicManyToManyGrid<TDocument, TEntity>
         where TEntity : Entity, IPersistent, IRemotable, new()
-        where TDocument : Entity, IEntityDocument, IPersistent, IRemotable, new() // Entity, IPersistent, IRemotable, IManyToMany<TEntity, Document>, new()
+        where TDocument : Entity, IEntityDocument<TEntityLink>, IPersistent, IRemotable, new() // Entity, IPersistent, IRemotable, IManyToMany<TEntity, Document>, new()
+        where TEntityLink : EntityLink<TEntity>, new()
     {
         private DynamicActionColumn supercedecolumn;
 
@@ -35,6 +37,8 @@ namespace InABox.DynamicGrid
 
         public DynamicDocumentGrid()
         {
+            Options.Add(DynamicGridOption.DragTarget);
+
             MultiSelect = false;
             HiddenColumns.Add(x => x.DocumentLink.ID);
             HiddenColumns.Add(x => x.Superceded);
@@ -49,7 +53,7 @@ namespace InABox.DynamicGrid
             return int.MaxValue;
         }
 
-        private BitmapImage SupercededImage(CoreRow row)
+        private BitmapImage SupercededImage(CoreRow? row)
         {
             if (row == null)
                 return Properties.Resources.tick.AsBitmapImage();
@@ -58,7 +62,7 @@ namespace InABox.DynamicGrid
             return Properties.Resources.tick.AsBitmapImage();
         }
 
-        private bool SupercedeDocument(CoreRow row)
+        private bool SupercedeDocument(CoreRow? row)
         {
             var id = row.Get<TDocument, Guid>(x => x.ID);
             var document = WorkingList.FirstOrDefault(x => x.ID.Equals(id));
@@ -67,12 +71,12 @@ namespace InABox.DynamicGrid
             return true;
         }
 
-        private BitmapImage DocumentImage(CoreRow arg)
+        private BitmapImage DocumentImage(CoreRow? arg)
         {
             return Properties.Resources.view.AsBitmapImage();
         }
 
-        private bool ViewDocument(CoreRow row)
+        private bool ViewDocument(CoreRow? row)
         {
             var filename = row.Get<TDocument, string>(x => x.DocumentLink.FileName);
             if (Path.GetExtension(filename).ToUpper().Equals(".PDF"))
@@ -130,7 +134,48 @@ namespace InABox.DynamicGrid
             return false;
         }
 
-        public event OnGetWatermark OnGetWaterMark; 
+        public event OnGetWatermark OnGetWaterMark;
+
+        protected override void OnDragEnd(Type entity, CoreTable table)
+        {
+            if(entity == typeof(Document))
+            {
+                var refresh = false;
+
+                var docIDS = table.Rows.Select(x => x.Get<Document, Guid>(x => x.ID)).ToArray();
+
+                var columns = new Columns<Document>(x => x.ID);
+                foreach(var column in VisibleColumns)
+                {
+                    if (column.ColumnName.StartsWith("DocumentLink."))
+                    {
+                        columns.Add(string.Join('.', column.ColumnName.Split('.').Skip(1)));
+                    }
+                }
+                var docs = new Client<Document>()
+                    .Query(
+                        new Filter<Document>(x => x.ID).InList(docIDS),
+                        columns);
+
+                foreach (var doc in docs.ToObjects<Document>())
+                {
+                    var entityDocument = new TDocument();
+                    entityDocument.EntityLink.ID = Item.ID;
+                    entityDocument.DocumentLink.ID = doc.ID;
+                    entityDocument.DocumentLink.Synchronise(doc);
+                    SaveItem(entityDocument);
+                    refresh = true;
+                }
+                if (refresh)
+                {
+                    Refresh(false, true);
+                }
+            }
+            else
+            {
+                base.OnDragEnd(entity, table);
+            }
+        }
 
         protected override void DoAdd()
         {

+ 111 - 0
InABox.DynamicGrid/DynamicGrid.cs

@@ -32,6 +32,7 @@ using Syncfusion.Windows.Shared;
 using Syncfusion.Windows.Tools.Controls;
 using Syncfusion.XPS;
 using Color = System.Drawing.Color;
+using DataColumn = System.Data.DataColumn;
 using DataRow = System.Data.DataRow;
 using FilterElement = Syncfusion.UI.Xaml.Grid.FilterElement;
 using Geometry = System.Windows.Media.Geometry;
@@ -296,6 +297,22 @@ namespace InABox.DynamicGrid
         }
     }
 
+    [Serializable]
+    class DynamicGridDragFormat
+    {
+        private string entity;
+
+        public DataTable Table { get; set; }
+
+        public Type Entity { get => CoreUtils.GetEntity(entity); set => entity = value.EntityName(); }
+
+        public DynamicGridDragFormat(DataTable table, Type entity)
+        {
+            Table = table;
+            Entity = entity;
+        }
+    }
+
     public abstract class DynamicGrid<T> : BaseDynamicGrid<T> where T : BaseObject, new()
     {
         private readonly Dictionary<string, string> _filterpredicates = new();
@@ -665,6 +682,27 @@ namespace InABox.DynamicGrid
             DataGrid.AllowFiltering = Options.Contains(DynamicGridOption.FilterRows);
             DataGrid.FilterRowPosition = Options.Contains(DynamicGridOption.FilterRows) ? FilterRowPosition.FixedTop : FilterRowPosition.None;
 
+            if (Options.Contains(DynamicGridOption.DragSource))
+            {
+                DataGrid.AllowDraggingRows = true;
+                DataGrid.RowDragDropController.DragStart += RowDragDropController_DragStart;
+            }
+            else if(DataGrid.AllowDraggingRows)
+            {
+                DataGrid.AllowDraggingRows = false;
+                DataGrid.RowDragDropController.DragStart -= RowDragDropController_DragStart;
+            }
+            if (Options.Contains(DynamicGridOption.DragTarget) && !DataGrid.AllowDrop)
+            {
+                DataGrid.Drop += DataGrid_Drop;
+                DataGrid.AllowDrop = true;
+            }
+            else if (DataGrid.AllowDrop)
+            {
+                DataGrid.Drop -= DataGrid_Drop;
+                DataGrid.AllowDrop = false;
+            }
+
             DataGrid.SelectionMode = Options.Contains(DynamicGridOption.MultiSelect) ? GridSelectionMode.Extended : GridSelectionMode.Single;
             if (up != null)
                 up.Position = Options.Contains(DynamicGridOption.EditRows) ? DynamicActionColumnPosition.Start : DynamicActionColumnPosition.Hidden;
@@ -3195,6 +3233,79 @@ namespace InABox.DynamicGrid
 
         #endregion
 
+        #region Drag + Drop
+
+        private static string DragFormat => typeof(DynamicGridDragFormat).FullName ?? "";
+
+        protected virtual void OnDragEnd(Type entity, CoreTable table)
+        {
+        }
+
+        private void DataGrid_Drop(object sender, DragEventArgs e)
+        {
+            if (e.Data.GetDataPresent(DragFormat))
+            {
+                var data = e.Data.GetData(DragFormat) as DynamicGridDragFormat;
+                if(data is not null)
+                {
+                    var table = new CoreTable();
+                    foreach(var column in data.Table.Columns)
+                    {
+                        if(column is DataColumn dataColumn)
+                        {
+                            table.Columns.Add(new CoreColumn { ColumnName = dataColumn.ColumnName, DataType = dataColumn.DataType });
+                        }
+                    }
+                    foreach(var row in data.Table.Rows)
+                    {
+                        if(row is DataRow dataRow)
+                        {
+                            var coreRow = table.NewRow();
+                            coreRow.LoadValues(dataRow.ItemArray);
+                            table.Rows.Add(coreRow);
+                        }
+                    }
+
+                    OnDragEnd(data.Entity, table);
+                }
+            }
+        }
+
+        protected void DragTable(Type entity, CoreTable table)
+        {
+            var data = new DataObject();
+            data.SetData(DragFormat, new DynamicGridDragFormat(table.ToDataTable(), entity));
+
+            DragDrop.DoDragDrop(this, data, DragDropEffects.All);
+        }
+
+        protected virtual void OnRowsDragStart(CoreRow[] rows)
+        {
+            var table = new CoreTable();
+
+            table.LoadColumns(Data.Columns);
+            table.LoadRows(rows);
+
+            DragTable(typeof(T), table);
+        }
+
+        private void RowDragDropController_DragStart(object? sender, GridRowDragStartEventArgs e)
+        {
+            var rows = new List<CoreRow>();
+            foreach(var record in e.DraggingRecords)
+            {
+                var rowIndex = DataGrid.ResolveToRowIndex(record);
+                rows.Add(GetRowFromIndex(rowIndex));
+            }
+
+            var rowArr = rows.ToArray();
+            OnRowsDragStart(rowArr);
+
+            e.Handled = true;
+        }
+
+        #endregion
+
         /* Removed as appears unused; removed as of 19/12/2022
         #region CellRendering
 

+ 1 - 0
InABox.DynamicGrid/DynamicGridUtils.cs

@@ -433,6 +433,7 @@ namespace InABox.DynamicGrid
         }
 
         private static Dictionary<Type, Type[]> _dynamicGrids = new();
+
         public static Type FindDynamicGrid(Type gridType, Type entityType)
         {
             if(!_dynamicGrids.TryGetValue(gridType, out var grids))

+ 4 - 3
InABox.DynamicGrid/DynamicManyToManyGrid.cs

@@ -18,10 +18,11 @@ namespace InABox.DynamicGrid
     }
 
     public class DynamicManyToManyGrid<TManyToMany, TThis> : DynamicGrid<TManyToMany>, IDynamicEditorPage, IDynamicManyToManyGrid<TManyToMany, TThis>
-        where TThis : Entity, new() where TManyToMany : Entity, IPersistent, IRemotable, new()
+        where TThis : Entity, new()
+        where TManyToMany : Entity, IPersistent, IRemotable, new()
     {
         //private Guid ID = Guid.Empty;
-        protected Entity Item;
+        protected TThis Item;
         private TManyToMany[] MasterList = { };
         protected PropertyInfo otherproperty;
 
@@ -82,7 +83,7 @@ namespace InABox.DynamicGrid
 
         public void Load(object item, Func<Type, CoreTable>? PageDataHandler)
         {
-            Item = (Entity)item;
+            Item = (TThis)item;
 
             CoreTable? data = null;
             if (PageDataHandler != null)