Просмотр исходного кода

Fixed issue with Editor Grids opening up off-screen

frankvandenbos 7 месяцев назад
Родитель
Сommit
21527c74d8

+ 2 - 2
inabox.wpf/DigitalForms/DigitalFormGrid.cs

@@ -413,10 +413,10 @@ namespace InABox.DynamicGrid
             }
         }
 
-        public override bool EditItems(DigitalForm[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null)
+        public override bool EditItems(DigitalForm[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
         {
             // Need to do this to make sure that the variables are available to the layouts (and vice versa?)
-            return base.EditItems(items, PageDataHandler, true, parent);
+            return base.EditItems(items, PageDataHandler, true);
         }
 
         private const string ExportFileFilter = "Excel Files (*.xls, *xlsx)|*.xls;*.xlsx|Digital Forms (*.prs-form)|*.prs-form";

+ 12 - 3
inabox.wpf/DynamicGrid/DynamicEditorForm/DynamicEditorForm.xaml.cs

@@ -100,15 +100,24 @@ public partial class DynamicEditorForm : ThemableChromelessWindow, IDynamicEdito
     public DynamicEditorForm()
     {
         InitializeComponent();
-        
-        //this.Loaded += new RoutedEventHandler(ConfigureSystemMenu);
-
         Form.OnEditorCreated += Editor_OnEditorCreated;
         Form.OnOK += Form_OnOK;
         Form.OnCancel += Form_OnCancel;
         Form.OnFormCustomiseEditor += (sender, items, column, editor) => OnFormCustomiseEditor?.Invoke(sender, items, column, editor);
     }
 
+    private bool _first = true;
+
+    protected override void OnActivated(EventArgs e)
+    {
+        if (_first)
+        {
+            _first = false;
+            this.MoveToCenter();
+        }
+        base.OnActivated(e);
+    }
+
     public DynamicEditorForm(Type type, DynamicEditorPages? pages = null, DynamicEditorButtons? buttons = null,
         Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false): this()
     {

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

@@ -1583,10 +1583,10 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     {
         InitialiseEditorForm(editor, items.Cast<T>().ToArray(), pageDataHandler, preloadPages);
     }
-    public virtual bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null)
+    public virtual bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
     {
         var values = items.Cast<T>().ToArray();
-        return EditItems(values, PageDataHandler, PreloadPages, parent);
+        return EditItems(values, PageDataHandler, PreloadPages);
     }
 
     public virtual void InitialiseEditorForm(IDynamicEditorForm editor, T[] items, Func<Type, CoreTable?>? pageDataHandler = null, bool preloadPages = false)
@@ -1745,19 +1745,16 @@ public abstract class DynamicGrid<T> : DynamicGrid, IDynamicGridUIComponentParen
     /// </summary>
     /// <param name="items">List of objects to edit.</param>
     /// <returns><see langword="true"/> if the items were saved.</returns>
-    public virtual bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null)
+    public virtual bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
     {
-        var owner = Window.GetWindow(parent ?? this);
         DynamicEditorForm editor;
         using (var cursor = new WaitCursor())
         {
-            editor = new DynamicEditorForm()
-            {
-                WindowStartupLocation = WindowStartupLocation.CenterOwner, 
-                Owner = owner
-            };
-            editor.SetValue(Panel.ZIndexProperty, 999);
 
+            editor = new DynamicEditorForm();
+            
+            editor.SetValue(Panel.ZIndexProperty, 999);
+            
             InitialiseEditorForm(editor, items, PageDataHandler, PreloadPages);
             OnEditorLoaded?.Invoke(editor, items);
         }

+ 2 - 3
inabox.wpf/DynamicGrid/DynamicImportGrid.cs

@@ -279,7 +279,7 @@ namespace InABox.DynamicGrid
             return result;
         }
 
-        public override bool EditItems(Importer[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null)
+        public override bool EditItems(Importer[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false)
         {
             if (items.Length != 1)
             {
@@ -287,8 +287,7 @@ namespace InABox.DynamicGrid
                 return false;
             }
 
-            var owner = Window.GetWindow(parent ?? this);
-            var form = new DynamicImportForm(items[0]) { Owner = owner };
+            var form = new DynamicImportForm(items[0]);
             if (form.ShowDialog() == true)
             {
                 SaveItem(items[0]);

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

@@ -50,7 +50,7 @@ public interface IDynamicGrid
     void DoChanged();
 
     void InitialiseEditorForm(IDynamicEditorForm editor, object[] items, Func<Type, CoreTable>? pageDataHandler = null, bool preloadPages = false);
-    bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null);
+    bool EditItems(object[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false);
 
     //bool DirectEdit(CoreTable data);
 
@@ -120,5 +120,5 @@ public interface IDynamicGrid<T> : IDynamicGrid
 
     void DeleteItems(CoreRow[] rows);
 
-    bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false, DependencyObject? parent = null);
+    bool EditItems(T[] items, Func<Type, CoreTable?>? PageDataHandler = null, bool PreloadPages = false);
 }

+ 108 - 2
inabox.wpf/WPFUtils.cs

@@ -10,6 +10,8 @@ using System.Windows.Media;
 using InABox.Core;
 using InABox.Wpf;
 using Image = System.Windows.Controls.Image;
+using System.Runtime.InteropServices;
+using System.Windows.Interop;
 
 namespace InABox.WPF;
 
@@ -33,6 +35,108 @@ public class FuncTemplateSelector : DataTemplateSelector
 
 public static class WPFUtils
 {
+    
+    public static void MoveToCenter(this Window window)
+    {
+        if (!GetCursorPos(out POINT cursorPoint))
+            return;
+
+        IntPtr mainWindow = MonitorFromPoint(new POINT() { x = 1, y = 1 }, MONITOR_DEFAULTTO.MONITOR_DEFAULTTONULL);
+        IntPtr monitorHandle = MonitorFromPoint(cursorPoint, MONITOR_DEFAULTTO.MONITOR_DEFAULTTONULL);
+
+        MONITORINFO monitorInfo = new() { cbSize = (uint)Marshal.SizeOf<MONITORINFO>() };
+        if (!GetMonitorInfo(monitorHandle, ref monitorInfo))
+            return;
+
+        IntPtr windowHandle = new WindowInteropHelper(window).EnsureHandle();
+
+        if (!GetWindowPlacement(windowHandle, out WINDOWPLACEMENT windowPlacement))
+            return;
+
+        int left = monitorInfo.rcWork.left + Math.Max(0, (int)((monitorInfo.rcWork.Width - windowPlacement.rcNormalPosition.Width) / 2D));
+        int top = monitorInfo.rcWork.top + Math.Max(0, (int)((monitorInfo.rcWork.Height - windowPlacement.rcNormalPosition.Height) / 2D));
+
+        windowPlacement.rcNormalPosition = new RECT(left, top, windowPlacement.rcNormalPosition.Width, windowPlacement.rcNormalPosition.Height);
+        SetWindowPlacement(windowHandle, ref windowPlacement);
+    }
+
+    [DllImport("User32.dll", SetLastError = true)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    private static extern bool GetCursorPos(out POINT lpPoint);
+
+    [DllImport("User32.dll")]
+    private static extern IntPtr MonitorFromPoint(POINT pt, MONITOR_DEFAULTTO dwFlags);
+
+    private enum MONITOR_DEFAULTTO : uint
+    {
+        MONITOR_DEFAULTTONULL = 0x00000000,
+        MONITOR_DEFAULTTOPRIMARY = 0x00000001,
+        MONITOR_DEFAULTTONEAREST = 0x00000002,
+    }
+
+    [DllImport("User32.dll")]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
+
+    [StructLayout(LayoutKind.Sequential)]
+    private struct MONITORINFO
+    {
+        public uint cbSize;
+        public RECT rcMonitor;
+        public RECT rcWork;
+        public uint dwFlags;
+    }
+
+    [DllImport("User32.dll", SetLastError = true)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    private static extern bool GetWindowPlacement(IntPtr hWnd, out WINDOWPLACEMENT lpwndpl);
+
+    [DllImport("User32.dll", SetLastError = true)]
+    [return: MarshalAs(UnmanagedType.Bool)]
+    private static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);
+
+    [StructLayout(LayoutKind.Sequential)]
+    private struct WINDOWPLACEMENT
+    {
+        public uint length;
+        public uint flags;
+        public uint showCmd;
+        public POINT ptMinPosition;
+        public POINT ptMaxPosition;
+        public RECT rcNormalPosition;
+    }
+
+    [StructLayout(LayoutKind.Sequential)]
+    private struct POINT
+    {
+        public int x;
+        public int y;
+    }
+
+    [StructLayout(LayoutKind.Sequential)]
+    private struct RECT
+    {
+        public int left;
+        public int top;
+        public int right;
+        public int bottom;
+
+        public int Width => right - left;
+        public int Height => bottom - top;
+
+        public RECT(int x, int y, int width, int height)
+        {
+            left = x;
+            top = y;
+            right = x + width;
+            bottom = y + height;
+        }
+    }
+
+    #region Setters/Triggers etc
+
+
+    
     public static Style AddSetter(this Style style, DependencyProperty property, object value)
     {
         style.Setters.Add(new Setter(property, value));
@@ -55,12 +159,14 @@ public static class WPFUtils
         style.Triggers.Add(trigger);
         return trigger;
     }
-
+    
+    #endregion
+    
     public static SolidColorBrush ToBrush(this System.Windows.Media.Color color, double opacity = 1.0)
     {
         return new SolidColorBrush(color) { Opacity = opacity };
     }
-
+    
     #region Multi-Binding
 
     public static MultiBinding CreateMultiBinding(IMultiValueConverter? converter = null, string? format = null, object? parameter = null)