csharp
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;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private readonly Image _plusImage = Resource.Plus;
private readonly Image _minusImage = Resource.Minus;
private readonly Image _blankImage = Resource.Blank;
private readonly string _imageColumnName = "imageColumn";
private readonly string _checkedColumnName = "checkedColumn";
private readonly string _nameColumnName = "deptNameColumn";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<DataItem> dataItems = new List<DataItem>()
{
new DataItem(){Expanded=true,Id=100,Name="门诊部"},
new DataItem(){Id=101,Name="儿科门诊",Description="专为儿童服务,限制年龄"},
new DataItem(){Id=102,Name="妇科门诊",Description="转为女性服务,限制性别"},
new DataItem(){Id=103,Name="内科门诊",Description="内科"},
new DataItem(){Expanded=true,Id=200,Name="住院部"},
new DataItem(){Id=201,Name="泌尿科",Description="泌尿专科"},
new DataItem(){Id=202,Name="骨伤科",Description="骨科专科"},
new DataItem(){Id=203,Name="妇产科",Description="妇科+产科"},
new DataItem(){Id=204,Name="消化科",Description="消化科"},
};
dataItemDataGridView.Rows.Clear();
/* foreach (DataItem dataItem in dataItems)
{
int count = dataItemDataGridView.Rows.Count;
dataItemDataGridView.Rows.Insert(dataItemDataGridView.Rows.Count, new object[] { !dataItem.Expanded.HasValue ? _blankImage : dataItem.Expanded.Value ? _minusImage : _plusImage, dataItem.Checked, dataItem.Name, dataItem.Description, dataItem.Id });
dataItemDataGridView.Rows[count].Tag = dataItem;
dataItemDataGridView.Rows[count].Visible = dataItem.Visible;
}*/
foreach (DataItem dataItem in dataItems)
{
DataGridViewRow row = new DataGridViewRow();
row.Cells.Add(new DataGridViewImageCell() { Value = dataItem.Expanded.HasValue ? (dataItem.Expanded.Value ? _minusImage : _plusImage) : _blankImage });
row.Cells.Add(new DataGridViewCheckBoxCell() { Value = dataItem.Checked });
row.Cells.Add(new DataGridViewTextBoxCell() { Value = dataItem.Name });
row.Cells.Add(new DataGridViewTextBoxCell() { Value = dataItem.Description });
row.Cells.Add(new DataGridViewTextBoxCell() { Value = dataItem.Id });
row.Tag = dataItem;
row.Visible = dataItem.Visible;
dataItemDataGridView.Rows.Add(row);
}
dataItemDataGridView.CellContentClick += dataItemDataGridView_CellContentClick;
}
/// <summary>
/// 实现折叠/展开
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void dataItemDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
DataGridViewRowCollection rows = dataItemDataGridView.Rows;
if (e.ColumnIndex == 0)
{
Image image = rows[e.RowIndex].Cells[_imageColumnName].Value as Image;
bool isChecked = (bool)rows[e.RowIndex].Cells[_checkedColumnName].Value;
string name = rows[e.RowIndex].Cells[_nameColumnName].Value as string;
if (image == _plusImage)
{
dataItemDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = _minusImage;
int index = e.RowIndex + 1;
while (index < rows.Count && rows[index].Cells[_imageColumnName].Value != _plusImage && rows[index].Cells[_imageColumnName].Value != _minusImage)
{
dataItemDataGridView.Rows[index].Visible = true;
index++;
}
}
else if (image == _minusImage)
{
dataItemDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = _plusImage;
int index = e.RowIndex + 1;
while (index < rows.Count-1 && rows[index].Cells[_imageColumnName].Value != _plusImage && rows[index].Cells[_imageColumnName].Value != _minusImage)
{
dataItemDataGridView.Rows[index].Visible = false;
index++;
}
}
}
else if (e.ColumnIndex == 1)
{
bool isChecked = !(bool)rows[e.RowIndex].Cells[_checkedColumnName].Value;
dataItemDataGridView.Rows[e.RowIndex].Cells[_checkedColumnName].Value = isChecked;
DataItem dataItem = dataItemDataGridView.Rows[e.RowIndex].Tag as DataItem;
dataItem.Checked = isChecked;
Image image = rows[e.RowIndex].Cells[_imageColumnName].Value as Image;
if (image == _plusImage || image == _minusImage)
{
int index = e.RowIndex + 1;
while (index < rows.Count && rows[index].Cells[_imageColumnName].Value != _plusImage && rows[index].Cells[_imageColumnName].Value != _minusImage)
{
dataItemDataGridView.Rows[index].Cells[_checkedColumnName].Value = isChecked;
dataItem = dataItemDataGridView.Rows[index].Tag as DataItem;
dataItem.Checked = isChecked;
index++;
}
}
else
{
bool isGroupAllChecked = true;
int index = e.RowIndex;
while (index < rows.Count && rows[index].Cells[_imageColumnName].Value != _plusImage && rows[index].Cells[_imageColumnName].Value != _minusImage)
{
if (!(bool)rows[index].Cells[_checkedColumnName].Value)
isGroupAllChecked = false;
index++;
}
index = e.RowIndex - 1;
while (index >= 0 && rows[index].Cells[_imageColumnName].Value != _plusImage && rows[index].Cells[_imageColumnName].Value != _minusImage)
{
if (!(bool)rows[index].Cells[_checkedColumnName].Value)
isGroupAllChecked = false;
index--;
}
if (index >= 0 && (bool)rows[index].Cells[_checkedColumnName].Value != isGroupAllChecked)
dataItemDataGridView.Rows[index].Cells[_checkedColumnName].Value = isGroupAllChecked;
}
}
}
}
}
}
csharp
public class DataItem
{
public bool? Expanded { get; set; } //是否展开 null-代表子项,不可折叠/展开 true-展开 false-折叠(用于显示不同的图标)
public bool Checked { get; set; } //是否勾选
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool Visible { get; set; } = true;
}
UI设计:
第一列类型为DataGridViewImageColumn
第二列类型为DataGridViewCheckBoxColumn
其中 Resource.Plus、Resource.Minus、Resource.Blank为图标资源文件
效果图: