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);
}
}

Button控件双击事件不执行的更多相关文章

  1. Asp:Button控件onclick事件无刷新页面提示消息

    <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptMana ...

  2. 【MFC】Button控件和Picture Control的鼠标事件执行顺序

    1.Button控件鼠标事件执行顺序 (1) WM_LBUTTONDOWN (2) WM_LBUTTONUP (3) OnBnClickedButton1(); 2.Picture Control的鼠 ...

  3. C# Windows - Button 控件

    .Net Framework提供了一个派生于Control的类System.Windows.Forms.ButtonBase,它实现了Button控件所需的基本功能. System.Windows.F ...

  4. ASP.net button类控件click事件中传递参数

    单击Button会同时触发这两个事件,但先执行Click,后执行Command,在button控件中加上参数属性 CommandArgument='' 在click响应函数中可以用以下代码获得传递的参 ...

  5. DELPHI控件属性事件说明

    常用DELPHI控件属性事件设置说明 常用DELPHI控件属性设置说明目录TForm Class TPanel组件 TToolBar Class TToolButton Class TTimer Cl ...

  6. C#-WebForm-WebForm开发基础、如何给控件注册事件?——事件委托写法、http无状态性、三层结构

    (小知识 - xml:可扩展的标记语言 html:超文本标记语言) 一.创建WebForm:新建→网站 此时文件夹中只有一个 config 文件,打开后 二.在项目下右键添加新项 在设计页面中打开 从 ...

  7. asp.net动态生成按钮Button控件

    1.动态生成button控件及响应服务端和客户端事件 void BindButtons(){ foreach (var item in items) { Button Btn = new Button ...

  8. UGUI Button控件

    今天一起来学习下Button控件, Button控件其实是由Text,Button,Image组件形成的. 这里就简单介绍下Button组件 Interactable: 代表该组件是否进行交互, 我们 ...

  9. Button 控件

    Button 控件是由system.Windows.Forms.button类提供,该控件最常用使用就是编写处理按钮的Click事件及MouseEnter事件代码 常用属性 Text按钮的说明 Ima ...

随机推荐

  1. css 笔记1

    type="text/css"的作用是什么?它是CSS样式的标记.type->类型,这里是style的属性text/css ->文本/css,即css文本type=&q ...

  2. [EffectiveC++]item22:Declare data members private

    将成员变量隐藏在函数接口的背后,可以为“所有可能的实现”提供弹性, 假设我们有一个public成员变量,而我们最终取消了它,多少代码可能会被破坏呢?那是一个不可知的大量. protected成员变量就 ...

  3. codeforces 388D Fox and Perfect Sets(线性基+数位dp)

    #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define mp mak ...

  4. 防止开放重定向,恶意篡改returnUrl

    1.防止开放重定向: /// <summary> /// 防止开放重定向 /// </summary> /// <param name="url"&g ...

  5. JAVA Color类

    Color类用于定义颜色,java.awt.Color中提供了13个预定义的常量用来表示13中标准颜色,分别是: public static final Color white白色. public s ...

  6. Java工具类(util) 之01- 数学运算工具(精确运算)

    数学运算工具(精确运算) /** * * @author maple * */ public abstract class AmountUtil { private AmountUtil() { } ...

  7. BZOJ1731:[USACO]Layout 排队布局(差分约束)

    Description Like everyone else, cows like to stand close to their friends when queuing for feed. FJ ...

  8. 【[CQOI2018]交错序列】

    这个题简直有毒,\(O((a+b)^3logn)\)的做法不卡常只比\(O(2^n*n)\)多\(10\)分 看到\(a\)和\(b\)简直小的可怜,于是可以往矩阵上联想 发现这个柿子有些特殊,好像可 ...

  9. max函数

    无论是几维,都只返回一个最大的值 >>> a = [1,2,3] >>> np.max(a) 3 >>> a = [[2,1],[3,4]] &g ...

  10. multimap详讲

    multimap和map的区别: 首先认识一下multimap和map的区别: 1>        multimap不提供operator[ ]运算符.因为这个运算符的语义在同一个键可以保存多个 ...