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