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);
}
}
Button控件双击事件不执行的更多相关文章
- Asp:Button控件onclick事件无刷新页面提示消息
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptMana ...
- 【MFC】Button控件和Picture Control的鼠标事件执行顺序
1.Button控件鼠标事件执行顺序 (1) WM_LBUTTONDOWN (2) WM_LBUTTONUP (3) OnBnClickedButton1(); 2.Picture Control的鼠 ...
- C# Windows - Button 控件
.Net Framework提供了一个派生于Control的类System.Windows.Forms.ButtonBase,它实现了Button控件所需的基本功能. System.Windows.F ...
- ASP.net button类控件click事件中传递参数
单击Button会同时触发这两个事件,但先执行Click,后执行Command,在button控件中加上参数属性 CommandArgument='' 在click响应函数中可以用以下代码获得传递的参 ...
- DELPHI控件属性事件说明
常用DELPHI控件属性事件设置说明 常用DELPHI控件属性设置说明目录TForm Class TPanel组件 TToolBar Class TToolButton Class TTimer Cl ...
- C#-WebForm-WebForm开发基础、如何给控件注册事件?——事件委托写法、http无状态性、三层结构
(小知识 - xml:可扩展的标记语言 html:超文本标记语言) 一.创建WebForm:新建→网站 此时文件夹中只有一个 config 文件,打开后 二.在项目下右键添加新项 在设计页面中打开 从 ...
- asp.net动态生成按钮Button控件
1.动态生成button控件及响应服务端和客户端事件 void BindButtons(){ foreach (var item in items) { Button Btn = new Button ...
- UGUI Button控件
今天一起来学习下Button控件, Button控件其实是由Text,Button,Image组件形成的. 这里就简单介绍下Button组件 Interactable: 代表该组件是否进行交互, 我们 ...
- Button 控件
Button 控件是由system.Windows.Forms.button类提供,该控件最常用使用就是编写处理按钮的Click事件及MouseEnter事件代码 常用属性 Text按钮的说明 Ima ...
随机推荐
- 浅析Linux操作系统是如何工作的(思维导图)
SA***189 多任务计算机运转机制如下思维导图所示: 小结: Linux操作系统是一个在时钟的节拍下,各个模块紧密协作.密不可分的整体,而整个Linux系统都是建立在存储程序的基础之上,正是有了程 ...
- 乘风破浪:LeetCode真题_011_Container With Most Water
乘风破浪:LeetCode真题_011_Container With Most Water 一.前言 下面我们继续进行编程练习,可以说对于实际问题的活学活用是非常重要的.比如我们这次的题目,就需要从中 ...
- .NET Reflector注册问题
reflector工具不错, 终于8.x了,也可以注册了,但是不小心注册成standard版本了,但vs中无法使用,于是各种删注册表,后来找到何英涛的解决方案 下面介绍一个Reflector很坑的一个 ...
- August 01st 2017 Week 31st Tuesday
A contented mind is the greatest blessing a man can enjoy in this world. 知足是人生在世最大的幸事. Being content ...
- [EffectiveC++]item22:Declare data members private
将成员变量隐藏在函数接口的背后,可以为“所有可能的实现”提供弹性, 假设我们有一个public成员变量,而我们最终取消了它,多少代码可能会被破坏呢?那是一个不可知的大量. protected成员变量就 ...
- [EffectiveC++]item04:Make sure the objects are initialized before they're used
28 页 C++规定,对象的成员变量的初始化动作发生在进入构造函数本体之前. 构造函数的一个较佳的写法是,使用所谓的member initialization list替换赋值动作. 29页 但请立下 ...
- myeclipse 2013破解注册图文教程
以下这个试过有效 http://www.33lc.com/article/10792.html
- jquery ui tabs(选项卡)插件
参考文档:http://www.css88.com/jquery-ui-api/tabs/ html代码: <div id="tabs"> <ul> < ...
- Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier
php 连接 sqlserver 时, 程序生成的sql语句, 如果在 sqlserver客户端执行时, 可以正确返回结果, 在程序中执行, 总返回 false, 打开调试也没有任何错误. 无意中发现 ...
- 面经:C++篇(持续更新)
一. 左值和右值 L-value中的L指的是Location,表示可寻址.Avalue (computer science)that has an address. R-value中的R指的是Read ...