所以,我有一个DataGridView,在这个表中有文本,最后一列是显示百分比的Progess Bar。我已经实现了DataGridViewProgressCell的修改版本,我找到了(如果我没记错的话)MSDN。此实现的源代码如下所示。
public class DataGridViewProgressColumn : DataGridViewImageColumn
{
public DataGridViewProgressColumn()
{
CellTemplate = new DataGridViewProgressCell();
}
}
public class DataGridViewProgressCell : DataGridViewImageCell
{
// Used to make custom cell consistent with a DataGridViewImageCell
static Image emptyImage;
static DataGridViewProgressCell()
{
emptyImage = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
}
public DataGridViewProgressCell()
{
this.ValueType = typeof(int);
}
protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
{
return emptyImage;
}
protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
double progressVal = 0.0;
if (value != null)
progressVal = Convert.ToDouble(this.Value);
float percentage = ((float)progressVal / 100.0f); // Need to convert to float before division; otherwise C# returns int which is 0 for anything but 100%.
Brush backColorBrush = new SolidBrush(cellStyle.BackColor);
Brush foreColorBrush = new SolidBrush(cellStyle.ForeColor);
// Draws the cell grid
base.Paint(g, clipBounds, cellBounds,
rowIndex, cellState, value, formattedValue, errorText,
cellStyle, advancedBorderStyle, (paintParts & ~DataGridViewPaintParts.ContentForeground));
if (percentage > 0.0)
{
// Draw the progress bar and the text
g.FillRectangle(new SolidBrush(Color.FromArgb(163, 189, 242)), cellBounds.X + 2, cellBounds.Y + 2, Convert.ToInt32((percentage * cellBounds.Width - 4)), cellBounds.Height - 4);
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + 6, cellBounds.Y + 2);
}
else
{
// draw the text
if (this.DataGridView.CurrentRow.Index == rowIndex)
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, new SolidBrush(cellStyle.SelectionForeColor), cellBounds.X + 6, cellBounds.Y + 2);
else
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + 6, cellBounds.Y + 2);
}
}
}
它在我的DataGridView中创建了一个漂亮的小进度条。只有一个问题......我无法弄清楚如何根据值的范围更改进度条的颜色,并且此值可能会根据生成的报告类型而更改DataGridView。例如,在一份报告中,如果百分比低于50%,则需要为红色,50-80%,黄色和80%以上,绿色,但在不同的报告中,阈值可能为40%和70%。我无法弄清楚如何将这些值传递给DataGridViewProgressCell。我的实现如下。谢谢你的帮助!
private void fillData()
{
dataGridView1.Columns.Clear(); dataGridView1.Rows.Clear();
dataGridView1.Columns.Add("Header1", "Header1");
dataGridView1.Columns.Add("Header2", "Header2");
dataGridView1.Columns.Add("Header3", "Header3");
dataGridView1.Columns.Add("Header4", "Header4");
dataGridView1.Columns.Add(new DataGridViewProgressColumn());
try
{
//jsonManager is a simple WebClient. Nothing fancy
//The data is in a JSON format, first part of code handles getting the values needed for the table.
JavaScriptSerializer js = new JavaScriptSerializer();
string getData = serverURL + "/data";
string htmlGET = jsonManager.DownloadString(getData);
object[] myVals = (object[])js.DeserializeObject(htmlGET);
Dictionary<string, object> overall = (Dictionary<string, object>)myVals[0];
for (int i = 0; i < myVals .Length; i++)
{
Dictionary<string, object> entry = (Dictionary<string, object>)myVals [i];
string fooHeader = "";
double percent = Convert.ToDouble(entry["percent"]);
int acceptable = (int)entry["acceptable"];
int total_foo = (int)entry["total_welds"];
if (i == 0)
sch = "OverallFoo";
else
sch = ((int)entry["fooHeader"]).ToString();
dataGridView1.Rows.Add(new object[] { sch, percent, acceptable, total_welds, percent });
}
}
catch(Exception e)
{
//Handle exception(s)
}
finally
{
//More steps, including log writing.
}
}
答案 0 :(得分:0)
如果我正确理解了您的问题,那么我们只需要一个位置来存储确定进度条颜色的百分比。然后在Paint()方法中使用它。这就是我要做的事情:
我在ProgressColumn中添加了两个属性:
public class DataGridViewProgressColumn : DataGridViewImageColumn
{
public float RedUntil { get; set; }
public float YellowUntil { get; set; }
public DataGridViewProgressColumn()
{
CellTemplate = new DataGridViewProgressCell();
}
}
然后我更改了您的单元格绘图代码:
var progressColumn = this.DataGridView.Columns[this.ColumnIndex] as DataGridViewProgressColumn;
if (percentage > 0.0 && progressColumn != null)
{
// Draw the progress bar and the text
Brush fillColor;
if (percentage < progressColumn.RedUntil)
{
fillColor = new SolidBrush(Color.Red);
}
else if (percentage < progressColumn.YellowUntil)
{
fillColor = new SolidBrush(Color.Yellow);
}
else
{
fillColor = new SolidBrush(Color.Green);
}
g.FillRectangle(fillColor, cellBounds.X + 2, cellBounds.Y + 2, Convert.ToInt32((percentage * cellBounds.Width - 4)), cellBounds.Height - 4);
g.DrawString(progressVal.ToString() + "%", cellStyle.Font, foreColorBrush, cellBounds.X + 6, cellBounds.Y + 2);
}
else
这就是你如何使用它:
dataGridView1.Columns.Add(new DataGridViewProgressColumn { RedUntil = 0.5f, YellowUntil = 0.75f });