Files
KJD/TEMUKJD/Extension/DataGridViewExtension.cs

913 lines
44 KiB
C#

using AllBase;
using AllBase.Helper;
using NaiBa.Util;
using NaiBa.Util.Extension;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TemuKJD.UserComponent;
namespace TemuKJD.Extension
{
public static class DataGridViewExtension
{
public static object GetCellValueFromColumnName(this DataGridViewCellCollection CellCollection, string name)
{
return CellCollection.Cast<DataGridViewCell>().FirstOrDefault(c => c.OwningColumn.Name == name)?.Value;
}
public static UcCheckBox AddSelectorColumn(this DataGridView dgv, string columnName = "Selected", Action<DataGridViewColumn> addHeaderCheckBoxOverride = null)
{
if (dgv.Columns[columnName] == null)
{
//var dt = dgv.Table();
//var dcol = new DataColumn(columnName, typeof(bool));
//dt.Columns.Add(dcol);
//dt.ColumnChanged += (s, e) =>
//{
// var chCols = e.Row.GetChangedColumns();
// if (chCols.Count == 1 && chCols[0].Equals(dcol))
// e.Row.AcceptChanges();
//};
}
var col = dgv.Columns[columnName];
col.HeaderText = "";
col.ReadOnly = false;
if (addHeaderCheckBoxOverride != null)
{
addHeaderCheckBoxOverride(col);
return null;
}
else
{
return col.AddHeaderCheckBox();
}
}
public static UcCheckBox AddHeaderCheckBox(this DataGridViewColumn column, HorizontalAlignment align = HorizontalAlignment.Center, int leftBorderOffset = 0, int rightBorderOffset = 0, Func<object, bool> getValue = null, Action<object, bool> setValue = null, bool isSetCheckedChangedEvent = true, UcCheckBox checkBox = null, bool isClearHeaderText = false)
{
if (column?.DataGridView == null) //throw new ArgumentNullException("First you need to add the column to grid.");
MessageBox.Show("DataGridView中没有对应的CheckBox列");
// Creating checkbox without panel
if (checkBox == null)
{
checkBox = new UcCheckBox();
checkBox.Name = "chk" + column.Name;
}
checkBox.Size = new Size(13, 13);
checkBox.BackColor = Color.Transparent;
checkBox.Enabled = true;
// Reset properties
checkBox.Padding = new Padding(6, 2, 0, 0);
checkBox.Margin = new Padding(0);
checkBox.Text = "";
if (isClearHeaderText)
column.HeaderText = "";
var changedByUser = true;
var dgv = column.DataGridView;
if (isSetCheckedChangedEvent)
{
checkBox.CheckedChanged += (s, e) =>
{
if (changedByUser)
{
try
{
changedByUser = false;
if (dgv.IsCurrentCellInEditMode && dgv.CurrentCell.OwningColumn.Name.Equals(column.Name))
dgv.EndEdit();
var dgvRows = new List<DataGridViewRow>((dgv.SelectedRows.Count < 2 ? (ICollection)dgv.Rows : dgv.SelectedRows).Cast<DataGridViewRow>());
dgvRows = dgvRows.Where(r => r.Visible == true).ToList();
if (column.IsDataBound)
{
//adding to list because of BindingSource sort by that column
var boundItems = new List<object>();
var areDataRows = dgvRows.Count < 1 || dgvRows[0].DataBoundItem is DataRowView;
if (areDataRows)
{
foreach (DataGridViewRow row in dgvRows)
boundItems.Add(((DataRowView)row.DataBoundItem).Row);
foreach (DataRow dr in boundItems)
{
var val = dr[column.DataPropertyName];
if ((val is bool && (bool)val) != checkBox.Checked)
dr[column.DataPropertyName] = checkBox.Checked;
}
}
else
{
foreach (DataGridViewRow row in dgvRows)
boundItems.Add(row.DataBoundItem);
foreach (var item in boundItems)
{
var val = getValue(item);
if (val != checkBox.Checked)
setValue(item, checkBox.Checked);
}
}
}
else
{
foreach (DataGridViewRow dgr in dgvRows)
{
var cell = dgr.Cells[column.Name];
if ((cell.Value is bool && (bool)cell.Value) != checkBox.Checked)
cell.Value = checkBox.Checked;
}
}
}
finally
{
changedByUser = true;
}
}
};
}
// Add checkbox to datagrid cell
dgv.Controls.Add(checkBox);
Action onColResize = () =>
{
var colCheck = dgv.Columns[column.Name];
if (colCheck == null) return;
int colLeft = (dgv.RowHeadersVisible ? dgv.RowHeadersWidth : 0) - (colCheck.Frozen ? 0 : dgv.HorizontalScrollingOffset);
foreach (DataGridViewColumn col in dgv.Columns)
{
if (col.DisplayIndex >= colCheck.DisplayIndex) break;
if (!col.Visible) continue;
colLeft += col.Width;
}
var newPoint = new Point(colLeft, dgv.ColumnHeadersHeight / 2 - checkBox.Height / 2);
if (align == HorizontalAlignment.Left)
newPoint.X += 3;
else if (align == HorizontalAlignment.Center)
newPoint.X += colCheck.Width / 2 - checkBox.Width / 2;
else if (align == HorizontalAlignment.Right)
newPoint.X += colCheck.Width - checkBox.Width - 3;
var minLeft = colLeft + leftBorderOffset;
var maxLeft = colLeft + colCheck.Width - checkBox.Width + rightBorderOffset;
if (newPoint.X < minLeft) newPoint.X = minLeft;
if (newPoint.X > maxLeft) newPoint.X = maxLeft;
checkBox.Location = newPoint;
checkBox.Visible = colCheck.Visible;
};
dgv.ColumnWidthChanged += (s, e) => onColResize();
dgv.ColumnHeadersHeightChanged += (s, e) => onColResize();
dgv.Scroll += (s, e) => onColResize();
dgv.Resize += (s, e) => onColResize();
dgv.Sorted += (s, e) => onColResize();
dgv.RowHeadersWidthChanged += (s, e) => onColResize();
dgv.ColumnStateChanged += (s, e) => onColResize();
Action<object> onDataChanged = (e) =>
{
if (!changedByUser) return;
if (e is DataColumnChangeEventArgs)
{
if (!((DataColumnChangeEventArgs)e).Column.ColumnName.Equals(column.Name))
return;
}
else if (e is ListChangedEventArgs)
{
var prop = ((ListChangedEventArgs)e).PropertyDescriptor;
if (prop != null && !prop.Name.Equals(column.DataPropertyName))
return;
}
bool allAreTrue = true;
foreach (DataGridViewRow row in dgv.SelectedRows.Count < 2 ? (ICollection)dgv.Rows : dgv.SelectedRows)
{
var val = row.Cells[column.Name].Value;
if (!(val is bool) || !(bool)val)
{
allAreTrue = false;
break;
}
}
try
{
changedByUser = false;
var tag = checkBox.Tag;
checkBox.Tag = "AUTO";
try
{
if (isSetCheckedChangedEvent)
{
checkBox.Checked = allAreTrue;
}
}
finally { checkBox.Tag = tag; }
}
finally
{
changedByUser = true;
}
};
dgv.CellClick += (s, e) => onDataChanged(e);
dgv.CellContentClick += (s, e) => onDataChanged(e);
dgv.SelectionChanged += (s, e) => onDataChanged(e);
if (dgv.DataSource is BindingSource)
((BindingSource)dgv.DataSource).ListChanged += (s, e) => onDataChanged(e);
else if (dgv.DataSource is DataSet)
((DataSet)dgv.DataSource).Tables[dgv.DataMember].ColumnChanged += (s, e) => onDataChanged(e);
else if (dgv.DataSource is DataTable)
((DataTable)dgv.DataSource).ColumnChanged += (s, e) => onDataChanged(e);
onColResize();
return checkBox;
}
/// <summary>
/// 绘制合并的表头单元格
/// </summary>
/// <param name="dgv"></param>
/// <param name="colNameCollection">单元格名称</param>
/// <param name="headerText">合并后的表头显示文字</param>
/// <param name="isEnableResizing">是否允许调整大小</param>
public static void AddMergeColumnHeader(this DataGridView dgv, List<string> colNameCollection, string headerText, bool isMultiLevelHeader = false)
{
int nHeight = 0;
int nLeft = 0;
int nTop = 0;
int nWidth = 0;
bool isMultiLevel = isMultiLevelHeader; // 是否为二级复合表头
bool isResize = false; // 是否已调整过表头
//合并列中某一列的列宽变化时,强制重绘表头
dgv.ColumnWidthChanged += (s, e) =>
{
if (colNameCollection.Contains(e.Column.Name))
{
foreach (var columnName in colNameCollection)
{
if (dgv.Columns.Contains(columnName))
dgv.InvalidateCell(dgv.Columns[columnName].HeaderCell); // 标记单元格为需要重绘
}
dgv.Update();
}
};
dgv.Scroll += (s, e) =>
{
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
{
bool tag = false;
foreach (var columnName in colNameCollection)
{
var bounds = dgv.Columns[columnName].HeaderCell.ContentBounds;
if (bounds.Left < 10 || bounds.Right > dgv.Width - 10)
{
tag = true;
break;
}
}
if (tag == true)
{
foreach (var columnName in colNameCollection)
{
if (dgv.Columns.Contains(columnName))
dgv.InvalidateCell(dgv.Columns[columnName].HeaderCell); // 标记单元格为需要重绘
}
dgv.Update();
}
}
};
//处理重绘事件,绘制合并表头和二级表头
dgv.CellPainting += (s, e) =>
{
if (e.RowIndex == -1 && e.ColumnIndex >= 0) // 重绘表头单元格及标题
{
string name = dgv.Columns[e.ColumnIndex].Name;
// 调整为复合表头
if (isMultiLevel && !isResize)
{
dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
dgv.ColumnHeadersHeight = e.CellBounds.Height * 2;
isResize = true;
}
if (colNameCollection.Contains(name))
{
e.PaintBackground(e.CellBounds, false); // false不绘制单元格背景
//e.PaintContent(e.CellBounds); // 绘制单元格内容,此处不要绘制
Brush brush;
Pen pen;
if (colNameCollection.IndexOf(name) == 0)
{
nTop = e.CellBounds.Top;
nLeft = e.CellBounds.Left;
nWidth = e.CellBounds.Width;
if (isMultiLevelHeader)
nHeight = e.CellBounds.Height / 2;
else
nHeight = e.CellBounds.Height;
foreach (string str2 in colNameCollection)
{
if (!str2.Equals(name))
{
nWidth += dgv.Columns[str2].Width;
}
}
}
//填充表头背景(覆盖原来的分隔线)
Rectangle rtTmp = new Rectangle(nLeft, nTop, nWidth, nHeight);
using (brush = new SolidBrush(/*e.CellStyle.BackColor*/dgv.BackgroundColor))
{
var rtBounds = e.CellBounds;
rtBounds.Height -= 1;
e.Graphics.FillRectangle(brush, rtBounds);
}
//非多级表头,只需绘制最后一个连续表头的垂直分隔线
if (!isMultiLevelHeader)
{
if (colNameCollection.IndexOf(name) == colNameCollection.Count - 1)
{
// 分隔线
using (pen = new Pen(Color.FromArgb(229, 229, 229)))
{
var rtBounds = e.CellBounds;
e.Graphics.DrawLine(pen, rtBounds.Right - 1, rtBounds.Top + 1, rtBounds.Right - 1, rtBounds.Bottom - 2);
}
}
}
else
{
//分割多级表头
using (pen = new Pen(/*dgv.GridColor*/Color.FromArgb(229, 229, 229)))
{
//水平分隔线
e.Graphics.DrawLine(pen, nLeft, nHeight, nLeft + nWidth, nHeight);
//垂直分隔线
var rtBounds = e.CellBounds;
if (colNameCollection.IndexOf(name) == colNameCollection.Count - 1)
e.Graphics.DrawLine(pen, rtBounds.Right - 1, rtBounds.Top + 1, rtBounds.Right - 1, rtBounds.Bottom - 2);
else
e.Graphics.DrawLine(pen, rtBounds.Right - 1, nHeight, rtBounds.Right - 1, rtBounds.Bottom - 2);
}
//绘制二级表头文字
using (brush = new SolidBrush(e.CellStyle.ForeColor))
{
SizeF textSize = TextRenderer.MeasureText(dgv.Columns[e.ColumnIndex].HeaderText, e.CellStyle.Font);
int nSubTop = nTop + nHeight;
int nSubLeft = e.CellBounds.Left;
int nSubWidth = e.CellBounds.Width;
int nSubHeight = nHeight;
PointF point = new PointF(nSubLeft + 6, nSubTop + (nSubHeight - textSize.Height) / 2);
if (e.CellStyle.Alignment.ToString().Contains("Center"))
point.X = nSubLeft + (nSubWidth - textSize.Width) / 2;
else if (e.CellStyle.Alignment.ToString().Contains("Right"))
point.X = nSubLeft + nSubWidth - textSize.Width - 6;
if (e.CellStyle.Alignment.ToString().Contains("Top"))
point.Y = nSubTop + 4;
else if (e.CellStyle.Alignment.ToString().Contains("Bottom"))
point.Y = nSubTop + nSubHeight - textSize.Height - 4;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
e.Graphics.DrawString(dgv.Columns[e.ColumnIndex].HeaderText, e.CellStyle.Font, brush, point);
}
}
//绘制合并表头名称,只在最后绘制一次
if (colNameCollection.IndexOf(name) == colNameCollection.Count - 1)
{
using (brush = new SolidBrush(e.CellStyle.ForeColor))
{
SizeF textSize = TextRenderer.MeasureText(headerText, e.CellStyle.Font);
//单元列移出可见范围后将不再移动,需要强制改变绘制文字的位置
if (nLeft < 0)
nLeft = e.CellBounds.Right - nWidth;
PointF point = new PointF(nLeft + 6, nTop + (nHeight - textSize.Height) / 2);
if (e.CellStyle.Alignment.ToString().Contains("Center") || isMultiLevel)
point.X = nLeft + (nWidth - textSize.Width) / 2;
else if (e.CellStyle.Alignment.ToString().Contains("Right"))
point.X = nLeft + nWidth - textSize.Width - 6;
if (e.CellStyle.Alignment.ToString().Contains("Top"))
point.Y = nTop + 4;
else if (e.CellStyle.Alignment.ToString().Contains("Bottom"))
point.Y = nTop + nHeight - textSize.Height - 4;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
e.Graphics.DrawString(headerText, e.CellStyle.Font, brush, point);
}
}
//e.set_Handled(true);
e.Handled = true; // 告知系统不再处理表头单元格绘制事件
}
}
};
}
public static void AddMergeColumn(this DataGridView dgv, List<string> colNameCollection, Color? VerGridColor = null, Color? VerGridSelectColor = null)
{
int nHeight = 0;
int nLeft = 0;
int nTop = 0;
int nWidth = 0;
//合并列中某一列的列宽变化时,强制重绘表头
dgv.ColumnWidthChanged += (s, e) =>
{
if (colNameCollection.Contains(e.Column.Name))
{
foreach (var columnName in colNameCollection)
{
if (dgv.Columns.Contains(columnName))
dgv.InvalidateCell(dgv.Columns[columnName].HeaderCell); // 标记单元格为需要重绘
}
dgv.Update();
}
};
dgv.Scroll += (s, e) =>
{
if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
{
bool tag = false;
foreach (var columnName in colNameCollection)
{
var bounds = dgv.Columns[columnName].HeaderCell.ContentBounds;
if (bounds.Left < 10 || bounds.Right > dgv.Width - 10)
{
tag = true;
break;
}
}
if (tag == true)
{
foreach (var columnName in colNameCollection)
{
if (dgv.Columns.Contains(columnName))
dgv.InvalidateCell(dgv.Columns[columnName].HeaderCell); // 标记单元格为需要重绘
}
dgv.Update();
}
}
};
//处理重绘事件
dgv.CellPainting += (s, e) =>
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0) // 重绘单元格
{
string name = dgv.Columns[e.ColumnIndex].Name;
if (colNameCollection.Contains(name))
{
e.PaintBackground(e.CellBounds, true); // false不绘制单元格背景
e.PaintContent(e.CellBounds); // 绘制单元格内容,此处要绘制内容
Brush brush;
Pen pen;
if (colNameCollection.IndexOf(name) == 0)
{
nTop = e.CellBounds.Top;
nLeft = e.CellBounds.Left;
nWidth = e.CellBounds.Width;
nHeight = e.CellBounds.Height;
foreach (string str2 in colNameCollection)
{
if (!str2.Equals(name))
{
nWidth += dgv.Columns[str2].Width;
}
}
}
//填充背景(覆盖原来的分隔线)
//Rectangle rtTmp = new Rectangle(nLeft, nTop, nWidth, nHeight);
//using (brush = new SolidBrush(/*e.CellStyle.BackColor*/dgv.BackgroundColor))
//{
// var rtBounds = e.CellBounds;
// rtBounds.Height -= 1;
// e.Graphics.FillRectangle(brush, rtBounds);
//}
if (colNameCollection.IndexOf(name) < colNameCollection.Count - 1)
{
var penColor = VerGridColor;
// 分隔线
if (penColor == null)
{
//VerGridColor = Color.FromArgb(229, 229, 229);
penColor = e.RowIndex % 2 == 0 ? dgv.DefaultCellStyle.BackColor : dgv.AlternatingRowsDefaultCellStyle.BackColor;
}
var penSelectColor = VerGridSelectColor;
if (penSelectColor == null)
//VerGridColorSelect = Color.FromArgb(129, 129, 129);
penSelectColor = dgv.DefaultCellStyle.SelectionBackColor;
if ((dgv.Rows[e.RowIndex].Cells[e.ColumnIndex]).Selected)
{
using (pen = new Pen(penSelectColor.Value))
{
var rtBounds = e.CellBounds;
e.Graphics.DrawLine(pen, rtBounds.Right - 1, rtBounds.Top, rtBounds.Right - 1, rtBounds.Bottom - 2);
}
}
else
{
using (pen = new Pen(penColor.Value))
{
var rtBounds = e.CellBounds;
e.Graphics.DrawLine(pen, rtBounds.Right - 1, rtBounds.Top, rtBounds.Right - 1, rtBounds.Bottom - 2);
}
}
}
//e.set_Handled(true);
e.Handled = true; // 告知系统不再处理表头单元格绘制事件
}
}
};
}
public static void AddVerticalMergeCell(this DataGridView dgv, ConcurrentList<DataGridViewCell> cellLst, bool drawRightBorder = true, Color? VerGridColor = null, Color? VerGridSelectColor = null)
{
int nHeight = 0;
int nLeft = 0;
int nTop = 0;
int nWidth = 0;
dgv.RowHeightChanged += (s, e) =>
{
bool has = false;
foreach (var cell in cellLst)
{
if (cell.RowIndex == e.Row.Index)
{
dgv.InvalidateCell(cell);
has = true;
}
}
if (has)
dgv.Update();
};
//合并列中某一列的列宽变化时,强制重绘
dgv.ColumnWidthChanged += (s, e) =>
{
bool has = false;
foreach (var cell in cellLst)
{
if (cell.ColumnIndex == e.Column.Index)
{
dgv.InvalidateCell(cell);
has = true;
}
}
if (has)
dgv.Update();
};
dgv.SelectionChanged += (s, e) =>
{
bool has = false;
foreach (var cell in cellLst)
{
if (cell.Displayed)
{
dgv.InvalidateCell(cell);
has = true;
}
}
if (has)
dgv.Update();
};
dgv.Scroll += (s, e) =>
{
bool has = false;
foreach (DataGridViewCell cell in cellLst)
{
if (cell.Displayed)
{
dgv.InvalidateCell(cell);
has = true;
}
}
if (has)
dgv.Update();
};
//处理重绘事件
dgv.CellPainting += (s, e) =>
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0) // 重绘单元格
{
foreach (DataGridViewCell cell in cellLst)
{
if (cell.RowIndex == e.RowIndex && cell.ColumnIndex == e.ColumnIndex)
{
nTop = e.CellBounds.Top;
nLeft = e.CellBounds.Left;
nWidth = e.CellBounds.Width;
nHeight = 0;
foreach (DataGridViewCell c in cellLst)
{
nHeight += dgv.Rows[c.RowIndex].Height;
}
for (int i = 0; i < cellLst.IndexOf(cell); i++)
{
nTop -= dgv.Rows[cellLst[i].RowIndex].Height;
}
var rect = new Rectangle(nLeft, nTop, nWidth - 1, nHeight - 1);
if (!drawRightBorder)
rect = new Rectangle(nLeft, nTop, nWidth, nHeight - 1);
e.PaintBackground(e.CellBounds, true); // false不绘制单元格背景
//e.PaintContent(e.CellBounds); // 绘制单元格内容,此处根据需要决定是否绘制内容
Brush brush;
Pen pen;
//if (cellLst.IndexOf(cell) < cellLst.Count - 1)
{
var color = VerGridColor;
// 分隔线
if (color == null)
{
//VerGridColor = Color.FromArgb(229, 229, 229);
color = e.RowIndex % 2 == 0 ? dgv.DefaultCellStyle.BackColor : dgv.AlternatingRowsDefaultCellStyle.BackColor;
color = e.CellStyle.BackColor;
}
var selectColor = VerGridSelectColor;
if (selectColor == null)
//VerGridColorSelect = Color.FromArgb(129, 129, 129);
selectColor = dgv.DefaultCellStyle.SelectionBackColor;
//if ((dgv.Rows[e.RowIndex].Cells[e.ColumnIndex]).Selected)
if (cellLst.Any(c => c.Selected))
{
//using (pen = new Pen(selectColor.Value))
//{
// var rtBounds = e.CellBounds;
// //e.Graphics.DrawLine(pen, rtBounds.Right - 1, rtBounds.Top, rtBounds.Right - 1, rtBounds.Bottom - 2); // 右竖线
// e.Graphics.DrawLine(pen, rtBounds.Left, rtBounds.Bottom - 1, rtBounds.Right - 2, rtBounds.Bottom - 1); // 下横线
//}
using (brush = new SolidBrush(selectColor.Value))
{
e.Graphics.FillRectangle(brush, rect);
}
}
else
{
//using (pen = new Pen(color.Value))
//{
// var rtBounds = e.CellBounds;
// //e.Graphics.DrawLine(pen, rtBounds.Right - 1, rtBounds.Top, rtBounds.Right - 1, rtBounds.Bottom - 2); // 右竖线
// e.Graphics.DrawLine(pen, rtBounds.Left, rtBounds.Bottom - 1, rtBounds.Right - 2, rtBounds.Bottom - 1); // 下横线
//}
using (brush = new SolidBrush(color.Value))
{
e.Graphics.FillRectangle(brush, rect);
}
}
}
//if (cellLst.IndexOf(cell) == cellLst.Count - 1)
if (cell is DataGridViewImageCell == false)
{
var color = e.CellStyle.ForeColor;
if (cellLst.Any(c => c.Selected))
{
color = e.CellStyle.SelectionForeColor;
}
using (brush = new SolidBrush(color))
{
//StringFormat stringFormat = new StringFormat();
//stringFormat.Alignment = StringAlignment.Near;
//stringFormat.LineAlignment = StringAlignment.Near;
//stringFormat.FormatFlags = StringFormatFlags.MeasureTrailingSpaces; // 确保尾部空格被计算在内
//stringFormat.Trimming = StringTrimming.Character; // 处理超出宽度的字符
//stringFormat.SetMeasurableCharacterRanges(new CharacterRange[] { new CharacterRange(0, cell.Value.ParseToString().Length) }); // 设置测量范围
SizeF textSize = TextRenderer.MeasureText(cell.Value.ParseToString(), e.CellStyle.Font, new Size(nWidth - 10, nHeight), TextFormatFlags.WordBreak);
//单元列移出可见范围后将不再移动,需要强制改变绘制文字的位置
if (nLeft < 0)
nLeft = e.CellBounds.Right - nWidth;
PointF point = new PointF(nLeft + 1, nTop + (nHeight - textSize.Height) / 2);
if (e.CellStyle.Alignment.ToString().Contains("Center"))
point.X = nLeft + (nWidth - textSize.Width) / 2;
else if (e.CellStyle.Alignment.ToString().Contains("Right"))
point.X = nLeft + nWidth - textSize.Width - 1;
if (e.CellStyle.Alignment.ToString().Contains("Top"))
point.Y = nTop + 4;
else if (e.CellStyle.Alignment.ToString().Contains("Bottom"))
point.Y = nTop + nHeight - textSize.Height - 4;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
RectangleF rectF = new RectangleF(point.X, point.Y, nWidth - 10, nHeight - 10);
//e.Graphics.DrawString(cell.Value.ParseToString(), e.CellStyle.Font, brush, point);
e.Graphics.DrawString(cell.Value.ParseToString(), e.CellStyle.Font, brush, rectF);
}
}
else
{
var img = cell.Value as Image;
PointF point = new PointF(nLeft, nTop + (nHeight - img.Height) / 2);
if (e.CellStyle.Alignment.ToString().Contains("Center"))
point.X = nLeft + (nWidth - img.Width) / 2;
else if (e.CellStyle.Alignment.ToString().Contains("Right"))
point.X = nLeft + nWidth - img.Width - 1;
if (e.CellStyle.Alignment.ToString().Contains("Top"))
point.Y = nTop + 4;
else if (e.CellStyle.Alignment.ToString().Contains("Bottom"))
point.Y = nTop + nHeight - img.Height;
e.Graphics.DrawImage(img, point);
//RectangleF rectF = new RectangleF(point.X, point.Y, nWidth - 10, nHeight - 10);
//e.Graphics.DrawString(cell.Value.ParseToString(), e.CellStyle.Font, brush, point);
//e.Graphics.DrawString(cell.Value.ParseToString(), e.CellStyle.Font, brush, rectF);
}
e.Handled = true; // 告知系统不再处理单元格绘制事件
}
}
}
};
}
public static void AddImgColumn(this DataGridView dgv, string imgColumn, string imgPathColumn, bool isSetHttpsHttp = true)
{
//bool isScroll = false;
CancellationTokenSource cancelToken = new CancellationTokenSource();
dgv.Scroll += (s, e) =>
{
cancelToken.Cancel();
cancelToken = new CancellationTokenSource();
Task.Run(() =>
{
//while (isScroll && 1 == 1)
// Thread.Sleep(1);
//isScroll = true;
ShowDgvImg(cancelToken, dgv, dgv.Rows.Cast<DataGridViewRow>().ToList(), imgColumn, imgPathColumn, isSetHttpsHttp);
//isScroll = false;
}, cancelToken.Token);
};
//dgv.Resize += (s, e) =>
//{
// ShowDgvImg(dgv, null, imgColumn, imgPathColumn, isSetHttpsHttp);
//};
dgv.Sorted += (s, e) =>
{
cancelToken.Cancel();
cancelToken = new CancellationTokenSource();
Task.Run(() =>
{
//while (isScroll && 1 == 1)
// Thread.Sleep(1);
//isScroll = true;
ShowDgvImg(cancelToken, dgv, dgv.Rows.Cast<DataGridViewRow>().ToList(), imgColumn, imgPathColumn, isSetHttpsHttp);
//isScroll = false;
}, cancelToken.Token);
};
//dgv.RowsRemoved += (s, e) =>
//{
// ShowDgvImg(dgv, null, imgColumn, imgPathColumn, isSetHttpsHttp);
//};
dgv.RowsAdded += (s, e) =>
{
cancelToken.Cancel();
cancelToken = new CancellationTokenSource();
Task.Run(() =>
{
//while (isScroll && 1 == 1)
// Thread.Sleep(1);
//isScroll = true;
if (e.RowIndex < (dgv.FirstDisplayedScrollingRowIndex + dgv.DisplayedRowCount(true)))
ShowDgvImg(cancelToken, dgv, dgv.Rows.Cast<DataGridViewRow>().ToList(), imgColumn, imgPathColumn, isSetHttpsHttp);
else
ShowDgvImg(cancelToken, dgv, new List<DataGridViewRow> { dgv.Rows[e.RowIndex] }, imgColumn, imgPathColumn, isSetHttpsHttp);
//isScroll = false;
}, cancelToken.Token);
};
dgv.RowPostPaint += (s, e) =>
{
//if (e.RowIndex >= 0 && e.RowIndex < 25)
//{
// Task.Run(() =>
// {
// while (isScroll && 1 == 1)
// Thread.Sleep(1);
// isScroll = true;
// try
// {
// if (dgv.Rows.Count > e.RowIndex)
// ShowDgvImg(dgv, new List<DataGridViewRow> { dgv.Rows[e.RowIndex] }, imgColumn, imgPathColumn, isSetHttpsHttp);
// }
// catch
// {
// }
// isScroll = false;
// });
//}
};
dgv.CellValueChanged += (s, e) =>
{
if (dgv.Columns[e.ColumnIndex].Name == imgPathColumn)
{
var row = dgv.Rows[e.RowIndex];
if (row.Cells[imgColumn].Value != null && row.Cells[imgColumn].Value != defaultBitmap)
{
row.Cells[imgColumn].Value = defaultBitmap;
cancelToken.Cancel();
cancelToken = new CancellationTokenSource();
Task.Run(() =>
{
//while (isScroll && 1 == 1)
// Thread.Sleep(1);
//isScroll = true;
ShowDgvImg(cancelToken, dgv, new List<DataGridViewRow> { row }, imgColumn, imgPathColumn, isSetHttpsHttp);
//isScroll = false;
});
}
}
};
}
public static Bitmap defaultBitmap = new Bitmap(1, 1);
static void ShowDgvImg(CancellationTokenSource cancelToken, DataGridView dgv, List<DataGridViewRow> rowLst, string imgColumn, string imgPathColumn, bool isSetHttpsHttp = true)
{
if (rowLst == null)
{
rowLst = new List<DataGridViewRow>();
rowLst.AddRange(dgv.Rows.Cast<DataGridViewRow>());
}
foreach (DataGridViewRow row in rowLst)
{
if (cancelToken.IsCancellationRequested)
break;
//if (row.Index <= 1)
// continue;
if (row.Displayed == false && row.Index > 0) // 不设置大于0 第一行始终不显示图片
{
dgv.Invoke(new Action(() =>
{
try
{
if (row.Index >= 0 && row.Cells[imgColumn]?.Value != defaultBitmap)
row.Cells[imgColumn].Value = defaultBitmap;
}
catch
{
}
}));
continue;
}
else
{
try
{
if (row.Cells[imgColumn]?.Value == defaultBitmap || row.Cells[imgColumn]?.Value == null)
{
Image image = defaultBitmap;
string imgUrl = row.Cells[imgPathColumn]?.Value.ParseToString();
if (!string.IsNullOrWhiteSpace(imgUrl))
{
if (isSetHttpsHttp == true)
imgUrl = imgUrl.Replace("https://", "http://");
string getImgError = "";
image = GetHtml.GetUrlImg(imgUrl, out getImgError);
if (!string.IsNullOrEmpty(getImgError))
//BaseMsgForm.ShowError("图片加载失败 " + getImgError);
image = TemuKJD.Properties.Resources.errpic;
}
dgv.Invoke(new Action(() =>
{
try
{
if (row.Index >= 0)
{
row.Cells[imgColumn].Value = image;
}
}
catch
{
}
}));
}
}
catch (Exception ex)
{
}
}
}
}
}
}