DataGridView的分级显示,如果想找相关的第三方控件的时候,可以在codeproject中输入datagridview outlook,有个控件,看上去还是很不错的。下面的代码只是简单的实现了这个效果,感觉没必要重写控件。
有图有真相,先看看效果图吧。
好了,这个功能一看就知道了,下面给出完成的代码(数据源的绑定就省略了,思路明白就OK,呵呵)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#region
绘制单元格
private void dgvAlarmLog_RowPostPaint( object sender, DataGridViewRowPostPaintEventArgs e)
{
if (e.RowIndex >= 0 )
{
Graphics g = e.Graphics;
if (dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value == plusImage || dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value == subImage)
{
using (Brush gridBrush = new SolidBrush( this .dgvAlarmLog.GridColor), backColorBrush = new SolidBrush(Color.White), fontBrush = new SolidBrush(System.Drawing.Color.Black))
{
// 去线
Rectangle rect = e.RowBounds;
g.FillRectangle(backColorBrush, rect.X + 30 , rect.Y, dgvAlarmLog.Width, rect.Height - 1 );
// 定义字体
Font font = new Font( " 宋体 " , 10 , FontStyle.Bold);
string str = dgvAlarmLog.Rows[e.RowIndex].Cells[ 3 ].Value.ToString();
// 显示日期
g.DrawString(str, font, fontBrush, rect.X + 50 , rect.Y + 4 );
}
}
}
}
#endregion
#region 显示子数据
private void dgvAlarmLog_CellContentClick( object sender, DataGridViewCellEventArgs e)
{
// 单击图片
if (e.ColumnIndex == 0 && e.RowIndex >= 0 )
{
object imageValue = dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value;
if (imageValue == plusImage) // 展开
{
string [] strs = (dgvAlarmLog.Rows[e.RowIndex].Cells[ 4 ].Value.ToString()).Split( ' ~ ' );
string sdate = strs[ 0 ].Trim(); // 开始时间
string edate = strs[ 1 ].Trim(); // 结束时间
dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value = subImage;
DataRow[] drs = dt.Select( " happen_date>=' " + sdate + " ' and happen_date <=' " + edate + " ' " );
int count = 0 ;
foreach (DataRow dr in drs)
{
dgvAlarmLog.Rows.Insert(e.RowIndex + 1 + (count ++ ), new object [] { blankImage, dr[ " describe " ].ToString(), dr[ " serial_no " ].ToString(), dr[ " happen_date " ].ToString(), dr[ " value " ].ToString(), dr[ " pre_value " ].ToString(), dr[ " avg_value " ].ToString() });
}
}
else if (imageValue == subImage) // 折叠
{
dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value = plusImage;
try
{
object tempImage = dgvAlarmLog.Rows[e.RowIndex + 1 ].Cells[ 0 ].Value;
while (tempImage != plusImage && tempImage != subImage)
{
dgvAlarmLog.Rows.RemoveAt(e.RowIndex + 1 );
tempImage = dgvAlarmLog.Rows[e.RowIndex + 1 ].Cells[ 0 ].Value;
}
}
catch { }
}
}
}
#endregion
private void dgvAlarmLog_RowPostPaint( object sender, DataGridViewRowPostPaintEventArgs e)
{
if (e.RowIndex >= 0 )
{
Graphics g = e.Graphics;
if (dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value == plusImage || dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value == subImage)
{
using (Brush gridBrush = new SolidBrush( this .dgvAlarmLog.GridColor), backColorBrush = new SolidBrush(Color.White), fontBrush = new SolidBrush(System.Drawing.Color.Black))
{
// 去线
Rectangle rect = e.RowBounds;
g.FillRectangle(backColorBrush, rect.X + 30 , rect.Y, dgvAlarmLog.Width, rect.Height - 1 );
// 定义字体
Font font = new Font( " 宋体 " , 10 , FontStyle.Bold);
string str = dgvAlarmLog.Rows[e.RowIndex].Cells[ 3 ].Value.ToString();
// 显示日期
g.DrawString(str, font, fontBrush, rect.X + 50 , rect.Y + 4 );
}
}
}
}
#endregion
#region 显示子数据
private void dgvAlarmLog_CellContentClick( object sender, DataGridViewCellEventArgs e)
{
// 单击图片
if (e.ColumnIndex == 0 && e.RowIndex >= 0 )
{
object imageValue = dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value;
if (imageValue == plusImage) // 展开
{
string [] strs = (dgvAlarmLog.Rows[e.RowIndex].Cells[ 4 ].Value.ToString()).Split( ' ~ ' );
string sdate = strs[ 0 ].Trim(); // 开始时间
string edate = strs[ 1 ].Trim(); // 结束时间
dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value = subImage;
DataRow[] drs = dt.Select( " happen_date>=' " + sdate + " ' and happen_date <=' " + edate + " ' " );
int count = 0 ;
foreach (DataRow dr in drs)
{
dgvAlarmLog.Rows.Insert(e.RowIndex + 1 + (count ++ ), new object [] { blankImage, dr[ " describe " ].ToString(), dr[ " serial_no " ].ToString(), dr[ " happen_date " ].ToString(), dr[ " value " ].ToString(), dr[ " pre_value " ].ToString(), dr[ " avg_value " ].ToString() });
}
}
else if (imageValue == subImage) // 折叠
{
dgvAlarmLog.Rows[e.RowIndex].Cells[ 0 ].Value = plusImage;
try
{
object tempImage = dgvAlarmLog.Rows[e.RowIndex + 1 ].Cells[ 0 ].Value;
while (tempImage != plusImage && tempImage != subImage)
{
dgvAlarmLog.Rows.RemoveAt(e.RowIndex + 1 );
tempImage = dgvAlarmLog.Rows[e.RowIndex + 1 ].Cells[ 0 ].Value;
}
}
catch { }
}
}
}
#endregion
再看一个二级目录的效果图:
源代码下载地址:http://files.cnblogs.com/wangyong/%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9.rar