我们知道,在DataGrid给我们提供的关于行颜色的设置中只能是奇数行为一种颜色,偶数行为另外一种颜色。不能精确到具体任意一行设置颜色。比如现在DataGrid中有5个数据行,我想设计第4行颜色为红色,其他行不变。在DataGrid为我们提供的属性中就不能办到。今日遇到这样一个需求,DataGrid数据源为DataTable,当DataTable第一列的任意一行数据与下一行的数据不一样时,要换颜色突出显示。在网上找了很多资料,自己在改动,终于实现了自己的需求。现将代码贴出来。
private DataTable tableData=new DataTable();
private SqlDataAdapter dtadpter=new SqlDataAdapter();
private SqlConnection Conn=new SqlConnection(DataAccess.ConnectionString);
private void setDataGrid(string sql)//设置dataGrid,绑定数据
{
if(Conn.State==ConnectionState.Closed)
Conn.Open();
try
{
tableData.Clear();
tableData.Columns.Clear();
SqlCommand cmd=new SqlCommand(sql,Conn);
dtadpter.SelectCommand=cmd;
SqlCommandBuilder updateCb=new SqlCommandBuilder(dtadpter);
dtadpter.Fill(tableData);
dtGrid.DataSource=tableData;
cmAmend = (CurrencyManager) BindingContext[tableData];
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
AddCellFormattingColumnStyles(this.dtGrid, new FormatCellEventHandler(FormatGridCells));
}
#region DataGrid行色彩控制
private void FormatGridCells(object sender, DataGridFormatCellEventArgs e,DataTable dt)
{
//设置颜色,当DataTable第一列的任意一行数据与下一行的数据不一样时,颜色为Wheat
dt=tableData.Copy();
if(e.Row==0)
e.BackBrush=Brushes.Wheat;
for(int i=0;i<dt.Rows.Count-1;i++)
{
if(dt.Rows[i][1].Equals(dt.Rows[i+1][1])==false)
{
if(e.Row == i+1)
e.BackBrush = Brushes.Wheat;
}
continue;
}
}
private void AddCellFormattingColumnStyles(DataGrid dtGrid, FormatCellEventHandler handler)
{
DataGridTableStyle ts = new DataGridTableStyle();
ts.MappingName = tableData.TableName;//dtGrid.DataMember;
for(int j = 0; j < tableData.Columns.Count; ++j)
{
DataGridFormattableTextBoxColumn cs = new DataGridFormattableTextBoxColumn(j);
cs.MappingName = tableData.Columns[j].ColumnName;
cs.HeaderText = tableData.Columns[j].ColumnName;
cs.SetCellFormat += handler;
ts.GridColumnStyles.Add(cs);
}
dtGrid.TableStyles.Clear();
dtGrid.TableStyles.Add(ts);
if(tableData.Columns.Count>3)//非模具费
{
dtGrid.TableStyles[0].GridColumnStyles[0].Width=0;
for(int i=0;i<5;i++)
{
dtGrid.TableStyles[0].GridColumnStyles[i].ReadOnly=true;
}
dtGrid.TableStyles[0].AlternatingBackColor = System.Drawing.SystemColors.Window;
dtGrid.TableStyles[0].GridLineColor = System.Drawing.SystemColors.ActiveCaption;
dtGrid.TableStyles[0].HeaderBackColor = System.Drawing.SystemColors.Window;
dtGrid.TableStyles[0].HeaderForeColor = System.Drawing.SystemColors.ControlText;
dtGrid.TableStyles[0].SelectionForeColor = System.Drawing.SystemColors.ActiveCaptionText;
if(tableData.Columns.Count==6)
{
dtGrid.TableStyles[0].GridColumnStyles[1].Width = 106;
dtGrid.TableStyles[0].GridColumnStyles[2].Width = 106;
dtGrid.TableStyles[0].GridColumnStyles[3].Width = 106;
dtGrid.TableStyles[0].GridColumnStyles[4].Width = 106;
dtGrid.TableStyles[0].GridColumnStyles[5].Width = 112;
}
else if(tableData.Columns.Count==7)
{
dtGrid.TableStyles[0].GridColumnStyles[1].Width = 89;
dtGrid.TableStyles[0].GridColumnStyles[2].Width = 89;
dtGrid.TableStyles[0].GridColumnStyles[3].Width = 89;
dtGrid.TableStyles[0].GridColumnStyles[4].Width = 89;
dtGrid.TableStyles[0].GridColumnStyles[5].Width = 89;
dtGrid.TableStyles[0].GridColumnStyles[6].Width = 90;
}
}
else
{
dtGrid.TableStyles[0].AlternatingBackColor = System.Drawing.SystemColors.Window;
dtGrid.TableStyles[0].GridLineColor = System.Drawing.SystemColors.ActiveCaption;
dtGrid.TableStyles[0].HeaderBackColor = System.Drawing.SystemColors.Window;
dtGrid.TableStyles[0].HeaderForeColor = System.Drawing.SystemColors.ControlText;
dtGrid.TableStyles[0].SelectionForeColor = System.Drawing.SystemColors.ActiveCaptionText;
dtGrid.TableStyles[0].GridColumnStyles[1].Width = 180;
dtGrid.TableStyles[0].GridColumnStyles[2].Width = 180;
dtGrid.TableStyles[0].GridColumnStyles[0].Width = 180;
}
}
public delegate void FormatCellEventHandler(object sender, DataGridFormatCellEventArgs e,DataTable dt);
public class DataGridFormatCellEventArgs : EventArgs
{
private int _column;
private int _row;
private Font _font;
private Brush _backBrush;
private Brush _foreBrush;
private bool _useBaseClassDrawing;
public DataGridFormatCellEventArgs(int row, int col, Font font1, Brush backBrush, Brush foreBrush)
{
_row = row;
_column = col;
_font = font1;
_backBrush = backBrush;
_foreBrush = foreBrush;
_useBaseClassDrawing = false;
}
public int Column
{
get{ return _column;}
set{ _column = value;}
}
public int Row
{
get{ return _row;}
set{ _row = value;}
}
public Font TextFont
{
get{ return _font;}
set{ _font = value;}
}
public Brush BackBrush
{
get{ return _backBrush;}
set{ _backBrush = value;}
}
public Brush ForeBrush
{
get{ return _foreBrush;}
set{ _foreBrush = value;}
}
public bool UseBaseClassDrawing
{
get{ return _useBaseClassDrawing;}
set{ _useBaseClassDrawing = value;}
}
}
public class DataGridFormattableTextBoxColumn : DataGridTextBoxColumn
{
//in your handler, set the EnableValue to true or false, depending upon the row & col
public event FormatCellEventHandler SetCellFormat;
private int _col;
public DataGridFormattableTextBoxColumn(int col)
{
_col = col;
}
protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight)
{
DataGridFormatCellEventArgs e = new DataGridFormatCellEventArgs(rowNum, this._col, this.DataGridTableStyle.DataGrid.Font, backBrush, foreBrush);
System.Data.DataTable dt=new DataTable();
if(SetCellFormat != null)
{
SetCellFormat(this, e,dt);
}
if(e.UseBaseClassDrawing)
base.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight);
else
{
g.FillRectangle(e.BackBrush, bounds);
g.DrawString(this.GetColumnValueAtRow(source, rowNum).ToString(), e.TextFont, e.ForeBrush, bounds.X, bounds.Y);
}
if(e.TextFont != this.DataGridTableStyle.DataGrid.Font)
e.TextFont.Dispose();
}
protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
{
//comment to make cells unable to become editable
base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible);
}
}
#endregion