zoukankan      html  css  js  c++  java
  • Button控件双击事件不执行

    Button控件双击事件不执行

    最近组态组新加入了一位同事,该同事原先是做ASP.NET的,没有做过WindowForm的开发。所以就先安排一个小示例来测验一下。这个示例有些年头了,当年我进入组态开发时候,总监也是安排了这个示例来入门^_^。
    需求是这样的:

    • 双击软件界面空白处,出现一个按钮,该按钮可以拉伸和移动
    • 可修改按钮内的文字描述
    • 下次打开软件,还是上一次的布局

    大概一天时间,界面是这样的:最初界面
    代码是这样的:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.IO;
    
    namespace WinFormTest1
    {
        public partial class FormButtonTest : System.Windows.Forms.Form
        {
            public FormButtonTest()
            {
                InitializeComponent();
            }
            private int i=1;
            private Control downCtrl;
            private Point downLoc;
            bool ctrlMove;
            bool ctrlZoom;
            public static string str = "";
            private void FormButtonTest_MouseDoubleClick(object sender, MouseEventArgs e)
            {
                Button btn = new Button();
                btn.Name = "btn" + i.ToString();
                btn.Text = "Button"+i.ToString();
                btn.Location = e.Location;
                btn.Cursor = Cursors.Default;  
                this.Controls.Add(btn);
                btn.MouseDown += new MouseEventHandler(this.btn_MouseDown);
                btn.MouseUp += new MouseEventHandler(this.btn_MouseUp);
                btn.MouseMove += new MouseEventHandler(this.btn_MouseMove);
                btn.Click += new EventHandler(this.btn_Click);
                i++;
            }
            private void btn_MouseDown(object sender, MouseEventArgs e)
            {
                downCtrl = sender as Control;
                downLoc = e.Location;
                if (downCtrl.Cursor == Cursors.SizeAll)
                {
                    ctrlMove = true;
                    ctrlZoom = false;
                }
                else if (downCtrl.Cursor == Cursors.SizeNESW || downCtrl.Cursor == Cursors.SizeNS || downCtrl.Cursor == Cursors.SizeNWSE || downCtrl.Cursor == Cursors.SizeWE)
                {
                    ctrlMove = false;
                    ctrlZoom = true;
                }
                
            }
            private void btn_MouseUp(object sender, MouseEventArgs e)
            {
                Control control = sender as Control;
                //if ((e.Button == MouseButtons.Left) && ctrlZoom)
                //{
                //    control.Width += e.X - downLoc.X;
                //    control.Height += e.Y - downLoc.Y;
                //}
                ctrlMove = false;
                ctrlZoom = false;
            }
            private void btn_MouseMove(object sender, MouseEventArgs e)
            {
                Control control = sender as Control;
                Point p1 = PointToClient(Control.MousePosition);
                int x = p1.X;
                int y = p1.Y;
                if (x >= control.Right - 10 && x <= control.Right + 10 && y >= control.Bottom - 10 && y <= control.Bottom + 10) //右下角
                {
                    control.Cursor = Cursors.SizeNWSE;
                }
                else if (x >= control.Left + 10 && x <= control.Right - 10 && y >= control.Bottom - 10 && y <= control.Bottom + 10) //下边界
                {
                    control.Cursor = Cursors.SizeNS;
                }
                else if (x >= control.Right - 10 && x <= control.Right + 10 && y >= control.Top + 10 && y <= control.Bottom - 10) //右边界
                {
                    control.Cursor = Cursors.SizeWE;
                }
                else if (x >= control.Left - 10 && x <= control.Right + 10 && y >= control.Top - 10 && y <= control.Top + 10)
                {
                    control.Cursor = Cursors.SizeAll;
                }
                else if (x > control.Left + 10 && x < control.Right - 10 && y > control.Top + 10 && y < control.Bottom - 10)
                {
                    control.Cursor = Cursors.Default;
                }
    
                if ((e.Button == MouseButtons.Left) && ctrlMove)
                {
                    int pos_x, pos_y;
                    pos_x = downCtrl.Location.X + (e.X - downLoc.X);
                    pos_y = downCtrl.Location.Y + (e.Y - downLoc.Y);
                    control.Location = new Point(pos_x, pos_y);
                }
                if ((e.Button == MouseButtons.Left) && ctrlZoom)
                {
                    int width = x - downCtrl.Location.X;
                    int height = y - downCtrl.Location.Y;
                    control.Width = control.Cursor == Cursors.SizeNS ? control.Width : (width > 0 ? width : 1);
                    control.Height = control.Cursor == Cursors.SizeWE ? control.Height : (height > 0 ? height : 1);
                }
    
            }
            public void formChild_accept(object sender, EventArgs e)
            {
                //事件的接收者通过一个简单的类型转换得到Form的引用
                FormChild formChild = (FormChild)sender;
                str = formChild.FormChildValue;
                //MessageBox.Show(str);
            }
    
            private void btn_Click(object sender, EventArgs e)
            {
                Control control = sender as Control;
                if ((control.Cursor == Cursors.Default) && !ctrlMove && !ctrlZoom)
                {
                    FormChild formChild = new FormChild();
                    formChild.FormChildValue = control.Text;
                    formChild.accept += new EventHandler(formChild_accept);
                    formChild.ShowDialog(this);
                    control.Text = str;
                }
            }
    
            private void FormButtonTest_FormClosing(object sender, FormClosingEventArgs e)
            {
                FileStream fs = new FileStream(@"../../a.txt", FileMode.Create);
                StreamWriter sw = new StreamWriter(fs);
                foreach (Control ctrl in this.Controls)
                {
                    sw.WriteLine(ctrl.Name + "|" + ctrl.Text + "|" + ctrl.Top + "|" + ctrl.Left + "|" + ctrl.Width + "|" + ctrl.Height + "|" +  i);
                }
                sw.Flush();
                sw.Close();
                fs.Close();
            }
    
            private void FormButtonTest_Load(object sender, EventArgs e)
            {
                if (File.Exists(@"../../a.txt"))
                {
                    StreamReader sr = new StreamReader(@"../../a.txt", Encoding.Default);
                    string lineString;
                    while ((lineString = sr.ReadLine()) != null)
                    {
                        string[] line = lineString.Split('|');
                        Button btn = new Button();
                        btn.Name = line[0];
                        btn.Text = line[1];
                        btn.Top = int.Parse(line[2]);
                        btn.Left = int.Parse(line[3]);
                        btn.Width = int.Parse(line[4]);
                        btn.Height = int.Parse(line[5]);
                        i = int.Parse(line[6]);
                        btn.Cursor = Cursors.Default;
                        this.Controls.Add(btn);
                        btn.MouseDown += new MouseEventHandler(this.btn_MouseDown);
                        btn.MouseUp += new MouseEventHandler(this.btn_MouseUp);
                        btn.MouseMove += new MouseEventHandler(this.btn_MouseMove);
                        btn.Click += new EventHandler(this.btn_Click);
                    }
                    sr.Close();
                }
            }
        }
    }
    

    总体来看也勉勉强强,但我对于代码有点洁癖,不简洁的代码就不是好代码,严于律己,对其他人就不强求。讲解了一下其中的不足之处。

    • 可进行移动的按钮区域做在边框上,不友好,很难点到可以移动。
    • 修改描述的部分,确定和取消的逻辑没有区分开。
    • 修改描述的窗体没有居中显示

    然后又提出了新的需求,需求总是会变的嘛。

    • 保存的文本改为Json格式
    • 加入能够双击新建文本控件,并且也可以拖动和拉伸
    • 修改文本描述,改为双击执行修改
    • 移动控件,但不能超出软件界面

    然后又过了一天,我再次审查,该同事跟我说了一下,他遇到的几个困难

    • 如何确定什么时候需要新建文本控件
    • 按钮的双击事件不起作用

    对于第一个问题,我给了一个方案,你可以使用两个事先确定的两个按钮功能,点新建文本控件按钮的时候,那么后面双击空白界面的时候就新建出文本控件来,如果点了新建按钮控件的那个按钮,则后面双击空白界面的时候就新建出按钮控件。
    第二个问题,该同事是找到解决方案的,解决按钮的双击事件不起作用。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WinFormTest1
    {
        public class ButtonEx : Button
        {
            public new event EventHandler DoubleClick;
            DateTime clickTime;
            bool isClicked = false;
            protected override void OnClick(EventArgs e)
            {
                base.OnClick(e);
                if (isClicked)
                {
                    TimeSpan span = DateTime.Now - clickTime;
                    if (span.TotalMilliseconds < SystemInformation.DoubleClickTime)
                    {
                        DoubleClick(this, e);
                        isClicked = false;
                    }
                    else                                                                         
                    {
                        isClicked = true;
                        clickTime = DateTime.Now;
                    }
                }
                else
                {
                    isClicked = true;
                    clickTime = DateTime.Now;
                }
            }
        }
    }
    

    看了还是略显复杂了,但最终也是解决了问题。其实对于这个问题,有一个简单的处理即可。

    public class ButtonEx:Button
    {
        public ButtonEx()
        {
            this.SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, true);
        }
    }
    
  • 相关阅读:
    LayoutInflater作用及使用
    php学习-数组(一)
    jQuery中$.get、$.post、$.getJSON和$.ajax的用法
    input的onchange事件实际触发条件与解决方法
    input有许多,点击按钮使用form传递文本框的值
    CI分页器pagination的原理及实现
    form表单传递下拉框的Value和Text值,不适用Jquery传递
    Servlet实现文件上传(多文件)(三)
    Servlet实现文件上传(深度)(二)
    Servlet实现文件上传(简单)(一)
  • 原文地址:https://www.cnblogs.com/zzr-stdio/p/10528161.html
Copyright © 2011-2022 走看看