Другой подход заключается в использовании API-функции PeekMessage, как показано в следующем коде.
using System.Runtime.InteropServices;
using System.Security;
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool PeekMessage(out NativeMessage message,
IntPtr handle, uint filterMin, uint filterMax, uint flags);
private const UInt32 WM_MOUSEFIRST = 0x0200;
private const UInt32 WM_MOUSELAST = 0x020D;
public const int PM_REMOVE = 0x0001;
// Flush all pending mouse events.
private void FlushMouseMessages()
{
NativeMessage msg;
// Repeat until PeekMessage returns false.
while (PeekMessage(out msg, IntPtr.Zero,
WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE))
;
}
Этот код включает в себя несколько объявлений для функции API и ее параметров. (Вам также необходимо добавить операторы using для пространств имен System.Runtime.InteropServices и System.Security. Загрузите пример для получения подробной информации.)
Метод FlushMouseMessages вызывает PeekMessage, сообщая ему об отмене любого сообщения в диапазоне от WM_MOUSELAST до PM_REMOVE. Код вызывает PeekMessage несколько раз, пока не вернет false, чтобы указать, что таких сообщений нет.
Следующий обработчик события кнопки вызывает FlushMouseMessage, поэтому вы не можете нажать кнопку, пока ее код еще работает.
private void but_Click(object sender, RoutedEventArgs e)
{
(sender as Button).IsEnabled = false;
doSomeThing();//e.g run for more than 20 seconds
(sender as Button).IsEnabled = true;
FlushMouseMessages();
}
Я выбрал вышеуказанный код с сайта
http://csharphelper.com/blog/2015/08/flush-click-events-in-c/
Это работает для меня.