C#创建磁性窗体的方法:创建特殊窗体

目录

一、磁性窗体

二、磁性窗体的实现方法

(1)无标题窗体的移动

(2)Left属性

(3)Top属性

二、设计一个磁性窗体的实例

(1)资源管理器Resources.Designer.cs设计

(2)公共类Frm_Play.cs

(3)主窗体

1.Frm_Play.cs

2.Frm_Play.Designer.cs

(4)子窗体1

1.Frm_ListBox.cs

2.Frm_ListBox.Designer.cs

(5)子窗体2

1.Frm_Libretto.cs

2.Frm_Libretto.Designer.cs

(6)生成效果


一、磁性窗体

        经常会遇到一种情况,即当拖动一个窗体(主窗体)时,其他窗体(子窗体)随着该窗体移动,当拖动子窗体时,其他窗体将不跟随移动,这就是磁性窗体。

二、磁性窗体的实现方法

        在主窗体移动时,通过改变跟随窗体的Left和Top属性值实现“磁性”。

(1)无标题窗体的移动

        无标题窗体的移动主要是通过控件来移动窗体,比如,用Panel控件来进行。首先,在Panel控件的MouseDown事件中将鼠标按下时的位置值(负值)存入到全局变量CPoint中,代码如下:

private void panel_Title_MouseDown(object sender,MouseEventArgs e)
CPoint=new Point(-e.X,-e.Y);    //获取鼠标按下时的位置

        然后,在Panel控件的MouseMove事件中按照CPoint变量的值,以屏幕坐标平移指定的量,并用平移后的结果设置窗体的DesktopLocation属性,代码如下:

private void panel_Title_MouseMove(object sender,MouseEventArgs e)
if(e.Button==MouseButtons.Left)
{Point myPosittion=Control.MousePosition; //获取当前鼠标的屏幕坐标myPosittion.Offset(CPoint.X,CPoint.Y);   //以屏幕坐标平移指定的量DesktopLocation=myPosittion;             //设置当前窗体在屏幕上的位置}

(2)Left属性

        该属性用于获取或设置控件左边缘与其容器的工作区左边缘之间的距离(以像素为单位)。语法格式如下:

public int Left {get;set;}
参数说明
属性值:窗体左边缘与其容器的工作区左边缘之间的距离(以像素为单位)。

(3)Top属性

        该属性用于获取或设置控件上边缘与其容器的工作区上边缘之间的距离(以像素为单位)。语法格式如下:

public int Top{get;set;}
参数说明属性值:窗体上边缘与其容器的工作区上边缘之间的距离(以像素为单位)。

二、设计一个磁性窗体的实例

        本实例将制作一个磁性窗体,当拖动主窗体移动时,两个子窗体如果相连,则跟随移动。

  • 三个窗体:主窗体Frm_Play.cs,2个子窗体:Frm_ListBox.cs、Frm_Libretto.cs;
  • 鼠标按下任一窗体顶部的控件,可以拖动窗体;
  • 拖动子窗体时,会使得粘在一起的窗体分开,拖动主窗体时会使粘在一起的子窗体随动;
  • 拖动主窗体靠近子窗体小于相互吸引的缝隙10时,松开鼠标,靠近的窗体会像磁铁一样吸引在一起;主窗体吸引子窗体后,该子窗体还可以吸引其它子窗体;
  • 双击主窗体的控件,激活所有窗体;

(1)资源管理器Resources.Designer.cs设计

        项目使用的图片资源应设计到资源管理器,详见本文作者写的其它文章:C#手动改变自制窗体的大小-CSDN博客 https://wenchm.blog.csdn.net/article/details/137027140

(2)公共类Frm_Play.cs

// 类设计
namespace _185
{internal class FrmClass{#region  磁性窗体-公共变量//记录窗体的隐藏与显示public static bool Frm_ListShow = false;public static bool Frm_LibrettoShow = false;public static bool Frm_ScreenShow = false;//记录鼠标的当前位置public static Point CPoint;public static Point FrmPoint;public static int Gap = 10;//设置窗体间相互吸引的缝隙尺寸//Frm_Play窗体的位置及大小public static int Frm_Play_Top = 0;public static int Frm_Play_Left = 0;public static int Frm_Play_Width = 0;public static int Frm_Play_Height = 0;public static bool Is_TwoAssitForm_AdhereTo = false;//辅助窗体是否磁性在一起//Frm_ListBos窗体的位置及大小public static int Frm_List_Top = 0;public static int Frm_List_Left = 0;public static int Frm_List_Width = 0;public static int Frm_List_Height = 0;public static bool Is_Frm_List_AdhereTo = false;//辅助窗体是否与主窗体磁性在一起//Frm_Libretto窗体的位置及大小public static int Frm_Libretto_Top = 0;public static int Frm_Libretto_Left = 0;public static int Frm_Libretto_Width = 0;public static int Frm_Libretto_Height = 0;public static bool Is_Frm_Libretto_AdhereTo = false;//辅助窗体是否与主窗体磁性在一起//窗体之间的距离差public static int Frm_List_Gap_Top = 0;public static int Frm_List_Gap_Left = 0;public static int Frm_Libretto_Gap_Top = 0;public static int Frm_Libretto_Gap_Left = 0;#endregion#region  检测各窗体是否连接在一起/// <summary>/// 检测各窗体是否连接在一起/// </summary>public static void Is_Addhered_Check(){//Frm_ListBos与主窗体bool Temp_Magnetism = false;if ((Frm_Play_Top - Frm_List_Top) == 0)Temp_Magnetism = true;if ((Frm_Play_Left - Frm_List_Left) == 0)Temp_Magnetism = true;if ((Frm_Play_Left - Frm_List_Left - Frm_List_Width) == 0)Temp_Magnetism = true;if ((Frm_Play_Left - Frm_List_Left + Frm_List_Width) == 0)Temp_Magnetism = true;if ((Frm_Play_Top - Frm_List_Top - Frm_List_Height) == 0)Temp_Magnetism = true;if ((Frm_Play_Top - Frm_List_Top + Frm_List_Height) == 0)Temp_Magnetism = true;if (Temp_Magnetism)Is_Frm_List_AdhereTo = true;//Frm_Libretto与主窗体Temp_Magnetism = false;if ((Frm_Play_Top - Frm_Libretto_Top) == 0)Temp_Magnetism = true;if ((Frm_Play_Left - Frm_Libretto_Left) == 0)Temp_Magnetism = true;if ((Frm_Play_Left - Frm_Libretto_Left - Frm_Libretto_Width) == 0)Temp_Magnetism = true;if ((Frm_Play_Left - Frm_Libretto_Left + Frm_Libretto_Width) == 0)Temp_Magnetism = true;if ((Frm_Play_Top - Frm_Libretto_Top - Frm_Libretto_Height) == 0)Temp_Magnetism = true;if ((Frm_Play_Top - Frm_Libretto_Top + Frm_Libretto_Height) == 0)Temp_Magnetism = true;if (Temp_Magnetism)Is_Frm_Libretto_AdhereTo = true;//两个辅窗体Temp_Magnetism = false;if ((Frm_List_Top - Frm_Libretto_Top) == 0)Temp_Magnetism = true;if ((Frm_List_Left - Frm_Libretto_Left) == 0)Temp_Magnetism = true;if ((Frm_List_Left - Frm_Libretto_Left - Frm_Libretto_Width) == 0)Temp_Magnetism = true;if ((Frm_List_Left - Frm_Libretto_Left + Frm_Libretto_Width) == 0)Temp_Magnetism = true;if ((Frm_List_Top - Frm_Libretto_Top - Frm_Libretto_Height) == 0)Temp_Magnetism = true;if ((Frm_List_Top - Frm_Libretto_Top + Frm_Libretto_Height) == 0)Temp_Magnetism = true;if (Temp_Magnetism)Is_TwoAssitForm_AdhereTo = true;}#endregion#region  利用窗体上的控件移动窗体/// <summary>/// 利用控件移动窗体/// </summary>/// <param Frm="Form">窗体</param>/// <param e="MouseEventArgs">控件的移动事件</param>public static void MoveForm(Form Frm, MouseEventArgs e) {if (e.Button == MouseButtons.Left){Point myPosittion = Control.MousePosition;    //获取当前鼠标的屏幕坐标myPosittion.Offset(CPoint.X, CPoint.Y);       //重载当前鼠标的位置Frm.DesktopLocation = myPosittion;            //设置当前窗体在屏幕上的位置}}#endregion#region  计算窗体之间的缝隙/// <summary>/// 计算窗体之间的距离差/// </summary>/// <param Frm="Form">窗体</param>/// <param Follow="Form">跟随窗体</param>public static void Calculate_Gap(Form Frm, Form Follow){switch (Follow.Name){case "Frm_ListBox":{Frm_List_Gap_Top = Follow.Top - Frm.Top;Frm_List_Gap_Left = Follow.Left - Frm.Left;break;}case "Frm_Libretto":{Frm_Libretto_Gap_Top = Follow.Top - Frm.Top;Frm_Libretto_Gap_Left = Follow.Left - Frm.Left;break;}}}#endregion#region  磁性窗体的移动/// <summary>/// 磁性窗体的移动/// </summary>/// <param Frm="Form">窗体</param>/// <param e="MouseEventArgs">控件的移动事件</param>/// <param Follow="Form">跟随窗体</param>public static void MoveManyForm(Form Frm, MouseEventArgs e, Form Follow){ArgumentNullException.ThrowIfNull(Frm);if (e.Button == MouseButtons.Left){int Tem_Left = 0;int Tem_Top = 0;Point myPosittion = Control.MousePosition;//获取当前鼠标的屏幕坐标switch (Follow.Name){case "Frm_ListBox":{Tem_Top = Frm_List_Gap_Top - FrmPoint.Y;Tem_Left = Frm_List_Gap_Left - FrmPoint.X;break;}case "Frm_Libretto":{Tem_Top = Frm_Libretto_Gap_Top - FrmPoint.Y;Tem_Left = Frm_Libretto_Gap_Left - FrmPoint.X;break;}}myPosittion.Offset(Tem_Left, Tem_Top);Follow.DesktopLocation = myPosittion;}}#endregion#region  对窗体的位置进行初始化/// <summary>/// 对窗体的位置进行初始化/// </summary>/// <param Frm="Form">窗体</param>public static void FrmInitialize(Form Frm){switch (Frm.Name){case "Frm_Play":{Frm_Play_Top = Frm.Top;Frm_Play_Left = Frm.Left;Frm_Play_Width = Frm.Width;Frm_Play_Height = Frm.Height;break;}case "Frm_ListBox":{Frm_List_Top = Frm.Top;Frm_List_Left = Frm.Left;Frm_List_Width = Frm.Width;Frm_List_Height = Frm.Height;break;}case "Frm_Libretto":{Frm_Libretto_Top = Frm.Top;Frm_Libretto_Left = Frm.Left;Frm_Libretto_Width = Frm.Width;Frm_Libretto_Height = Frm.Height;break;}}}#endregion#region  存储各窗体的当前信息/// <summary>/// 存储各窗体的当前信息/// </summary>/// <param Frm="Form">窗体</param>/// <param e="MouseEventArgs">控件的移动事件</param>public static void FrmPlace(Form Frm){FrmInitialize(Frm);FrmMagnetism(Frm);}#endregion#region  窗体的磁性设置/// <summary>/// 窗体的磁性设置/// </summary>/// <param Frm="Form">窗体</param>public static void FrmMagnetism(Form Frm){if (Frm.Name != "Frm_Play"){FrmMagnetismCount(Frm, Frm_Play_Top, Frm_Play_Left, Frm_Play_Width, Frm_Play_Height, "Frm_Play");}if (Frm.Name != "Frm_ListBos"){FrmMagnetismCount(Frm, Frm_List_Top, Frm_List_Left, Frm_List_Width, Frm_List_Height, "Frm_ListBos");}if (Frm.Name != "Frm_Libratto"){FrmMagnetismCount(Frm, Frm_Libretto_Top, Frm_Libretto_Left, Frm_Libretto_Width, Frm_Libretto_Height, "Frm_Libratto");}FrmInitialize(Frm);}#endregion#region  磁性窗体的计算/// <summary>/// 磁性窗体的计算/// </summary>/// <param Frm="Form">窗体</param>/// <param e="MouseEventArgs">控件的移动事件</param>public static void FrmMagnetismCount(Form Frm, int top, int left, int width, int height, string Mforms){bool Tem_Magnetism = false;    //判断是否有磁性发生string Tem_MainForm = "";      //临时记录主窗体string Tem_AssistForm = "";    //临时记录辅窗体//上面进行磁性窗体if ((Frm.Top + Frm.Height - top) <= Gap && (Frm.Top + Frm.Height - top) >= -Gap){//当一个主窗体不包含辅窗体时if ((Frm.Left >= left && Frm.Left <= (left + width)) || ((Frm.Left + Frm.Width) >= left && (Frm.Left + Frm.Width) <= (left + width))){Frm.Top = top - Frm.Height;if ((Frm.Left - left) <= Gap && (Frm.Left - left) >= -Gap)Frm.Left = left;Tem_Magnetism = true;}//当一个主窗体包含辅窗体时if (Frm.Left <= left && (Frm.Left + Frm.Width) >= (left + width)){Frm.Top = top - Frm.Height;if ((Frm.Left - left) <= Gap && (Frm.Left - left) >= -Gap)Frm.Left = left;Tem_Magnetism = true;}}//下面进行磁性窗体if ((Frm.Top - (top + height)) <= Gap && (Frm.Top - (top + height)) >= -Gap){//当一个主窗体不包含辅窗体时if ((Frm.Left >= left && Frm.Left <= (left + width)) || ((Frm.Left + Frm.Width) >= left && (Frm.Left + Frm.Width) <= (left + width))){Frm.Top = top + height;if ((Frm.Left - left) <= Gap && (Frm.Left - left) >= -Gap)Frm.Left = left;Tem_Magnetism = true;}//当一个主窗体包含辅窗体时if (Frm.Left <= left && (Frm.Left + Frm.Width) >= (left + width)){Frm.Top = top + height;if ((Frm.Left - left) <= Gap && (Frm.Left - left) >= -Gap)Frm.Left = left;Tem_Magnetism = true;}}//左面进行磁性窗体if ((Frm.Left + Frm.Width - left) <= Gap && (Frm.Left + Frm.Width - left) >= -Gap){//当一个主窗体不包含辅窗体时if ((Frm.Top > top && Frm.Top <= (top + height)) || ((Frm.Top + Frm.Height) >= top && (Frm.Top + Frm.Height) <= (top + height))){Frm.Left = left - Frm.Width;if ((Frm.Top - top) <= Gap && (Frm.Top - top) >= -Gap)Frm.Top = top;Tem_Magnetism = true;}//当一个主窗体包含辅窗体时if (Frm.Top <= top && (Frm.Top + Frm.Height) >= (top + height)){Frm.Left = left - Frm.Width;if ((Frm.Top - top) <= Gap && (Frm.Top - top) >= -Gap)Frm.Top = top;Tem_Magnetism = true;}}//右面进行磁性窗体if ((Frm.Left - (left + width)) <= Gap && (Frm.Left - (left + width)) >= -Gap){//当一个主窗体不包含辅窗体时if ((Frm.Top > top && Frm.Top <= (top + height)) || ((Frm.Top + Frm.Height) >= top && (Frm.Top + Frm.Height) <= (top + height))){Frm.Left = left + width;if ((Frm.Top - top) <= Gap && (Frm.Top - top) >= -Gap)Frm.Top = top;Tem_Magnetism = true;}//当一个主窗体包含辅窗体时if (Frm.Top <= top && (Frm.Top + Frm.Height) >= (top + height)){Frm.Left = left + width;if ((Frm.Top - top) <= Gap && (Frm.Top - top) >= -Gap)Frm.Top = top;Tem_Magnetism = true;}}if (Frm.Name == "Frm_Play")Tem_MainForm = "Frm_Play";elseTem_AssistForm = Frm.Name;if (Mforms == "Frm_Play")Tem_MainForm = "Frm_Play";elseTem_AssistForm = Mforms;if (Tem_MainForm == ""){Is_TwoAssitForm_AdhereTo = Tem_Magnetism;}else{switch (Tem_AssistForm){case "Frm_ListBos":Is_Frm_List_AdhereTo = Tem_Magnetism;break;case "Frm_Libratto":Is_Frm_Libretto_AdhereTo = Tem_Magnetism;break;}}}#endregion#region  恢复窗体的初始大小/// <summary>/// 恢复窗体的初始大小(当松开鼠标时,如果窗体的大小小于300*200,恢复初始状态)/// </summary>/// <param Frm="Form">窗体</param>public static void FrmScreen_FormerlySize(Form Frm, int PWidth, int PHeight){if (Frm.Width < PWidth || Frm.Height < PHeight){Frm.Width = PWidth;Frm.Height = PHeight;//Example_Size = false;}}#endregion}
}

(3)主窗体

1.Frm_Play.cs

namespace _185
{public partial class Frm_Play : Form{public Frm_Play(){InitializeComponent();}#region  公共变量FrmClass Cla_FrmClass = new();public static Form F_List = new();public static Form F_Libretto = new();public static Form F_Screen = new();#endregionprivate void Frm_Play_Load(object sender, EventArgs e){FrmClass.FrmInitialize(this);                //窗体位置的初始化}private void Panel1_MouseDown(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left)            //按下的是否为鼠标左键{FrmClass.Is_Addhered_Check();             //检测各窗体是否连在一起int Tem_Y = e.Y;FrmClass.FrmPoint = new Point(e.X, Tem_Y);//获取鼠标在窗体上的位置,用于磁性窗体FrmClass.CPoint = new Point(-e.X, -Tem_Y);//获取鼠标在屏幕上的位置,用于窗体的移动if (FrmClass.Is_Frm_List_AdhereTo)              //如果与frm_ListBox窗体相连接{FrmClass.Calculate_Gap(this, F_List);        //计算窗体的距离差if (FrmClass.Is_TwoAssitForm_AdhereTo)       //两个辅窗体是否连接在一起{FrmClass.Calculate_Gap(this, F_Libretto);//计算窗体的距离差}}if (FrmClass.Is_Frm_Libretto_AdhereTo)        //如果与frm_Libretto窗体相连接{FrmClass.Calculate_Gap(this, F_Libretto); //计算窗体的距离差if (FrmClass.Is_TwoAssitForm_AdhereTo)    //两个辅窗体是否连接在一起{FrmClass.Calculate_Gap(this, F_List); //计算窗体的距离差}}}}private void Panel1_MouseMove(object sender, MouseEventArgs e){if (e.Button == MouseButtons.Left)            //按下的是否为鼠标左键{FrmClass.MoveForm(this, e);               //利用控件移动窗体if (FrmClass.Is_Frm_List_AdhereTo)        //如果frm_ListBox窗体与主窗体连接{FrmClass.MoveManyForm(this, e, F_List);//磁性窗体的移动FrmClass.FrmInitialize(F_List);        //对frm_ListBox窗体的位置进行初始化if (FrmClass.Is_TwoAssitForm_AdhereTo) //如果两个子窗体连接在一起{FrmClass.MoveManyForm(this, e, F_Libretto);FrmClass.FrmInitialize(F_Libretto);}}if (FrmClass.Is_Frm_Libretto_AdhereTo)    //如果frm_Libretto窗体与主窗体连接{FrmClass.MoveManyForm(this, e, F_Libretto);FrmClass.FrmInitialize(F_Libretto);if (FrmClass.Is_TwoAssitForm_AdhereTo){FrmClass.MoveManyForm(this, e, F_List);FrmClass.FrmInitialize(F_List);}}FrmClass.FrmInitialize(this);}}private void Panel1_MouseUp(object sender, MouseEventArgs e){FrmClass.FrmPlace(this);}private void Frm_Play_Shown(object sender, EventArgs e){//显示列表窗体F_List = new Frm_ListBox{ShowInTaskbar = false};FrmClass.Frm_ListShow = true;F_List.Show();//显示歌词窗体F_Libretto = new Frm_Libretto{ShowInTaskbar = false,Left = Left + Width,Top = Top};FrmClass.Frm_LibrettoShow = true;F_Libretto.Show();//各窗体位置的初始化FrmClass.FrmInitialize(F_List);FrmClass.FrmInitialize(F_Libretto);}private void Panel2_Click(object sender, EventArgs e){F_List.Close();F_List.Dispose();F_Libretto.Close();F_Libretto.Dispose();F_Screen.Close();F_Screen.Dispose();Close();}private void Panel1_Click(object sender, EventArgs e){F_List.Focus();F_Libretto.Focus();Focus();}}
}

2.Frm_Play.Designer.cs

namespace _185
{partial class Frm_Play{/// <summary>///  Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>///  Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>///  Required method for Designer support - do not modify///  the contents of this method with the code editor./// </summary>private void InitializeComponent(){panel1 = new Panel();pictureBox1 = new PictureBox();panel2 = new Panel();((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();SuspendLayout();// // panel1// panel1.BackgroundImage = Properties.Resources._5;panel1.BackgroundImageLayout = ImageLayout.Stretch;panel1.Dock = DockStyle.Top;panel1.Location = new Point(0, 0);panel1.Name = "panel1";panel1.Size = new Size(290, 31);panel1.TabIndex = 0;panel1.Click += Panel1_Click;panel1.MouseDown += Panel1_MouseDown;panel1.MouseMove += Panel1_MouseMove;panel1.MouseUp += Panel1_MouseUp;// // pictureBox1// pictureBox1.BackgroundImage = Properties.Resources._01;pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;pictureBox1.Dock = DockStyle.Fill;pictureBox1.Location = new Point(0, 31);pictureBox1.Name = "pictureBox1";pictureBox1.Size = new Size(290, 89);pictureBox1.TabIndex = 1;pictureBox1.TabStop = false;// // panel2// panel2.BackgroundImage = Properties.Resources.Close;panel2.BackgroundImageLayout = ImageLayout.Stretch;panel2.Location = new Point(265, 5);panel2.Name = "panel2";panel2.Size = new Size(18, 18);panel2.TabIndex = 0;panel2.Click += Panel2_Click;// // Frm_Play// AutoScaleDimensions = new SizeF(7F, 17F);AutoScaleMode = AutoScaleMode.Font;ClientSize = new Size(290, 120);Controls.Add(panel2);Controls.Add(pictureBox1);Controls.Add(panel1);FormBorderStyle = FormBorderStyle.None;Name = "Frm_Play";Text = "Form1";Load += Frm_Play_Load;Shown += Frm_Play_Shown;((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();ResumeLayout(false);}#endregionprivate Panel panel1;private PictureBox pictureBox1;private Panel panel2;}
}

(4)子窗体1

1.Frm_ListBox.cs

namespace _185
{public partial class Frm_ListBox : Form{public Frm_ListBox(){InitializeComponent();}#region  公共变量FrmClass Cla_FrmClass = new();#endregionprivate void Frm_ListBox_Load(object sender, EventArgs e){Left = FrmClass.Frm_Play_Left;Top = FrmClass.Frm_Play_Top + FrmClass.Frm_Play_Height;FrmClass.FrmInitialize(this);}private void Panel1_MouseDown(object sender, MouseEventArgs e){FrmClass.CPoint = new Point(-e.X, -e.Y);}private void Panel1_MouseMove(object sender, MouseEventArgs e){FrmClass.Is_TwoAssitForm_AdhereTo = false;FrmClass.Is_Frm_List_AdhereTo = false;FrmClass.MoveForm(this, e);}private void Panel1_MouseUp(object sender, MouseEventArgs e){FrmClass.FrmPlace(this);}}
}

2.Frm_ListBox.Designer.cs


namespace _185
{partial class Frm_ListBox{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){panel1 = new Panel();pictureBox1 = new PictureBox();((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();SuspendLayout();// // panel1// panel1.BackgroundImage = Properties.Resources._5;panel1.Dock = DockStyle.Top;panel1.Location = new Point(0, 0);panel1.Name = "panel1";panel1.Size = new Size(290, 31);panel1.TabIndex = 0;panel1.MouseDown += Panel1_MouseDown;panel1.MouseMove += Panel1_MouseMove;panel1.MouseUp += Panel1_MouseUp;// // pictureBox1// pictureBox1.BackgroundImage = Properties.Resources._02;pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;pictureBox1.Dock = DockStyle.Fill;pictureBox1.Location = new Point(0, 31);pictureBox1.Name = "pictureBox1";pictureBox1.Size = new Size(290, 89);pictureBox1.TabIndex = 1;pictureBox1.TabStop = false;// // Frm_ListBox// AutoScaleDimensions = new SizeF(7F, 17F);AutoScaleMode = AutoScaleMode.Font;ClientSize = new Size(290, 120);Controls.Add(pictureBox1);Controls.Add(panel1);FormBorderStyle = FormBorderStyle.None;Name = "Frm_ListBox";Text = "Form1";Load += Frm_ListBox_Load;((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();ResumeLayout(false);}#endregionprivate Panel panel1;private PictureBox pictureBox1;}
}

(5)子窗体2

1.Frm_Libretto.cs

namespace _185
{public partial class Frm_Libretto : Form{public Frm_Libretto(){InitializeComponent();}#region  公共变量FrmClass Cla_FrmClass = new();#endregionprivate void Frm_Libretto_Load(object sender, EventArgs e){Left = FrmClass.Frm_Play_Left;Top = FrmClass.Frm_Play_Top + FrmClass.Frm_Play_Height;FrmClass.FrmInitialize(this);}private void Panel1_MouseDown(object sender, MouseEventArgs e){FrmClass.CPoint = new Point(-e.X, -e.Y);}private void Panel1_MouseMove(object sender, MouseEventArgs e){FrmClass.Is_TwoAssitForm_AdhereTo = false;FrmClass.Is_Frm_List_AdhereTo = false;FrmClass.MoveForm(this, e);}private void Panel1_MouseUp(object sender, MouseEventArgs e){FrmClass.FrmPlace(this);}}
}

2.Frm_Libretto.Designer.cs

namespace _185
{partial class Frm_Libretto{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){panel1 = new Panel();pictureBox1 = new PictureBox();((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();SuspendLayout();// // panel1// panel1.BackgroundImage = Properties.Resources._5;panel1.BackgroundImageLayout = ImageLayout.Stretch;panel1.Dock = DockStyle.Top;panel1.Location = new Point(0, 0);panel1.Name = "panel1";panel1.Size = new Size(290, 31);panel1.TabIndex = 0;panel1.MouseDown += Panel1_MouseDown;panel1.MouseMove += Panel1_MouseMove;panel1.MouseUp += Panel1_MouseUp;// // pictureBox1// pictureBox1.BackgroundImage = Properties.Resources._03;pictureBox1.BackgroundImageLayout = ImageLayout.Stretch;pictureBox1.Dock = DockStyle.Fill;pictureBox1.Location = new Point(0, 31);pictureBox1.Name = "pictureBox1";pictureBox1.Size = new Size(290, 209);pictureBox1.TabIndex = 1;pictureBox1.TabStop = false;// // Frm_Libretto// AutoScaleDimensions = new SizeF(7F, 17F);AutoScaleMode = AutoScaleMode.Font;ClientSize = new Size(290, 240);Controls.Add(pictureBox1);Controls.Add(panel1);FormBorderStyle = FormBorderStyle.None;Name = "Frm_Libretto";Text = "Form2";Load += Frm_Libretto_Load;((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();ResumeLayout(false);}#endregionprivate Panel panel1;private PictureBox pictureBox1;}
}

(6)生成效果

         三个窗体吸引在一起

         三个窗体被拖动分开

 

        主窗体吸引子窗体再吸引子窗体 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/821405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPS的JS宏如何实现全文件路径字符串中截取文件名(excel)

从全文件路径的字符串中&#xff0c;截取文件名称&#xff0c;例如&#xff1a; 全文件路径字符串为&#xff1a;C:\Windows\System32\drivers\acpi1.sys 需要截取文件名&#xff1a;acpi1.sys 方法如下&#xff1a; 1、简单的方式&#xff1a;把全文件路径字符串拷贝&…

面试:sleep 和 wait

一、共同点 wait(),wait(long)和sleep(long)的效果都是让当前线程暂时放弃CPU的使用权&#xff0c;进入阻塞状态 二、不同点 1、方法归属不同 sleep(long)是Thread的静态方法而wait(), wait(long)都是Object的成员方法&#xff0c;每个对象都有 2、醒来的时机不同 执行sleep(l…

NTC热敏电阻采集温度-单片机通用模板

NTC热敏电阻采集温度-单片机通用模板 一、NTC热敏电阻转换温度的原理二、AT104Tem.c的实现三、AT104Tem.h的实现 一、NTC热敏电阻转换温度的原理 ①NTC热敏电阻会随着温度的升高&#xff0c;电阻值R逐渐降低&#xff1b;②硬件搭建电阻分压电路采集ADC逆推热敏电阻当前的阻值&…

C语言学习笔记之指针(二)

指针基础知识&#xff1a;C语言学习笔记之指针&#xff08;一&#xff09;-CSDN博客 目录 字符指针 代码分析 指针数组 数组指针 函数指针 代码分析&#xff08;出自《C陷阱和缺陷》&#xff09; 函数指针数组 指向函数指针数组的指针 回调函数 qsort() 字符指针 一…

新版AndroidStudio使用switch-case语句时出现Constant expression required错误

原因: 在新版的Android Studio中使用JDK17以上版本&#xff0c;会出现switch语句报错"Constant expression required"的问题&#xff0c;这是因为在JDK17中switch语句的条件表达式支持使用枚举类型&#xff0c;而这个特性还没有被支持。 解决方法: ①在gradle.prope…

UE4_动画基础_不同骨骼的动画重定向步骤

学习笔记&#xff0c;仅供参考&#xff01; 1、导入fbx外部资源&#xff0c;不包含动画&#xff0c;需要使用小白人动画资源。 2、打开Girl_Skeleton。发现骨骼数量不同&#xff0c;要想使用另一个骨骼的动画资源&#xff0c;需要进行不同骨骼的动画重定向。 3、打开小白人骨骼…

mmap函数小实验

mmap函数小实验 文章目的参数 length 不是页大小的整数倍会怎样&#xff1f;研究过程length结论 参数 offset 取不同的值时会怎样&#xff1f;研究过程offset 结论 参考链接 文章目的 本文是为了深入理解mmap的参数length与offset对mmap函数行为的影响&#xff0c;从而更好地理…

反转链表【java】

给定一个链表的头节点head反转链表 方法一&#xff1a;循环 1.定义三个指针&#xff1a; pre指针&#xff1a;刚开始指向空 prenull cur指针&#xff1a;刚开始指向head节点 curhead temp指针&#xff1a;保存cur指针指向节点的下一个节点 2. 不断循环改变相邻两个节点的指…

JavaWeb前端/后端开发规范——接口文档概述及YApi平台的使用

前言&#xff1a; 整理下笔记&#xff0c;打好基础&#xff0c;daydayup!!! 接口文档 什么是接口文档&#xff1f; 目前主流的开发模式为前后端分离式开发&#xff0c;为了方便前后端的对接&#xff0c;就需要使用接口文件进行统一规范。 接口文档记载什么信息&#xff1f; 1&…

第19天:信息打点-小程序应用解包反编译动态调试抓包静态分析源码架构

第十九天 本课意义 1.如何获取到目标小程序信息 2.如何从小程序中提取资产信息 一、Web&备案信息&单位名称中发现小程序 1.国内主流小程序平台 微信 百度 支付宝 抖音头条 2.小程序结构 1.主体结构 小程序包含一个描述整体程序的app和多个描述各自页面的page …

goland2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 Goland 是一款由 JetBrains 公司开发的集成开发环境&#xff08;IDE&#xff09;&#xff0c;专门用于 Go 语言的开发。它提供了丰富的功能和工具&#xff0c;帮助开发者更高效地编写、调试和管理 Go 语言项目。 功能特点&#x…

Milvus 老友汇|RAG 场景、电商平台、AI 平台……如何用向量数据库构建业务方案?

近日&#xff0c;Milvus 老友汇Arch Meetup 在深圳圆满落幕。本次 Meetup 由 Milvus 社区携手 Shopee 共同举办&#xff0c;同时还邀请到来自 AWS、点石科技的技术专家&#xff0c;分享电商行业、RAG 场景、AI 平台等如何基于向量数据库构建业务方案。 以下是本次 Meetup 的重点…

OSPF---综合实验

1、R4为ISP&#xff0c;其上只配置IP地址&#xff1b;R4与其他所直连设备间均使用公有IP&#xff1b; 2、R3-R5、R6、R7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个OSPF环境IP基于172.16.0.0/16划分&#xff1b;除了R12有两个环回&#xff0c;其他路由器均有一个环…

HTML 入门

HTML 简介 1. 什么是 HTML&#xff1f; 全称&#xff1a;HyperText Markup Language&#xff08;超文本标记语言&#xff09;。 超文本&#xff1a;暂且简单理解为 “超级的文本”&#xff0c;和普通文本比&#xff0c;内容更丰富。 标 记&#xff1a;文本要变成超文本&…

PLC扩展更自由,钡铼IOy系列模块实现DI/DO/AI/AO任意组合

随着工业自动化的不断发展&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;作为工业控制领域的核心设备&#xff0c;扮演着至关重要的角色。而钡铼IOy系列模块作为PLC的重要扩展设备&#xff0c;不仅实现了DI&#xff08;数字输入&#xff09;、DO&#xff08;数字输出…

TOP100 二分法

写在前面&#xff1a;二分法用在有序序列上 1.35. 搜索插入位置 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 示…

Ubuntu20从0开始选择合适版本手动安装cuda,torch-geometric,jax

一个全新的ubuntu20台式机&#xff0c;在Additional Drivers安装nvidia-470-server&#xff08;一开始安装450&#xff0c;cunda版本只能到11.0&#xff0c;torch有些库用不了&#xff0c;可以直接切换点击Apply Changes重启就行&#xff09; nvidia-smi查看CUDA Version可到…

全球最新国内外18个热门风景视频素材网站推荐

寻找最新的高清风景视频素材&#xff1f;这里有国内外共18个热门网站&#xff0c;精心整理供您选择。 国内资源&#xff1a; 蛙学网&#xff1a;免费提供多种无版权视频素材&#xff0c;资源丰富。新GG网&#xff1a;需QQ登录&#xff0c;提供丰富的视频模板&#xff0c;通过…

vue快速入门(十七)v-model数据双向绑定修饰符

注释很详细&#xff0c;直接上代码 上一篇 新增内容 v-model.trim 自动去除首尾空格v-model.number 自动转换成数字类型 源码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" con…

基于ADB的Scrcpy实现电脑控制手机

Scrcpy是一个开源的&#xff0c;基于ADB&#xff08;Android 调试桥&#xff09;的手机到电脑上的投屏操控的实现&#xff0c;本文将介绍如何搭建开发环境&#xff0c;使得在Windows系统中去控制投屏的安卓手机。 1. 安装投屏软件 下载Scrcpy软件到电脑上&#xff0c;该软件中…