Explorar o código

Changed interface for allowing re-ordering rows.

Kenric Nugteren hai 7 meses
pai
achega
ab7efafa8c

+ 11 - 0
InABox.Core/CoreTable/CoreRow.cs

@@ -336,6 +336,17 @@ namespace InABox.Core
             return rows.Select(x => x.ToObject<T>());
         }
 
+        public static List<T> ToList<T>(this IList<CoreRow> rows)
+            where T : BaseObject, new()
+        {
+            var result = new List<T>(rows.Count);
+            for (var i = 0; i < rows.Count; ++i)
+            {
+                result.Add(rows[i].ToObject<T>());
+            }
+            return result;
+        }
+
         public static T[] ToArray<T>(this IList<CoreRow> rows)
             where T : BaseObject, new()
         {

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

@@ -641,16 +641,13 @@ public class DynamicDataGrid<TEntity> : DynamicGrid<TEntity>, IDynamicDataGrid w
         return rows.Select(x => x.ToObject<TEntity>());
     }
 
-    protected override bool BeforePaste(IEnumerable<TEntity> items, ClipAction action)
+    protected override bool BeforeCopy(IList<TEntity> items)
     {
-        if (action == ClipAction.Copy)
-        {
-            foreach (var item in items)
-                item.ID = Guid.Empty;
-            return true;
-        }
+        if (!base.BeforeCopy(items)) return false;
 
-        return base.BeforePaste(items, action);
+        foreach (var item in items)
+            item.ID = Guid.Empty;
+        return true;
     }
 
     protected override void CustomiseExportFilters(Filters<TEntity> filters, CoreRow[] visiblerows)

+ 50 - 112
inabox.wpf/DynamicGrid/DynamicGrid.cs

@@ -65,17 +65,16 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     bool IDynamicGridUIComponentParent<T>.IsRefreshing => bRefreshing;
 
     private readonly Label ClipboardSpacer;
-
     private readonly Button Copy;
 
     private readonly Label Count;
 
-    private readonly Button Cut;
     private readonly Border Disabler;
 
+    private readonly DynamicActionColumn? drag;
+
     private readonly Button Delete;
     private readonly DockPanel Docker;
-    private readonly DynamicRowMovementColumn? down;
     private readonly Button Edit;
     private readonly Label EditSpacer;
     private readonly Button Export;
@@ -91,17 +90,12 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     private DoubleAnimation LoadingFader = new DoubleAnimation(1d, 0.2d, new Duration(TimeSpan.FromSeconds(2))) { AutoReverse = true };
 
-    //private readonly Button MultiEdit;
-    private readonly Button Paste;
-
     private readonly Button Print;
     private readonly Label PrintSpacer;
 
     private readonly StackPanel LeftButtonStack;
     private readonly StackPanel RightButtonStack;
 
-    private readonly DynamicRowMovementColumn? up;
-
     protected DynamicGridRowStyleSelector<T> RowStyleSelector;
 
     #region Events
@@ -205,12 +199,10 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
         HiddenColumns = new HiddenColumnsList();
 
-        if (ShowSequenceButtons)
+        drag = new DynamicImageColumn(InABox.Wpf.Resources.drag.AsBitmapImage()) { Position = DynamicActionColumnPosition.Start };
+        ActionColumns.Add(drag);
+        if (typeof(T).IsAssignableTo(typeof(ISequenceable)))
         {
-            up = new DynamicRowMovementColumn(DynamicRowMovement.Up, SwapRows);
-            ActionColumns.Add(up);
-            down = new DynamicRowMovementColumn(DynamicRowMovement.Down, SwapRows);
-            ActionColumns.Add(down);
             HiddenColumns.Add(x => (x as ISequenceable)!.Sequence);
         }
 
@@ -261,18 +253,10 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
         PrintSpacer = new Label { Width = 5 };
 
-        Cut = CreateButton(Wpf.Resources.cut.AsBitmapImage(Color.White));
-        Cut.Margin = new Thickness(0, 2, 2, 0);
-        Cut.Click += Cut_Click;
-
-        Copy = CreateButton(Wpf.Resources.copy.AsBitmapImage(Color.White));
+        Copy = CreateButton(Wpf.Resources.duplicate.AsBitmapImage(Color.White), tooltip: "Duplicate Rows");
         Copy.Margin = new Thickness(0, 2, 2, 0);
         Copy.Click += Copy_Click;
 
-        Paste = CreateButton(Wpf.Resources.paste.AsBitmapImage(Color.White));
-        Paste.Margin = new Thickness(0, 2, 2, 0);
-        Paste.Click += Paste_Click;
-
         ClipboardSpacer = new Label { Width = 5 };
 
         Export = CreateButton(Wpf.Resources.doc_xls.AsBitmapImage(Color.White), "Export");
@@ -300,9 +284,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         LeftButtonStack.Children.Add(Print);
         LeftButtonStack.Children.Add(PrintSpacer);
 
-        LeftButtonStack.Children.Add(Cut);
         LeftButtonStack.Children.Add(Copy);
-        LeftButtonStack.Children.Add(Paste);
         LeftButtonStack.Children.Add(ClipboardSpacer);
 
         LeftButtonStack.Children.Add(Export);
@@ -390,12 +372,12 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     bool IDynamicGridUIComponentParent<T>.CanFilter()
     {
-        return !ShowSequenceButtons || !Options.EditRows;
+        return !Options.ReorderRows || !Options.EditRows;
     }
 
     bool IDynamicGridUIComponentParent<T>.CanSort()
     {
-        return !ShowSequenceButtons || !Options.EditRows;
+        return !Options.ReorderRows || !Options.EditRows;
     }
 
     T IDynamicGrid<T>.LoadItem(CoreRow row) => LoadItem(row);
@@ -430,7 +412,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     void IDynamicGridUIComponentParent<T>.HandleKey(KeyEventArgs e)
     {
-        if (ShowSequenceButtons)
+        if (Options.ReorderRows)
         {
             if (e.Key == Key.X && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
             {
@@ -653,8 +635,6 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
     private static bool IsSequenced => typeof(T).GetInterfaces().Any(x => x.Equals(typeof(ISequenceable)));
 
-    protected virtual bool ShowSequenceButtons => IsSequenced;
-
     public double RowHeight
     {
         get => UIComponent.RowHeight;
@@ -694,10 +674,8 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         Print.Visibility = Options.Print ? Visibility.Visible : Visibility.Collapsed;
         PrintSpacer.Visibility = Options.Print ? Visibility.Visible : Visibility.Collapsed;
 
-        Cut.Visibility = ShowSequenceButtons && Options.EditRows ? Visibility.Visible : Visibility.Collapsed;
-        Copy.Visibility = ShowSequenceButtons && Options.EditRows ? Visibility.Visible : Visibility.Collapsed;
-        Paste.Visibility = ShowSequenceButtons && Options.EditRows ? Visibility.Visible : Visibility.Collapsed;
-        ClipboardSpacer.Visibility = ShowSequenceButtons && Options.EditRows ? Visibility.Visible : Visibility.Collapsed;
+        Copy.Visibility = Options.ReorderRows ? Visibility.Visible : Visibility.Collapsed;
+        ClipboardSpacer.Visibility = Options.ReorderRows ? Visibility.Visible : Visibility.Collapsed;
 
         Export.Visibility = Options.ExportData ? Visibility.Visible : Visibility.Collapsed;
         Import.Visibility = Options.ImportData ? Visibility.Visible : Visibility.Collapsed;
@@ -715,14 +693,12 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
 
         Delete.Visibility = Options.DeleteRows ? Visibility.Visible : Visibility.Collapsed;
 
-        if (up != null && down != null)
+        if (drag is not null)
         {
-            var hasSequence = up.Position == DynamicActionColumnPosition.Start;
-            var shouldHaveSequence = Options.EditRows;
-            if(hasSequence != shouldHaveSequence)
+            var hasSequence = drag.Position == DynamicActionColumnPosition.Start;
+            if(hasSequence != Options.ReorderRows)
             {
-                up.Position = Options.EditRows ? DynamicActionColumnPosition.Start : DynamicActionColumnPosition.Hidden;
-                down.Position = Options.EditRows ? DynamicActionColumnPosition.Start : DynamicActionColumnPosition.Hidden;
+                drag.Position = Options.ReorderRows ? DynamicActionColumnPosition.Start : DynamicActionColumnPosition.Hidden;
                 reloadColumns = true;
             }
         }
@@ -773,7 +749,7 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     public void Reconfigure(DynamicGridOptions options)
     {
         options.BeginUpdate().Clear();
-        options.DragRows = IsSequenced;
+        options.ReorderRows = IsSequenced;
         DoReconfigure(options);
         OnReconfigureEvent(options);
         options.EndUpdate();
@@ -2119,44 +2095,8 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         }
     }
 
-    private bool SwapRows(int row1, int row2)
-    {
-        CoreRow[] rows = Data.Rows.Where(x => x.Index.Equals(row1) || x.Index.Equals(row2)).ToArray();
-        var items = LoadItems(rows);
-        var first = (items.First() as ISequenceable)!;
-        var last = (items.Last() as ISequenceable)!;
-        var iBuf1 = first.Sequence;
-        var iBuf2 = last.Sequence;
-        first.Sequence = iBuf2;
-        last.Sequence = iBuf1;
-        SaveItems(items);
-        return true;
-    }
-
     void IDynamicGridUIComponentParent<T>.MoveRows(InABox.Core.CoreRow[] rows, int index) => MoveRows(rows, index);
 
-    protected virtual void MoveRows(CoreRow[] rows, int index)
-    {
-        var sequence = index < Data.Rows.Count
-            ? Data.Rows[index].Get<ISequenceable, long>(x => x.Sequence)
-            : Data.Rows[^1].Get<ISequenceable, long>(x => x.Sequence) + 1;
-
-        var postRows = Data.Rows.Where(r => !rows.Contains(r) && r.Get<ISequenceable, long>(x => x.Sequence) >= sequence);
-
-        var updates = rows.Concat(postRows).ToObjects<T>().ToArray();
-        foreach (var update in updates)
-        {
-            ((ISequenceable)update).Sequence = sequence;
-            sequence++;
-        }
-
-        if (updates.Length != 0)
-        {
-            SaveItems(updates);
-            Refresh(false, true);
-        }
-    }
-
     #region ClipBuffer
 
     private Tuple<ClipAction, CoreRow[]>? ClipBuffer;
@@ -2183,59 +2123,57 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
         InvalidateGrid();
     }
 
+    protected virtual bool BeforeCopy(IList<T> items)
+    {
+        return true;
+    }
+
     private void PasteFromClipBuffer()
     {
         if (ClipBuffer == null)
             return;
+        var row = SelectedRows.FirstOrDefault();
+        MoveRows(ClipBuffer.Item2, row is not null ? (int)row.Index + 1 : Data.Rows.Count, isCopy: ClipBuffer.Item1 == ClipAction.Copy);
+    }
 
-        if (!ShowSequenceButtons)
-            return;
+    protected virtual void MoveRows(CoreRow[] rows, int index, bool isCopy = false)
+    {
+        if (!Options.ReorderRows || !IsSequenced) return;
 
-        using (new WaitCursor())
+        var items = rows.ToArray<T>();
+        if (isCopy)
         {
-            var updates = ClipBuffer.Item2.Select(x => x.ToObject<T>()).ToList();
-            if (BeforePaste(updates, ClipBuffer.Item1))
+            if (!BeforeCopy(items))
             {
-                var currow = SelectedRows.FirstOrDefault()
-                    ?? Data.Rows.LastOrDefault();
-
-                var sequence = currow != null ? currow.Get<T, long>(c => ((ISequenceable)c).Sequence) : 0;
+                return;
+            }
+        }
 
-                var postrows = Data.Rows.Where(r => !ClipBuffer.Item2.Contains(r) && r.Get<ISequenceable, long>(x => x.Sequence) >= sequence);
-                updates.AddRange(LoadItems(postrows.ToArray()));
+        var sequence = index < Data.Rows.Count
+            ? Data.Rows[index].Get<ISequenceable, long>(x => x.Sequence)
+            : Data.Rows[^1].Get<ISequenceable, long>(x => x.Sequence) + 1;
 
-                foreach (var update in updates)
-                {
-                    sequence++;
-                    ((ISequenceable)update).Sequence = sequence;
-                }
-            }
+        var postRows = Data.Rows.Where(r => !rows.Contains(r) && r.Get<ISequenceable, long>(x => x.Sequence) >= sequence);
 
-            if (updates.Count != 0)
-            {
-                SaveItems(updates);
-                Refresh(false, true);
-            }
+        var updates = items.Concat(postRows.ToObjects<T>()).ToArray();
+        foreach (var update in updates)
+        {
+            ((ISequenceable)update).Sequence = sequence;
+            sequence++;
         }
-    }
 
-    protected virtual bool BeforePaste(IEnumerable<T> items, ClipAction action)
-    {
-        return true;
-    }
-    private void Cut_Click(object sender, RoutedEventArgs e)
-    {
-        CutToClipBuffer();
+        if (updates.Length != 0)
+        {
+            SaveItems(updates);
+            Refresh(false, true);
+        }
     }
 
     private void Copy_Click(object sender, RoutedEventArgs e)
     {
-        CopyToClipBuffer();
-    }
-
-    private void Paste_Click(object sender, RoutedEventArgs e)
-    {
-        PasteFromClipBuffer();
+        var rows = SelectedRows;
+        if (rows.Length == 0) return;
+        MoveRows(rows, rows[^1].Index + 1, isCopy: true);
     }
 
     #endregion

+ 12 - 15
inabox.wpf/DynamicGrid/DynamicGridColumn/DynamicColumnGrid.cs

@@ -15,9 +15,6 @@ public class DynamicColumnGrid : DynamicGrid<DynamicGridColumn>
 
     protected override void Init()
     {
-        ActionColumns.Add(new DynamicRowMovementColumn(DynamicRowMovement.Up, SwapRows));
-        ActionColumns.Add(new DynamicRowMovementColumn(DynamicRowMovement.Down, SwapRows));
-
         var column = MasterColumns.FirstOrDefault(x => string.Equals(x.ColumnName, nameof(DynamicGridColumn.ColumnName)));
         if(column is not null && column.Editor is DynamicColumnNameEditor edit)
         {
@@ -33,7 +30,7 @@ public class DynamicColumnGrid : DynamicGrid<DynamicGridColumn>
         options.EditRows = true;
         options.DeleteRows = true;
 
-        options.DragRows = true;
+        options.ReorderRows = true;
     }
 
     public Type Type { get; set; }
@@ -42,22 +39,21 @@ public class DynamicColumnGrid : DynamicGrid<DynamicGridColumn>
 
     public bool DirectEdit { get; set; }
 
-    private bool SwapRows(int row1, int row2)
-    {
-        var item = Columns[row1];
-        Columns.Remove(item);
-        Columns.Insert(row2, item);
-        return true;
-    }
-
-    protected override void MoveRows(CoreRow[] rows, int index)
+    protected override void MoveRows(CoreRow[] rows, int index, bool isCopy)
     {
         var targetCol = index < Columns.Count ? Columns[index] : null;
  
         var cols = LoadItems(rows);
-        foreach(var col in cols)
+        if (isCopy)
         {
-            Columns.Remove(col);
+            cols = cols.ToArray(x => x.Copy());
+        }
+        else
+        {
+            foreach(var col in cols)
+            {
+                Columns.Remove(col);
+            }
         }
         if(targetCol is not null)
         {
@@ -69,6 +65,7 @@ public class DynamicColumnGrid : DynamicGrid<DynamicGridColumn>
             Columns.AddRange(cols);
         }
         Refresh(false, true);
+        SelectedRows = cols.Select(x => Columns.IndexOf(x)).Select(x => Data.Rows[x]).ToArray();
     }
 
     protected override void DoAdd(bool openEditorOnDirectEdit = false)

+ 13 - 0
inabox.wpf/DynamicGrid/DynamicGridColumn/DynamicGridColumn.cs

@@ -69,6 +69,19 @@ public class DynamicGridColumn : DynamicColumnBase
         return ColumnName;
     }
 
+    public DynamicGridColumn Copy()
+    {
+        return new DynamicGridColumn
+        {
+            ColumnName = ColumnName,
+            Width = Width,
+            Caption = Caption,
+            Format = Format,
+            Alignment = Alignment,
+            Editor = Editor.CloneEditor()
+        };
+    }
+
     public static DynamicGridColumn FromCoreGridColumn(CoreGridColumn column)
     {
         return new DynamicGridColumn

+ 11 - 6
inabox.wpf/DynamicGrid/DynamicGridCommon.cs

@@ -54,6 +54,7 @@ public class DynamicGridOptions
         MultiSelect = false;
         DragSource = false;
         DragTarget = false;
+		ReorderRows = false;
         DirectEdit = false;
         ShowHelp = false;
         Print = false;
@@ -226,21 +227,25 @@ public class DynamicGridOptions
 			}
 		}
 	}
-    private bool _dragRows;
+    private bool _reorderRows;
 	/// <summary>
-	/// Allow dragging rows within this grid.
+	/// Allow re-ordering rows within this grid, including cut+paste functionality, and row dragging.
+	/// This is never <see langword="true"/> if <see cref="EditRows"/> is not enabled.
 	/// </summary>
 	/// <remarks>
 	/// <see cref="DragSource"/> and <see cref="DragTarget"/> deal with external dragging, whereas this deals with internal dragging.
+	/// <br/>
+	/// Note that this requires the <see cref="DynamicGrid{T}.MoveRows(CoreRow[], int)"/> function; the default implementation relies on the items
+	/// being <see cref="ISequenceable"/>, but this can be overriden.
 	/// </remarks>
-    public bool DragRows
+	public bool ReorderRows
 	{
-		get => _dragRows && EditRows;
+		get => _reorderRows && EditRows;
 		set
 		{
-			if(_dragRows != value)
+			if(_reorderRows != value)
 			{
-				_dragRows = value;
+				_reorderRows = value;
 				Changed();
 			}
 		}

+ 6 - 9
inabox.wpf/DynamicGrid/DynamicManyToManyGrid.cs

@@ -427,15 +427,12 @@ public class DynamicManyToManyGrid<TManyToMany, TThis> : DynamicGrid<TManyToMany
         return item.ID != Guid.Empty ? base.LoadEditorPages(item) : new DynamicEditorPages();
     }
 
-    protected override bool BeforePaste(IEnumerable<TManyToMany> items, ClipAction action)
+    protected override bool BeforeCopy(IList<TManyToMany> items)
     {
-        if (action == ClipAction.Copy)
-        {
-            foreach (var item in items)
-            {
-                item.ID = Guid.Empty;
-            }
-        }
-        return base.BeforePaste(items, action);
+        if (!base.BeforeCopy(items)) return false;
+
+        foreach (var item in items)
+            item.ID = Guid.Empty;
+        return true;
     }
 }

+ 6 - 9
inabox.wpf/DynamicGrid/DynamicOneToManyGrid.cs

@@ -360,16 +360,13 @@ public class DynamicOneToManyGrid<TOne, TMany> : DynamicGrid<TMany>,
         return item.ID != Guid.Empty ? base.LoadEditorPages(item) : new DynamicEditorPages();
     }
 
-    protected override bool BeforePaste(IEnumerable<TMany> items, ClipAction action)
+    protected override bool BeforeCopy(IList<TMany> items)
     {
-        if (action == ClipAction.Copy)
-        {
-            foreach (var item in items)
-            {
-                item.ID = Guid.Empty;
-            }
-        }
-        return base.BeforePaste(items, action);
+        if (!base.BeforeCopy(items)) return false;
+
+        foreach (var item in items)
+            item.ID = Guid.Empty;
+        return true;
     }
 
     #endregion

+ 18 - 18
inabox.wpf/DynamicGrid/PDF/PDFEditorControl.xaml

@@ -26,76 +26,76 @@
 
             <Button x:Name="PdfPrint" Click="PdfPrint_Click" Margin="0,0,0,15" Height="40" Width="40"
                     Visibility="Collapsed">
-                <Image Source="pack://application:,,,/Resources/print.png" />
+                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/print.png" />
             </Button>
 
             <Button x:Name="PdfSave" Click="PdfSave_Click" Margin="0,0,0,15" Height="40" Width="40"
                     Visibility="Collapsed">
-                <Image Source="pack://application:,,,/Resources/disk.png" />
+                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/disk.png" />
             </Button>
 
             <Button x:Name="PdfZoomIn" Click="PdfZoomIn_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image Source="pack://application:,,,/Resources/zoomin.png" />
+                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/zoomin.png" />
             </Button>
 
             <Button x:Name="PdfZoomWidth" Click="PdfZoomWidth_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image Source="pack://application:,,,/Resources/pagewidth.png" />
+                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/pagewidth.png" />
             </Button>
 
             <Button x:Name="PdfZoomPage" Click="PdfZoomPage_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image Source="pack://application:,,,/Resources/fullpage.png" />
+                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/fullpage.png" />
             </Button>
 
             <Button x:Name="PdfZoomOut" Click="PdfZoomOut_Click" Margin="0,0,0,15" Height="40" Width="40">
-                <Image Source="pack://application:,,,/Resources/zoomout.png" />
+                <Image Source="pack://application:,,,/InABox.Wpf;component/Resources/zoomout.png" />
             </Button>
 
             <Button x:Name="PdfColor" Click="PdfColor_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image x:Name="PdfColorImage" Source="pack://application:,,,/Resources/palette.png" />
+                <Image x:Name="PdfColorImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/palette.png" />
             </Button>
 
             <Button x:Name="PdfSize" Click="PdfSize_Click" Margin="0,0,0,15" Height="40" Width="40">
-                <Image x:Name="PdfSizeImage" Source="pack://application:,,,/Resources/fontsize.png" />
+                <Image x:Name="PdfSizeImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/fontsize.png" />
             </Button>
 
             <Button x:Name="PdfNone" Click="PdfNone_Click" Margin="0,0,0,15" Height="40" Width="40">
-                <Image x:Name="PdfNoneImage" Source="pack://application:,,,/Resources/hand.png" />
+                <Image x:Name="PdfNoneImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/hand.png" />
             </Button>
 
             <Button x:Name="PdfInk" Click="PdfInk_Click" Margin="0,0,0,2" Height="40" Width="40" Visibility="Collapsed">
-                <Image x:Name="PdfInkImage" Source="pack://application:,,,/Resources/draw.png" />
+                <Image x:Name="PdfInkImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/draw.png" />
             </Button>
             <Button x:Name="PdfLine" Click="PdfLine_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image x:Name="PdfLineImage" Source="pack://application:,,,/Resources/line.png" />
+                <Image x:Name="PdfLineImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/line.png" />
             </Button>
             <Button x:Name="PdfRectangle" Click="PdfRectangle_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image x:Name="PdfRectangleImage" Source="pack://application:,,,/Resources/square.png" />
+                <Image x:Name="PdfRectangleImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/square.png" />
             </Button>
             <Button x:Name="PdfCircle" Click="PdfCircle_Click" Margin="0,0,0,2" Height="40" Width="40">
-                <Image x:Name="PdfCircleImage" Source="pack://application:,,,/Resources/circle.png" />
+                <Image x:Name="PdfCircleImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/circle.png" />
             </Button>
             <Button x:Name="PdfFreeText" Click="PdfFreeText_Click" Margin="0,0,0,10" Height="40" Width="40">
-                <Image x:Name="PdfFreeTextImage" Source="pack://application:,,,/Resources/text.png" />
+                <Image x:Name="PdfFreeTextImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/text.png" />
             </Button>
 
             <Button x:Name="PDFOKStamp" Click="PdfOKStamp_Click" Margin="0,0,0,2" Height="40" Width="40"
                     Visibility="Collapsed">
-                <Image x:Name="PdfOKImage" Source="pack://application:,,,/Resources/tick.png" />
+                <Image x:Name="PdfOKImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/tick.png" />
             </Button>
             <Button x:Name="PDFWarningStamp" Click="PdfWarningStamp_Click" Margin="0,0,0,2" Height="40" Width="40"
                     Visibility="Collapsed">
-                <Image x:Name="PdfWarningImage" Source="pack://application:,,,/Resources/warning.png" />
+                <Image x:Name="PdfWarningImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/warning.png" />
             </Button>
             <Button x:Name="PDFErrorStamp" Click="PdfErrorStamp_Click" Margin="0,0,0,2" Height="40" Width="40"
                     Visibility="Collapsed">
-                <Image x:Name="PdfErrorImage" Source="pack://application:,,,/Resources/delete.png" />
+                <Image x:Name="PdfErrorImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/delete.png" />
             </Button>
 
         </StackPanel>
 
         <Button x:Name="RefreshPDF" Click="RefreshPDF_Click" Margin="4,0,0,0" Height="40" Width="40" Grid.Column="1"
                 Grid.Row="1">
-            <Image x:Name="RefreshPDFImage" Source="pack://application:,,,/Resources/refresh.png" />
+            <Image x:Name="RefreshPDFImage" Source="pack://application:,,,/InABox.Wpf;component/Resources/refresh.png" />
         </Button>
 
     </Grid>

+ 5 - 5
inabox.wpf/DynamicGrid/UIComponent/DynamicGridGridUIComponent.cs

@@ -555,7 +555,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
         DataGrid.AllowFiltering = Parent.Options.FilterRows && Parent.CanFilter();
         DataGrid.FilterRowPosition = Parent.Options.FilterRows && Parent.CanFilter() ? FilterRowPosition.FixedTop : FilterRowPosition.None;
 
-        if (Parent.Options.DragSource || Parent.Options.DragRows)
+        if (Parent.Options.DragSource || Parent.Options.ReorderRows)
         {
             if (!DataGrid.AllowDraggingRows)
             {
@@ -574,7 +574,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
             }
         }
 
-        if (Parent.Options.DragTarget || Parent.Options.DragRows)
+        if (Parent.Options.DragTarget || Parent.Options.ReorderRows)
         {
             if (!DataGrid.AllowDrop)
             {
@@ -1877,7 +1877,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
     private void RowDragDropController_Drop(object? sender, GridRowDropEventArgs e)
     {
-        if (!Parent.Options.DragRows)
+        if (!Parent.Options.ReorderRows)
         {
             e.Handled = true;
         }
@@ -1886,7 +1886,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
     private void RowDragDropController_Dropped(object? sender, GridRowDroppedEventArgs e)
     {
-        if (!Parent.Options.DragRows)
+        if (!Parent.Options.ReorderRows)
         {
         }
 
@@ -1914,7 +1914,7 @@ public class DynamicGridGridUIComponent<T> : IDynamicGridUIComponent<T>, IDynami
 
     private void RowDragDropController_DragOver(object? sender, GridRowDragOverEventArgs e)
     {
-        if (!Parent.Options.DragRows)
+        if (!Parent.Options.ReorderRows)
         {
             e.Handled = true;
         }

+ 4 - 0
inabox.wpf/InABox.Wpf.csproj

@@ -55,6 +55,7 @@
         <None Remove="Resources\doc-xls.png" />
         <None Remove="Resources\downarrow.png" />
         <None Remove="Resources\download.png" />
+        <None Remove="Resources\drag.png" />
         <None Remove="Resources\draw.png" />
         <None Remove="Resources\edit.png" />
         <None Remove="Resources\filter.png" />
@@ -254,6 +255,9 @@
       <Resource Include="Resources\download.png">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Resource>
+      <Resource Include="Resources\drag.png">
+        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+      </Resource>
       <Resource Include="Resources\draw.png">
         <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       </Resource>

+ 23 - 0
inabox.wpf/Resources.Designer.cs

@@ -9,6 +9,9 @@
 //------------------------------------------------------------------------------
 
 namespace InABox.Wpf {
+    using System;
+    
+    
     /// <summary>
     ///   A strongly-typed resource class, for looking up localized strings, etc.
     /// </summary>
@@ -397,6 +400,16 @@ namespace InABox.Wpf {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap drag {
+            get {
+                object obj = ResourceManager.GetObject("drag", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized resource of type System.Drawing.Bitmap.
         /// </summary>
@@ -407,6 +420,16 @@ namespace InABox.Wpf {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        /// </summary>
+        public static System.Drawing.Bitmap duplicate {
+            get {
+                object obj = ResourceManager.GetObject("duplicate", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized resource of type System.Drawing.Bitmap.
         /// </summary>

+ 6 - 0
inabox.wpf/Resources.resx

@@ -220,9 +220,15 @@
   <data name="download" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>Resources\download.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
+  <data name="drag" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\drag.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
   <data name="draw" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>Resources\draw.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
+  <data name="duplicate" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>Resources\duplicate.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
   <data name="edit" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>Resources\edit.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>

BIN=BIN
inabox.wpf/Resources/drag.png


BIN=BIN
inabox.wpf/Resources/duplicate.png