C# Winfrm窗体-库房图、餐厅餐桌图展示

一、整体布局构思

        采用 Panel 和 一些其他控件bt(例如:button、lable或者一些自定义的控件)做出的一个平面图。主要功能包含:1> Panel 上 bt 的自动加载,bt的事件绑定;
                                    2> Panel 与 bt 的同步缩放,滚动条事件的处理;
                                    3> Panel 上 bt 的拖拽,以及对齐线的自动保存处理;

二、Panel的基本配置。
//窗体加载事件
private void Frm_Load(object sender, EventArgs e)
{
   //如果面板内的内容超出了面板的可见范围,将自动滚动面板
   this.PanShow.AutoScroll = true;
}

三、Bt的自动加载。
private void BuildCrib()
{
    // 清除PanShow画布上所有控件
    this.PanShow.Controls.Clear();
    //假如咱们从后台数据库中拿到的建筑信息是DataTable
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        // 自定义后面使用,咱们现在使用Winfrm源生控件Button
	Button cfb = new Button();

	// 设置其Size(宽、高)
	cfb.Size = new Size(Width,Height);

	// 设置其Location(x,y)
	cfb.Location = new Point(x,y);

	// 设置其Name(唯一值)
	cfb.Name="";

	//  设置其显示文本
	cfs.text="";

	// 设置其背景颜色
	cfb.BackColor= Color.LightBlue;	
	
	// 设置其可以拖拽
	cfb.AllowDrop = true;
        
	// 设置其字体、颜色、阴影面积.....
	//...
	
	// 设置其点击或者其他事件
	cfb.MouseDown += new MouseEventHandler(Control_MouseDown);
        cfb.MouseMove += new MouseEventHandler(Control_MouseMove);
        cfb.Click += new MouseEventHandler(Control_Click);
	
	// 将其添加到画布
	 PanShow.Controls.Add(cfb);
    }
}

四、Bt的拖拽。
[DllImport("user32.dll", EntryPoint = "ReleaseCapture")]
public static extern void ReleaseCapture();
[DllImport("user32.dll", EntryPoint = "SendMessage")]
public static extern void SendMessage(int hwnd, int wMsg, int wParam, int lParam);
private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
private const int WM_MOVING = 0x216;//鼠标移动消息
private const int SC_MOVE = 0xF010;//移动信息
private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息
private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息
private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息
private const int SC_MAXIMIZE = 0xF030;//最大化信息
private const int SC_MINIMIZE = 0xF020;//最小化信息


private void Control_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Control control = (Control)sender;
                control.BringToFront(); //将控件置于顶层
                ReleaseCapture();
                SendMessage((int)control.Handle, 0xA1, 2, 0);
		control.BackColor = Color.Plum;
            }
        }
   
protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_MOVING: //如果鼠标移                  
                    base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息
                    if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT
                    {
                        m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION
                        return;//直接返回退出方法
                    }
                    break;
            }
            base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理
        }

protected override void OnMouseMove(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                Control control = Control.FromHandle(this.PanShow.Handle);
                SendMessage(control.Left, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
            }
            base.OnMouseMove(e);
        }

private void Control_Click(object sender, EventArgs e)
	{
		Button bt = sender as Button;
		bt.BackColor = Color.Plum;
	}

五、Panle滚动条事件。
Point scrollPosition=new Point(0,0);//滚动条初始值 
private void PanShow_Scroll(object sender, ScrollEventArgs e)
 {
  // 获取Panel控件的滚动位置  
  scrollPosition.Y = PanShow.VerticalScroll.Value;
  scrollPosition.X = PanShow.HorizontalScroll.Value;
 }

六、Bt的保存。
private void btnSave_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            //获取PanShow中所有的控件
            Control.ControlCollection controls = this.PanShow.Controls;
            foreach (Control control in controls)
            {
                //只要Button类型的控件
                if (control is Button)
                {
                    Button btn = (Button)control;
                    if().......//根据实际情况写
                    当前坐标x= control.Location.X + scrollPosition.X;
                }
            }
        }

七、拖拽对齐网格线绘制。
private void PanShow_Paint(object sender, PaintEventArgs e)
{
    // 清除多余线
    e.Graphics.Clear(PanShow.BackColor);
}

public void Grid_Line(Button bt)
        {
            //可以容忍最大值
            int tolerance = 1;
            // 获取Panel的Graphics对象  
            Graphics g = this.PanShow.CreateGraphics();
            // 清除绘图区域  
            g.Clear(this.PanShow.BackColor);  
            //获取目的控件坐标位置
            Point location = bt.Location;

            // 检查周围Button的坐标,如果相差5px,在其左下角绘制十字线  
            foreach (Control neighbor in this.PanShow.Controls)
            {
                if (neighbor is Button && neighbor != bt)
                {

                    Button neighborButton = (Button)neighbor;
                    Point neighborLocation = neighborButton.Location;

                    #region 纵向
                    if (Math.Abs(location.X - neighborLocation.X) <= tolerance)
                    {
                        // 使用Graphics类绘制十字线 --左上角 
                        using (Pen pen = new Pen(Color.Red, 2))
                        {
                            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                            pen.DashPattern = new float[] { 4.0F, 2.0F, 1.0F, 3.0F }; // 设置虚线的模式 
                            PanShow.CreateGraphics().DrawLine(pen, location.X - 0, location.Y - bt.Height, location.X - 0, location.Y + 2*bt.Height);
                        }
                        // 使用Graphics类绘制十字线 --右上角
                        using (Pen pen = new Pen(Color.Red, 2))
                        {
                            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                            pen.DashPattern = new float[] { 4.0F, 2.0F, 1.0F, 3.0F }; // 设置虚线的模式 
                            PanShow.CreateGraphics().DrawLine(pen, location.X + bt.Width + 0, location.Y - bt.Height, location.X + bt.Width + 0, location.Y + 2*bt.Height);
                        }
                    }
                  #endregion

                    #region 横向
                    if (Math.Abs(location.Y - neighborLocation.Y) <= tolerance)
                    {
                        // 使用Graphics类绘制十字线  
                        using (Pen pen = new Pen(Color.Red, 2))
                        {
                            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                            pen.DashPattern = new float[] { 4.0F, 2.0F, 1.0F, 3.0F }; // 设置虚线的模式 
                            PanShow.CreateGraphics().DrawLine(pen, location.X - bt.Width, location.Y - 0, location.X + 2*bt.Width, location.Y - 0);
                        }

                        // 使用Graphics类绘制十字线  
                        using (Pen pen = new Pen(Color.Red, 2))
                        {
                            pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
                            pen.DashPattern = new float[] { 4.0F, 2.0F, 1.0F, 3.0F }; // 设置虚线的模式 
                            PanShow.CreateGraphics().DrawLine(pen, location.X - bt.Width, location.Y +bt.Height+ 0, location.X + 2 * bt.Width, location.Y +bt.Height+ 0);
                        }
                    }
                    #endregion
                }
            }
        }
八、自定义控件的制作

        后续咱们来日方长.......

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值