Event for window

I am trying to jump over some hoops at the moment while working with a WPF SizeChanged event in a window. I have some user code that I need to execute after , the user has finished resizing the window, unfortunately there is no event that I could find for this, so I created a solution using Reactive Extensions to throttle the SizeChange event:

 IObservable<SizeChangedEventArgs> ObservableSizeChanges = Observable .FromEventPattern<SizeChangedEventArgs>(this, "SizeChanged") .Select(x => x.EventArgs) .Throttle(TimeSpan.FromMilliseconds(200)); IDisposable SizeChangedSubscription = ObservableSizeChanges .ObserveOn(SynchronizationContext.Current) .Subscribe(x => { Size_Changed(x); }); 

Basically, what this does is ensure that 200 milliseconds without SizeChanged events must pass before it invokes my custom code. This works great, but I ran into the problem that if the user drags the window handle and continues to hold the mouse button, the code will still be executed. I want to make sure that custom code cannot be executed when the mouse button is unavailable. I tried to connect to PreviewMouseLeftButtonDown , but it does not start when the window handle is clicked, only when the mouse click is inside the window frame. Is there any similar event that I can hook up for a mouse that relates to a window handle? Or can someone think of a suitable workaround for the problem that I have?

+4
source share
2 answers

Windows sends a special message to notify the window of a modal size / move cycle. WM_EXITSIZEMOVE, launched when the user allows you to move from the mouse button or press Escape. But yes, WPF does not disclose it. Google "wpf wm_exitsizemove" to find the interaction code you want. Good look - this blog post

+2
source

This is probably too much, but specifically for your address, "How can I find out if the mouse button is clicked?" question, look at this P / Invoke shell:

 public class ButtonObserver : IDisposable { public struct MouseButtons { public bool LeftButton; public bool RightButton; } [DllImport("user32.dll")] static extern short GetAsyncKeyState(int vKey); private const int VK_LBUTTON = 0x01; private const int VK_RBUTTON = 0x02; private Task _pollTask = null; private Subject<MouseButtons> _pollBuffer = new Subject<MouseButtons>(); private CancellationTokenSource _canceller; public IObservable<MouseButtons> PollMouse(int pollDelayMs) { if(_pollTask == null) { _canceller = new CancellationTokenSource(); _pollTask = Task.Factory.StartNew(() => { while(!_canceller.IsCancellationRequested) { var mbLeft = GetAsyncKeyState(VK_LBUTTON) != 0; var mbRight = GetAsyncKeyState(VK_RBUTTON) != 0; _pollBuffer.OnNext(new MouseButtons{ LeftButton = mbLeft, RightButton = mbRight}); Thread.Sleep(pollDelayMs); } }); } return _pollBuffer; } public void Dispose() { _canceller.Cancel(); _pollTask.Wait(); _pollTask = null; } } 

You can use it like:

 void Main() { var buttonObs = new ButtonObserver(); var buttons = buttonObs.PollMouse(100).Where(mb => mb.LeftButton); using(buttons.Subscribe(mb => Console.WriteLine("Left button down"))) { Console.ReadLine(); } buttonObs.Dispose(); } 
+1
source

Source: https://habr.com/ru/post/1479567/


All Articles