Способ сделать окно без окон WPF перетаскиваемым без получения InvalidOperationException
У меня есть окно меньше основного окна WPF. Я пытаюсь сделать так, чтобы конечный пользователь мог перетащить окно.
Я добавил следующее в конструктор окна:
this.MouseLeftButtonDown += delegate { DragMove(); };
Проблема в том, что у меня есть диалоговое окно, которое открывается с двумя кнопками. Когда я нажимаю одну из этих кнопок, я получаю InvalidOperationException, необработанное с сообщением "Может вызывать DragMove только тогда, когда основная кнопка мыши нажата".
Это ставит несколько вопросов: почему событие mousedown в диалоге как-то связано с этим? Как я могу сделать это без этого исключения?
Спасибо!
4 ответа
"Правильный" способ сделать окно без полей подвижным - это вернуть HTCAPTION в сообщении WM_NCHITTEST. Следующий код показывает, как это сделать. Обратите внимание, что вы захотите вернуть HTCLIENT, если курсор находится над определенными визуальными элементами вашего Window, поэтому этот код только для начала.
http://msdn.microsoft.com/en-us/library/ms645618(VS.85).aspx
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
HwndSource hwndSource = (HwndSource)HwndSource.FromVisual(this);
hwndSource.AddHook(WndProcHook);
base.OnSourceInitialized(e);
}
private static IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handeled)
{
if (msg == 0x0084) // WM_NCHITTEST
{
handeled = true;
return (IntPtr)2; // HTCAPTION
}
return IntPtr.Zero;
}
}
Установите атрибут MouseDown окна или любого другого элемента управления, который вы хотите использовать:
<TextBlock Grid.Column="0" HorizontalAlignment="Stretch" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" >Handy Dandy</TextBlock>
И внедрите это в коде так:
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
От: http://www2.suddenelfilio.net/2007/01/19/wpf-draggable-windowless-windows/
Вы можете переопределить оригинальный метод:
public new void DragMove()
{
if (this.WindowState == WindowState.Normal)
{
SendMessage(hs.Handle, WM_SYSCOMMAND, (IntPtr)0xf012, IntPtr.Zero);
SendMessage(hs.Handle, WM_LBUTTONUP, IntPtr.Zero, IntPtr.Zero);
}
}
Есть проект Microsoft, который обрабатывает все "безоконный" стиль и многое другое, и он с открытым исходным кодом, вы можете взглянуть на http://code.msdn.microsoft.com/WPFShell. Я использую коммерческое финансовое приложение, и еще не сталкивался с какими-либо проблемами ни в одной версии Windows.