Winform编程中遇到的坑

坑1. DataGridView设置网格背景色
情景:当窗体载入时,网格DataGridView显示从数据库中查询到的数据,其中一些特殊列的特定值需要设置特殊背景色,如“是否已上传”列,如果值为“已上传”,则标记为黄色等。
习惯性上,我们会在Winfrom的load事件中执行数据查询操作,绑定网格,设置网格背景色等。

 //ds_tasks 为查询到的数据集
 this.dgv_HistoryTasks.InitDgvWithoutAutoSizeCol();
 if (ds_tasks.Tables[0].Rows.Count > 0)
    {
      this.dgv_HistoryTasks.DataSource = ds_tasks.Tables[0];
      this.dgv_HistoryTasks.ClearSelection();

      for (int i = 0; i < this.dgv_HistoryTasks.Rows.Count; i++)
         {
        if (this.dgv_HistoryTasks.Rows[i].Cells["is_upload"].Value.ToString().Equals("1"))
            {     
                   this.dgv_HistoryTasks.Rows[i].Cells["is_upload"].Value = "是";  
                   //设置单元格背景色            
                    this.dgv_HistoryTasks.Rows[i].Cells["is_upload"].Style.BackColor = Color.Yellow;                         

              } else
                 {
                   this.dgv_HistoryTasks.Rows[i].Cells["is_upload"].Value = "否";
                    }
                  }

   //设置网格显示格式                  
    this.dgv_HistoryTasks.Columns["task_create_time"].DefaultCellStyle.Format = "yyyy/MM/dd HH:mm:ss ";
    this.dgv_HistoryTasks.Columns["task_id"].Frozen = true;
    this.dgv_HistoryTasks.Columns["task_create_time"].Frozen = true;

然而,写完以上代码,运行程序,你会发现数据成功绑定在网格内,然而背景色却并没有显示。单步调试发现,背景色设置语句又确实执行了。那么只有一个可能,load事件之后的事件方法覆盖的网格的背景色。
换种思路,那就在窗体展示出来后,再设置网格背景色。就将上面设置单元格背景色的语句放在Winform的Shown事件中。
Shown:只有在首次显示窗体时才会引发 Shown 事件;随后执行的最小化、最大化、还原、隐藏、显示或无效化和重新绘制操作都不会引发该事件。

 DataTable dt = (DataTable)this.dgv_HistoryTasks.DataSource;
 if (dt != null && dt.Rows.Count > 0)
     {
       for (int i = 0; i < this.dgv_HistoryTasks.Rows.Count; i++)
          {
             if (this.dgv_HistoryTasks.Rows[i].Cells["is_upload"].Value.ToString().Equals("是"))
                 {
                    this.dgv_HistoryTasks.Rows[i].Cells["is_upload"].Style.BackColor = Color.Yellow;

                    }

          }
       }

坑2. DateTimePicker设置时间
情景:在winform窗体中放置了一个DEVExpress的tabPane控件,并新建了两个tabPage选项页。第一个tabPage放置一个DateTimePicker,第二个TabPage页也放置一个tabPage页。在窗体载入时,给两个DateTimePicker赋值日期和时间(格式为:yyMMddHHmmss)。

 // 日期和时间合并到一起                  
 this.dtp_StartTimeError.Value = DateTime.ParseExact("170511061155", "yyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);//将字符串时间转换成DateTime类型                              

神奇的地方来了,如果窗体载入时,默认显示第一个tabPage页,则第一个TabPage的DateTimePicker控件显示正常,第二个TabPage页的时间显示就不正确,日期是赋值时给的日期,但时分秒却是系统时间,即DateTimePicker的value和text不一致。如果窗体载入时,默认显示第二个tabPage页,则情况正好相反。单步调试,可以看到两个TabPage页的value值都是正常的,即都是所赋的值。真是坑!
后来,考虑是不是后面窗体调用的方法,覆盖了DateTimePicker的值。于是,将赋值操作放在了窗体的Shown方法内实现,结果运行发现,DateTimePicker显示正常了。到这,以为问题解决了。然而,too young too simple。运行了几次后,上述问题又出现了,这。。。。。相当无语。
再后来,想想DateimePicker的value值一直是正确的,但是显示出来DateimePicker的text却有问题,是不是控件绑定值时出现了问题。于是,在赋值操作的最后增加了控件刷新操作,强制DateTimePicker重新刷新一次。

 //2017.12.27 刷新控件
  this.dtp_StartTimeError.Refresh();
  this.dtp_EndTimeError.Refresh();

到目前为止,尚未出现以上时间显示不正确的问题了。
为什么DateimePicker会跟所赋的值显示的不一样,猜想是不是DEVExpress的控件与微软的窗体控件在某些地方有冲突。没找到确切答案。
记录几个时间转换的小Tip:

        /// <summary>
        /// 将时间转换成时分秒(时间如:061155)
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static string getHHMMSS(string time)
        {
            string hhmmss = "";
            for (int i = 0; i < 3; i++)
            {
                string temp = time.Substring(0, 2);
                hhmmss = hhmmss + temp + ":";
                time = time.Remove(0, 2);
            }
            hhmmss = hhmmss.Substring(0, 8);
            return hhmmss;
        }
1)DateTimePicker只显示时分秒,如06:11:55
设置DateTimePicker 的Format 属性设为 Custom ,CustomFormat 属性设为 "HH:mm:ss"
按如下赋值:
string st_hhmmss=getHHMMSS("061155");//时分秒06:11:55
this.dtp_StartTime.Value = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " " + st_hhmmss);2)DateTimePicker显示日期和时分秒,如2017/05/11 06:11:55
设置DateTimePicker 的Format 属性设为 Custom ,CustomFormat 属性设为 "yyyy/MM/dd HH:mm:ss"
//将字符串时间转换成DateTime类型
this.dtp_StartTime.Value = DateTime.ParseExact("170511061155", "yyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);

  // 设置最大值最小值 
  this.dtp_StartTimeError.MinDate = DateTime.ParseExact("170511061155", "yyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
 this.dtp_StartTimeError.MaxDate = DateTime.ParseExact("170511061155", "yyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);

猜你喜欢

转载自blog.csdn.net/nancy50/article/details/78904836