[C#]死循环:我给自己挖了个坑!

写了个父子页面的传值(交互),竟整出个死循环来,最后纠结地自己去填自己挖的坑(还好不是填别人的坑),废话不说,开始主题.

1. 问题的发生

根据父窗体中的输入值,在数据库中查询资料,并在子窗体加载的时候根据资料的不同显示不同的颜色,子页面中根据输入对数据库中的数据做一些修改,返回父窗体时,检查这些修改,并判断是否要修改父窗体中这些值的显示颜色。

父窗体

子窗体

即当子窗体中QTY输入框输入的值等于DataGridView中ISQTY的值时(小于实现每次输入的累加),修改本条记录的显示颜色为蓝色。当点击返回或是关闭子窗体时(关闭子窗体和返回按钮实现的效果相同,检查子窗体中值的显示颜色,并决定是否要改变父窗体MO列的显示颜色),如果子窗体中的记录都显示为蓝色,要改变父窗体中对应的MO列显示的颜色为蓝色。问题就发生在点击返回或是点击关闭子窗体时。

2. 问题的表现及导致发生问题的代码

“返回”按钮的单击事件

private void btnReturn_Click(object sender, EventArgs e)
{   //-----------------根据子窗体中显示颜色判断是否要改变父窗体中值的显示颜色--------
 
    #region 返回父窗体
    CHECK_MO_MATERIAL cmm = (CHECK_MO_MATERIAL)this.Owner;//CHECK_MO_MATERIAL父窗体的名称
    if ( cmm != null )
    {
        cmm.moChangeFlag = moFlag;
        cmm.ChangeMoColor();
    }    
    #endregion
    this.Close();
}

窗体的关闭事件

private void CHECK_MO_MATERIAL_CONFIG_FormClosing(object sender, FormClosingEventArgs e)
{
    btnReturn_Click(sender, e);
}

到这里你一定发现的问题的发生的,不喜勿碰,本人旨在分享而已。

3. 问题的查找

那个报错的图片很大程度会转移注意力,可能是调用的.Net的库的版本不兼容导致的,或是像我一样的不幸运,在自己的电脑上根本就不会发生,这些在很大程度会转移问题的定位,但是到什么时候,都不要Debug!我就一步一步跟着走,看是在哪里走进了死胡同。

如果上面的代码还是没看出来,试着看下面的精简版本

private void btnReturn_Click(object sender, EventArgs e)
{ 
    //-----------------根据子窗体中显示颜色判断是否要改变父窗体中值的显示颜色--------
    this.Close();
}
private void CHECK_MO_MATERIAL_CONFIG_FormClosing(object sender, FormClosingEventArgs e)
{
    btnReturn_Click(sender, e);
}

4. 问题的分析

我只是想在点关闭关闭窗体和返回按钮时实现相同的效果,结果却写出了这么挫的东东,我想剁掉自己的小手手......

一个死循环就此诞生,返回按钮的this.Close()方法会导致窗体关闭,从而导致执行FormClosing()窗体事件,而窗体FormClosing()事件调用返回按钮的方法,由此A调用B,B反过来调用A,再也没有结束的机会。

4. 问题的解决

知道问题的原因,解决办法总是会有很多种,下面是其中的一种,欢迎你写下自己的想法,分享,共同成长...

private void btnReturn_Click(object sender, EventArgs e)
{ 
    this.Close();
}
private void CHECK_MO_MATERIAL_CONFIG_FormClosing(object sender, FormClosingEventArgs e)
{
    //-----------------根据子窗体中显示颜色判断是否要改变父窗体中值的显示颜色--------
    #region 返回父窗体
    CHECK_MO_MATERIAL cmm = (CHECK_MO_MATERIAL)this.Owner;//CHECK_MO_MATERIAL父窗体的名称
    if ( cmm != null )
    {
        cmm.moChangeFlag = moFlag;
        cmm.ChangeMoColor();
    }    
    #endregion
}

4. 你可能学到的小知识

  • 如果FormClosing事件到调用的方法包含关闭当前窗体的方法(如本文中的this.Close()),那么就会导致死循环的发生。
  • 窗体之间的传值,如想把子窗体的值传给父窗体,可在父窗体中定义一个Public类型的变量,在子窗体返回时给父窗体的该变量赋值
#region 父窗体跳轉到子窗體
CHECK_MO_MATERIAL_CONFIG cmmc = new CHECK_MO_MATERIAL_CONFIG();//CHECK_MO_MATERIAL_CONFIG子窗体的名称
cmmc.moFromParantForm = this.tbMo.Text.Trim().ToUpper();
cmmc.opFromParantForm = this.tbOp.Text.Trim().ToUpper();
cmmc.categoryFromParantForm = this.cmbCategory.SelectedItem.ToString();
cmmc.Owner = this;
cmmc.Show();//cmmc.ShowDialog();//顯示子窗體,隱藏父窗體
#endregion

#region 子窗体返回父窗体
CHECK_MO_MATERIAL cmm = (CHECK_MO_MATERIAL)this.Owner;//CHECK_MO_MATERIAL父窗体的名称
if ( cmm != null )
{
    cmm.moChangeFlag = moFlag;
    cmm.ChangeMoColor();
}
#endregion
  • 设置DataGridView中数值的显示颜色
dgvMoDetails.Rows[i].Cells["時間"].Style.ForeColor = Color.DarkBlue;
  • 获取或设置DataGridView控件中某一单元格的值
dgvMoDetails.Rows[i].Cells["時間"].Value = "xxxx";
  • 点击DataGridView的标题列,禁止刷新(排序)DataGridView中的数据(注意以下方法要在DataGridView控件绑定数据之后执行)
private void ForbidSortColumn(DataGridView dgv)
{
    for ( int i = 0 ; i < dgv.Columns.Count ; i++ )
    {
        dgv.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
    }
}
  • 禁止移动窗体(改变窗体的位置)(直接在窗体类中添加以下方法)
protected override void WndProc(ref Message m)
{
    const int WM_NCLBUTTONDOWN = 161;
    const int WM_SYSCOMMAND = 274;
    const int HTCAPTION = 2;
    const int SC_MOVE = 61456;

    if ( (m.Msg == WM_SYSCOMMAND) && (m.WParam.ToInt32() == SC_MOVE) )
        return;
    if ( (m.Msg == WM_NCLBUTTONDOWN) && (m.WParam.ToInt32() == HTCAPTION) )
        return;
    base.WndProc(ref m);

}
时间: 2024-08-24 15:22:05

[C#]死循环:我给自己挖了个坑!的相关文章

记录这几天挖的一个坑

最最根本的原因: public String func1( Object args ) { char [] flags = new char[60]; ... ... return flags.toString();            // java 基础不扎实!!!还"理所当然"地就用了.  应该使用 // return new String(flags); } 挖坑经过及其原因: 间接原因:  !!!自己没有写单元测试就仍上去了!!!   做为一个coder,未达标 再间接原因

我刚到现在公司的时候挖了一个坑,现在我正在努力把这个坑填上

我刚到现在公司的时候挖了一个坑,现在我正在努力把这个坑填上. 我仔细并且理智的想想,领导有一部分责任,我也有一部分责任,领导的设计的有问题,而我没有及时发现这个问题. 我做的这个功能是个调查活动,但不仅仅是一般的调查活动,包括指标评测活动和普通调查活动.原来的数据库是这样设计的:调查活动表关联一个问卷模板,问卷模板关联题目,有个严重的问题,就是很多调查活动可能关联了同一个模板,而这个模板有人会修改,那就意味着,在活动进行过程中,以及后面的统计,都会出问题.我现在是这样设计的:调查活动表直接关联题

拆分又遇变数,传赛门铁克或将出售VERITAS,这又是挖的什么坑?

按原定的拆分计划,赛门铁克与VERITAS两家公司将于2016年1月正式完成法律上的拆分,成为两家独立运营的公司.正如之前笔者的<十年之后--赛门铁克.VERITAS中国区高层首谈拆分后战略>一文所述,目前在中国,赛门铁克与VERITAS正按部就班地以拆分为最终目标而进行运作.据悉,VERITAS正在申请公司中文注册名称,并计划于拆分后独立上市等. 就在赛门铁克与VERITAS拆分计划顺利进行之时,又横生枝节.今天爆出一条新闻:外媒援引匿名人士消息,赛门铁克公司正准备出售VERITAS业务部门

自己给自己挖了个坑,struts2访问Action 404

今天发布工程,访问其中一个模块,老是返回404异常. /vweb/view/vweb.action 查看struts2配置文件和Action中的方法,没有问题啊. 于是怀疑是缓存引起的. rm -rf Catalina/ 结果还是不行. 忽然想到了 tomcat的server.xml中加了对应的模块的资源映射 <Context docBase="/home/resource/vweb/" path="/vweb"/> 可能是path="/vwe

js简直了,连大小都不能直接比,还变量提升,这个是挖了多少坑啊,故意的把,,,,写起来又不简单,运行起来又不是很稳,很迷啊

如题,var eq = tr.eq(i);            var kucun_amt = eq.children('td#inputline').find('input').val();            var L7_amt = eq.children('td#L7').text();            var check1 = kucun_amt - L7_amt <=0;这样写是可以的 但是如果俩变量比大小就得parseInt($.trim($("#max"

并行编程之多线程共享非volatile变量,会不会可能导致线程while死循环

背景 大家都知道线程之间共享变量要用volatile关键字.但是,如果不用volatile来标识,会不会导致线程死循环?比如下面的伪代码: static int flag = -1; void thread1(){ while(flag > 0){ //wait or do something } } void thread2(){ //do something flag = -1; } 线程1,线程2同时运行,线程2退出之后,线程1会不会有可能因为缓存等原因,一直死循环? 真实的世界 第一个坑

斯坦福大学操作系统

Pintos-斯坦福大学操作系统Project详解-Project1 前言:  本实验来自斯坦福大学cs140课程,只限于教学用途,以下是他们对于Pintos系统的介绍:  Pintos is a simple operating system framework for the 80x86 architecture. It supports kernel threads, loading and running user programs, and a file system, but it

【JavaScript】让事件支持先发布后订阅

之前写过一个的事件管理器,就是普通的先订阅后发布模式.但实际场景中我们需要做到后订阅的也能收到发布的消息.比如我们关注微信公众号,还是能看到历史消息的.类似于qq离线消息,我先发给你,你登录了就能收到了.就是确保订阅该事件的方法都能被执行. var eventManger = { cached: {}, handlers: {}, //类型,绑定事件 addHandler: function (type, handler) { if (typeof handler !== "function&q

一位资深开发的个人经历 【转自百度贴吧 java吧 原标题 4年java 3年产品 现在又开始做android了】

楼主2007年从一家天津的三流大学毕业.毕业前报了一个职位培训,毕业后可以推荐工作.因为推荐的公司都是北京的,所以就来北京了. 找了一个月工作,没有找到要我的,就在出租屋里宅了起来,打着考研的旗号,又耗了一年.研究生肯定没有考上,这下没有退路了,又开始找工作了.记得宅出租屋的那年,过年没有回家.正好我有一个姑姑在石家庄过年,就非要我过去.过完年,姑姑回家和老妈说,我穿了一条破牛仔裤,头发长长的.言外之意,我在北京日子不好过. 后来老妈给我打电话,我都说,挺好的,没事儿,我姑姑就是好几年没见我了,