Есть ли способ сделать форму, у которой нет границы (FormBorderStyle установлен в "none"), подвижной, когда мышь щелкает вниз по форме, как если бы была граница?
Сделать безграничную форму подвижной?
Ответ 1
Эта статья о CodeProject описывает методику. В основном сводится к:
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool ReleaseCapture();
private void Form1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
}
}
По сути, это аналогично захвату строки заголовка окна с точки зрения диспетчера окон.
Ответ 2
Пусть не делаются вещи более трудными, чем они должны быть. Я столкнулся с таким количеством фрагментов кода, которые позволяют перетаскивать форму вокруг (или другого элемента управления). И у многих из них есть свои недостатки/побочные эффекты. Особенно те, где они обманывают Windows, думая, что элемент управления в форме является фактической формой.
Итак, вот мой фрагмент. Я использую это все время. Я также хотел бы отметить, что вы не должны использовать this.Invalidate(); как это делают другие, потому что в некоторых случаях форма мерцает. И в некоторых случаях так и происходит. Обновление. Используя this.Update, у меня не было никаких мерцающих проблем:
private bool mouseDown;
private Point lastLocation;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
lastLocation = e.Location;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if(mouseDown)
{
this.Location = new Point(
(this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);
this.Update();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
Ответ 3
Еще один простой способ сделать то же самое.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// set this.FormBorderStyle to None here if needed
// if set to none, make sure you have a way to close the form!
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST)
m.Result = (IntPtr)(HT_CAPTION);
}
private const int WM_NCHITTEST = 0x84;
private const int HT_CLIENT = 0x1;
private const int HT_CAPTION = 0x2;
}
Ответ 4
используйте MouseDown, MouseMove и MouseUp. Вы можете установить для него флаг переменной. У меня есть образец, но я думаю, вам нужно пересмотреть.
Я кодирую действие мыши на панель. Как только вы нажмете панель, ваша форма будет перемещаться вместе с ней.
//Global variables;
private bool _dragging = false;
private Point _offset;
private Point _start_point=new Point(0,0);
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
_dragging = true; // _dragging is your variable flag
_start_point = new Point(e.X, e.Y);
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
_dragging = false;
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if(_dragging)
{
Point p = PointToScreen(e.Location);
Location = new Point(p.X - this._start_point.X,p.Y - this._start_point.Y);
}
}
Ответ 5
Только WPF
не имеют точного кода, но в недавнем проекте я думаю, что я использовал событие MouseDown и просто поставлю это:
frmBorderless.DragMove();
Ответ 6
Это проверено и легко понять.
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x84:
base.WndProc(ref m);
if((int)m.Result == 0x1)
m.Result = (IntPtr)0x2;
return;
}
base.WndProc(ref m);
}
Ответ 7
Нет свойства, которое вы можете перевернуть, чтобы это произошло волшебным образом. Посмотрите на события для формы, и это становится довольно тривиальным для реализации этого, установив this.Top
и this.Left
. В частности, вы захотите посмотреть MouseDown
, MouseUp
и MouseMove
.
Ответ 8
public Point mouseLocation;
private void frmInstallDevice_MouseDown(object sender, MouseEventArgs e)
{
mouseLocation = new Point(-e.X, -e.Y);
}
private void frmInstallDevice_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point mousePos = Control.MousePosition;
mousePos.Offset(mouseLocation.X, mouseLocation.Y);
Location = mousePos;
}
}
это может решить проблему ур....
Ответ 9
Лучший способ, который я нашел (конечно, модифицированный)
// This adds the event handler for the control
private void AddDrag(Control Control) { Control.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DragForm_MouseDown); }
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HT_CAPTION = 0x2;
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern bool ReleaseCapture();
private void DragForm_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
// Checks if Y = 0, if so maximize the form
if (this.Location.Y == 0) { this.WindowState = FormWindowState.Maximized; }
}
}
Чтобы применить перетаскивание к элементу управления, просто вставьте его после InitializeComponent()
AddDrag(NameOfControl);
Ответ 10
Этот бит кода из приведенной выше ссылки сделал трюк в моем случае:)
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
if (e.Button == MouseButtons.Left)
{
this.Capture = false;
Message msg = Message.Create(this.Handle, 0XA1, new IntPtr(2), IntPtr.Zero);
this.WndProc(ref msg);
}
}
Ответ 11
Для .NET Framework 4,
Вы можете использовать this.DragMove()
для события MouseDown
компонента (mainLayout в этом примере), который вы используете для перетаскивания.
private void mainLayout_MouseDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
Ответ 12
Я пытался сделать форму окон без полей подвижной, которая содержала элемент управления WPF Element Host и элемент управления пользователя WPF.
В итоге в моем пользовательском элементе управления WPF появилась панель стека StackPanel, которая казалась логичной, чтобы попытаться перейти. Попытка кода junmats работала, когда я медленно перемещал мышь, но если бы я двигал мышь быстрее, мышь уходила из формы, и форма застревала где-то в середине движения.
Это улучшило его ответ на мою ситуацию с использованием CaptureMouse и ReleaseCaptureMouse, и теперь мышь не сдвигается с формы при ее перемещении, даже если я перемещаю ее быстро.
private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
{
_start_point = e.GetPosition(this);
StackPanel.CaptureMouse();
}
private void StackPanel_MouseUp(object sender, MouseButtonEventArgs e)
{
StackPanel.ReleaseMouseCapture();
}
private void StackPanel_MouseMove(object sender, MouseEventArgs e)
{
if (StackPanel.IsMouseCaptured)
{
var p = _form.GetMousePositionWindowsForms();
_form.Location = new System.Drawing.Point((int)(p.X - this._start_point.X), (int)(p.Y - this._start_point.Y));
}
}
//Global variables;
private Point _start_point = new Point(0, 0);
Ответ 13
Также, если вам нужно удвоить DoubleClick и сделать вашу форму больше/меньше, вы можете использовать первый ответ, создайте глобальную переменную int, добавьте 1 каждый раз, когда пользователь нажимает на компонент, который вы используете для перетаскивания. Если variable == 2
, то сделайте вашу форму больше/меньше. Также используйте таймер на каждые полсе секунды или секунду, чтобы сделать ваш variable = 0
;
Ответ 14
Самый простой способ это:
Сначала создайте метку с именем label1. Перейдите к событиям label1> события мыши> Label1_Mouse Переместите и напишите:
if (e.Button == MouseButtons.Left){
Left += e.X;
Top += e.Y;'
}
Ответ 15
Поскольку некоторые ответы не позволяют перетаскивать дочерние элементы управления, я создал небольшой вспомогательный класс. Надо пройти форму верхнего уровня. При желании может быть сделано более общим.
class MouseDragger
{
private readonly Form _form;
private Point _mouseDown;
protected void OnMouseDown(object sender, MouseEventArgs e)
{
_mouseDown = e.Location;
}
protected void OnMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int dx = e.Location.X - _mouseDown.X;
int dy = e.Location.Y - _mouseDown.Y;
_form.Location = new Point(_form.Location.X + dx, _form.Location.Y + dy);
}
}
public MouseDragger(Form form)
{
_form = form;
MakeDraggable(_form);
}
private void MakeDraggable(Control control)
{
var type = control.GetType();
if (typeof(Button).IsAssignableFrom(type))
{
return;
}
control.MouseDown += OnMouseDown;
control.MouseMove += OnMouseMove;
foreach (Control child in control.Controls)
{
MakeDraggable(child);
}
}
}
Ответ 16
Добавление MouseLeftButtonDown
события MouseLeftButtonDown
в MainWindow сработало для меня.
В функцию события, которая генерируется автоматически, добавьте следующий код:
base.OnMouseLeftButtonDown(e);
this.DragMove();
Ответ 17
Я попробовал следующее и до изменения, мое прозрачное окно больше не было заморожено на месте, но могло быть перемещено !! (выбросить все эти сложные решения выше...)
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
// Begin dragging the window
this.DragMove();
}
Ответ 18
Я расширяю решение от jay_t55 еще одним методом ToolStrip1_MouseLeave
который обрабатывает события, когда мышь быстро движется и покидает регион.
private bool mouseDown;
private Point lastLocation;
private void ToolStrip1_MouseDown(object sender, MouseEventArgs e) {
mouseDown = true;
lastLocation = e.Location;
}
private void ToolStrip1_MouseMove(object sender, MouseEventArgs e) {
if (mouseDown) {
this.Location = new Point(
(this.Location.X - lastLocation.X) + e.X, (this.Location.Y - lastLocation.Y) + e.Y);
this.Update();
}
}
private void ToolStrip1_MouseUp(object sender, MouseEventArgs e) {
mouseDown = false;
}
private void ToolStrip1_MouseLeave(object sender, EventArgs e) {
mouseDown = false;
}
Ответ 19
Это сработало для меня.
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
_mouseLoc = e.Location;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int dx = e.Location.X - _mouseLoc.X;
int dy = e.Location.Y - _mouseLoc.Y;
this.Location = new Point(this.Location.X + dx, this.Location.Y + dy);
}
}