DataGridView 能否用于在 WinForms 中完成以下类似 table 的 UI?
Can DataGridView be used to accomplish the following table-like UI in WinForms?
这一直很痛苦,但我一直在使用 TableLayoutPanel
来显示一些数据,如下面的屏幕截图所示。但是有好几次有人建议用 DataGridView
.
可以 轻松完成
所以我的问题是,可以使用 DataGridView
在 Windows 表单中完成以下屏幕截图吗?我在网上搜索过,但没有与以下内容类似的内容。
答案是 "Yes, it can." 或 "No, it's not possible."。但是请不要 post 替代方案,因为问题的目的是最终知道是否可以 DataGridView
.
完成这样的事情
DataTable
如下所示:
BG_Color EmpId ColNum RowNum
Yellow 4304 1 1
Yellow 8464 2 1
Yellow 2012 3 1
Blue 4593 1 2
Blue 3515 2 2
Blue 0546 3 2
Green 4346 1 3
Green 5426 2 3
Green 0551 3 3
结果如下。它仅供显示,此处不可点击:
DataGridView
这怎么可能?我什至在 RowNum
和 ColNum
中包括了每个单元格的确切位置,以备不时之需。
或者如果有人可以分享 link 类似的东西,我们将不胜感激。
谢谢。
是的,您可以使用 DataGridView
:
创建这样的用户界面
- 您可以手动设置网格的
RowCount
和 ColumnCount
。
- 您可以处理
DataGridView
的 CellFormatting
事件并在那里设置单元格的值和背景色。
- 您不能对当前数据结构使用数据绑定。
这是一个使用您的示例数据的工作示例:
DataTable table;
private void Form1_Load(object sender, EventArgs e)
{
table = GetData();
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.ColumnHeadersVisible = false;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
this.dataGridView1.RowTemplate.Height = 64;
this.dataGridView1.CellFormatting += dataGridView1_CellFormatting;
this.dataGridView1.ColumnCount = (int)table.Compute("Max(ColNum)", "");
this.dataGridView1.RowCount = (int)table.Compute("Max(RowNum)", "");
}
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex >= 0 & e.ColumnIndex >= 0)
{
var row = table.Select(string.Format("RowNum={0} AND ColNum={1}",
e.RowIndex + 1, e.ColumnIndex + 1)).FirstOrDefault();
if (row != null)
{
e.Value = row["EmpId"];
var color = (Color)new ColorConverter().ConvertFrom(row["BG_Color"]);
e.CellStyle.BackColor = color;
e.CellStyle.SelectionBackColor = color;
e.CellStyle.SelectionForeColor = Color.Black;
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
}
}
正如我在问题的评论中提到的那样,实现这一点很容易,但只有一个条件:存储在数据表中的数据必须进行透视。如何?看例子:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//create DataTable
DataTable dt = CreateCustomDataTable();
var pivotDt = dt.AsEnumerable()
.GroupBy(x => x.Field<int>("RowNum"))
.Select(grp => new
{
BG_Color = grp.First().Field<string>("BG_Color").ToLower(), //System.Drawing.Color.FromName(grp.First().Field<string>("BG_Color")),
Emp1 = grp.Where(e => e.Field<int>("ColNum") == 1).Select(a => a.Field<int>("EmpId")).SingleOrDefault(),
Emp2 = grp.Where(e => e.Field<int>("ColNum") == 2).Select(a => a.Field<int>("EmpId")).SingleOrDefault(),
Emp3 = grp.Where(e => e.Field<int>("ColNum") == 3).Select(a => a.Field<int>("EmpId")).SingleOrDefault()
}).ToList();
dataGridView1.DataSource = pivotDt;
dataGridView1.Columns[0].Visible = false;
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
e.CellStyle.BackColor = Color.FromName(dgv.Rows[e.RowIndex].Cells[0].Value.ToString());
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
e.CellStyle.SelectionBackColor = Color.Transparent;
}
//...
}
结果:
对于这样的数据量,性能损失的风险等于零。
关于您的主要问题的最后说明:
(...) can the following screenshot be accomplished in a Windows Form using a datagridview?
An answer would be Yes, it can or No, it's not possible. (...)
是的。这是可能的 - 很容易。
这一直很痛苦,但我一直在使用 TableLayoutPanel
来显示一些数据,如下面的屏幕截图所示。但是有好几次有人建议用 DataGridView
.
所以我的问题是,可以使用 DataGridView
在 Windows 表单中完成以下屏幕截图吗?我在网上搜索过,但没有与以下内容类似的内容。
答案是 "Yes, it can." 或 "No, it's not possible."。但是请不要 post 替代方案,因为问题的目的是最终知道是否可以 DataGridView
.
DataTable
如下所示:
BG_Color EmpId ColNum RowNum
Yellow 4304 1 1
Yellow 8464 2 1
Yellow 2012 3 1
Blue 4593 1 2
Blue 3515 2 2
Blue 0546 3 2
Green 4346 1 3
Green 5426 2 3
Green 0551 3 3
结果如下。它仅供显示,此处不可点击:
DataGridView
这怎么可能?我什至在 RowNum
和 ColNum
中包括了每个单元格的确切位置,以备不时之需。
或者如果有人可以分享 link 类似的东西,我们将不胜感激。
谢谢。
是的,您可以使用 DataGridView
:
- 您可以手动设置网格的
RowCount
和ColumnCount
。 - 您可以处理
DataGridView
的CellFormatting
事件并在那里设置单元格的值和背景色。 - 您不能对当前数据结构使用数据绑定。
这是一个使用您的示例数据的工作示例:
DataTable table;
private void Form1_Load(object sender, EventArgs e)
{
table = GetData();
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.AllowUserToDeleteRows = false;
this.dataGridView1.ReadOnly = true;
this.dataGridView1.RowHeadersVisible = false;
this.dataGridView1.ColumnHeadersVisible = false;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
this.dataGridView1.RowTemplate.Height = 64;
this.dataGridView1.CellFormatting += dataGridView1_CellFormatting;
this.dataGridView1.ColumnCount = (int)table.Compute("Max(ColNum)", "");
this.dataGridView1.RowCount = (int)table.Compute("Max(RowNum)", "");
}
void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.RowIndex >= 0 & e.ColumnIndex >= 0)
{
var row = table.Select(string.Format("RowNum={0} AND ColNum={1}",
e.RowIndex + 1, e.ColumnIndex + 1)).FirstOrDefault();
if (row != null)
{
e.Value = row["EmpId"];
var color = (Color)new ColorConverter().ConvertFrom(row["BG_Color"]);
e.CellStyle.BackColor = color;
e.CellStyle.SelectionBackColor = color;
e.CellStyle.SelectionForeColor = Color.Black;
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
}
}
正如我在问题的评论中提到的那样,实现这一点很容易,但只有一个条件:存储在数据表中的数据必须进行透视。如何?看例子:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//create DataTable
DataTable dt = CreateCustomDataTable();
var pivotDt = dt.AsEnumerable()
.GroupBy(x => x.Field<int>("RowNum"))
.Select(grp => new
{
BG_Color = grp.First().Field<string>("BG_Color").ToLower(), //System.Drawing.Color.FromName(grp.First().Field<string>("BG_Color")),
Emp1 = grp.Where(e => e.Field<int>("ColNum") == 1).Select(a => a.Field<int>("EmpId")).SingleOrDefault(),
Emp2 = grp.Where(e => e.Field<int>("ColNum") == 2).Select(a => a.Field<int>("EmpId")).SingleOrDefault(),
Emp3 = grp.Where(e => e.Field<int>("ColNum") == 3).Select(a => a.Field<int>("EmpId")).SingleOrDefault()
}).ToList();
dataGridView1.DataSource = pivotDt;
dataGridView1.Columns[0].Visible = false;
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
e.CellStyle.BackColor = Color.FromName(dgv.Rows[e.RowIndex].Cells[0].Value.ToString());
e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
e.CellStyle.SelectionBackColor = Color.Transparent;
}
//...
}
结果:
对于这样的数据量,性能损失的风险等于零。
关于您的主要问题的最后说明:
(...) can the following screenshot be accomplished in a Windows Form using a datagridview?
An answer would be Yes, it can or No, it's not possible. (...)
是的。这是可能的 - 很容易。