Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Movement of MainPage window from Blazor components

$
0
0

I am developing Blazor MAUI Hybrid application. One of the requirements is to remove top bar (with minimize, maximize, close buttons) and create my own. Then be able to drag it and move windows in same way as it would be native one. After some work, I end up in solution, which looks finally (almost) working. Only issue with this solution is that user can move mouse much faster than window is moving. Does anyone know what reason of that behavior is and how to eventually solve it? If you drag any other application window, like Visual Studio, or Browser or even MAUI app with default top bar, it moves as fast as mouse cursor.

My current code is this:

  • I have MAUI app and I have library with Blazor components (so Blazor components have no direct access to MAUI window)
  • I don't use MouseEventArgs objects in Blazor events because they were returning completely wrong values
  • This is closest working solution I was able to get, so far, but can't figure out the speed issue.
  1. MauiApp / MauiProgram.cs - This code removes top bar
        public static MauiApp CreateMauiApp()        {            var builder = MauiApp.CreateBuilder();            builder                .UseMauiApp<App>()                .ConfigureLifecycleEvents(events =>                {        #if WINDOWS                events.AddWindows(windowsLifecycleBuilder =>                {                    windowsLifecycleBuilder.OnWindowCreated(window =>                    {                        var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);                        var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle);                        var appWindow = AppWindow.GetFromWindowId(id);                        if (appWindow.Presenter is OverlappedPresenter presenter)                        {                            presenter.SetBorderAndTitleBar(false, false);                            presenter.IsMinimizable = false;                            presenter.IsMaximizable = false;                            presenter.IsResizable = false;                        }                    });                });        #endif            })             ... other code
  1. Blazor components project defines interface for accessing MAUI specific methods:
        public interface IMauiManipulater        {           void OnPointerPressed();           void OnPointerMoved();           void OnPointerReleased();        }
  1. MAUI project implements it:
        internal class MauiManipulator : IMauiManipulator        {            private bool isDragging = false;            private Point initialCursorPosition;            private Point initialWindowPosition;        #if WINDOWS            [DllImport("user32.dll")]            public static extern bool SetCapture(IntPtr hWnd);            [DllImport("user32.dll")]            public static extern bool ReleaseCapture();            [DllImport("user32.dll")]            public static extern bool GetCursorPos(out POINT lpPoint);            public struct POINT            {                public int X;                public int Y;            }            private Point GetCursorPosition()            {                GetCursorPos(out POINT point);                return new Point(point.X, point.Y);            }        #endif        public void OnPointerPressed()            {                isDragging = true;        #if WINDOWS            // Capture pointer globally            var mauiWindow = App.Current.Windows.First();            var nativeWindow = mauiWindow.Handler.PlatformView;            IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);            SetCapture(windowHandle);            // Get initial cursor position            initialCursorPosition = GetCursorPosition();            // Get initial window position            var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(                Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle));            initialWindowPosition = new Point(appWindow.Position.X, appWindow.Position.Y);        #endif        }        public void OnPointerMoved()        {            if (!isDragging) return;            Debug.WriteLine(DateTime.Now.Ticks);        #if WINDOWS            // Get current cursor position            var currentCursorPosition = GetCursorPosition();            // Calculate offset            var offsetX = currentCursorPosition.X - initialCursorPosition.X;            var offsetY = currentCursorPosition.Y - initialCursorPosition.Y;            // Move window            var mauiWindow = App.Current.Windows.First();            var nativeWindow = mauiWindow.Handler.PlatformView;            IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);            var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(                Microsoft.UI.Win32Interop.GetWindowIdFromWindow(windowHandle));            appWindow.Move(new Windows.Graphics.PointInt32(                (int)(initialWindowPosition.X + offsetX),                (int)(initialWindowPosition.Y + offsetY)            ));        #endif        }        public void OnPointerReleased()        {        #if WINDOWS            // Release pointer capture            var mauiWindow = App.Current.Windows.First();            var nativeWindow = mauiWindow.Handler.PlatformView;            IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);            ReleaseCapture();        #endif            isDragging = false;        }4. And finally usage in Blazor components be like:<div class="top-bar" @onmousedown="HandleMouseDown" @onmouseup="HandleMouseUp" @onmousemove="HandleMouseMove" @onmouseleave="HandleMouseUp">            // Top bar content</div>        private bool isDragging = false;        [Inject]        private IMauiManipulator MauiManipulator { get; set; } = default!;        private void HandleMouseDown(MouseEventArgs e)        {            Debug.WriteLine("Mouse down");            isDragging = true;            MauiManipulator.OnPointerPressed();        }        private void HandleMouseUp(MouseEventArgs e)        {            Debug.WriteLine("Mouse up");            if (isDragging)            {                isDragging = false;                MauiManipulator.OnPointerReleased();            }        }        private async Task HandleMouseMove(MouseEventArgs e)        {            if (isDragging)            {                MauiManipulator.OnPointerMoved();            }        }

Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>