我有一个绑定到数据源的DataGridView。我想让细胞的背面颜色改变(比如红色),只要细胞中的值发生变化就会持续1-2秒。我已经尝试过并且能够更改单元格的背面颜色,但几秒钟后无法将其恢复为默认颜色。这个想法是在用户的价值发生变化时引起用户的注意。
应用程序C#.NET 4.5
答案 0 :(得分:1)
我为按钮创建了示例,但您可以将它应用于DataGridView单元格。
private Color OriginalColor = Color.WhiteSmoke;
private int TimeToColorInMiliSeconds = 2000;
private void button1_Click(object sender, EventArgs e)
{
ColorForTwoSeconds(button1);
}
private void ColorForTwoSeconds(Button button)
{
button.BackColor = Color.Red;
Task.Run(() => ResetBackColor());
}
private void ResetBackColor()
{
Thread.Sleep(TimeToColorInMiliSeconds);
button1.BeginInvoke((MethodInvoker) delegate
{
button1.BackColor = OriginalColor;
});
}
答案 1 :(得分:0)
试试这个
dataGridView1.Rows[rowIndex].Cells[columnIndex].Style.BackColor = Color.Red;
如果你想为所有行着色试试这个
dataGridView1.RowsDefaultCellStyle.SelectionBackColor = Color.Red;
答案 2 :(得分:0)
与KernalMode suggested非常相似,您可以使用线程调用将单元格BackColor
设置一段时间。为了确保对单元格的其他编辑在颜色更改时“重置”计时器,您可以使用上次编辑的DateTime
值设置单元格的标记,并检查其经过的时间。
private int TimeToColorInMiliSeconds = 2000;
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
this.dataGridView1[e.ColumnIndex, e.RowIndex].Tag = DateTime.Now;
Task.Run(() => this.ChangeCellBackground(e.ColumnIndex, e.RowIndex, Color.White, Color.IndianRed));
}
private void ChangeCellBackground(int col, int row, Color original, Color alert)
{
this.dataGridView1.BeginInvoke((MethodInvoker)delegate
{
this.dataGridView1[col, row].Style.BackColor = alert;
});
Thread.Sleep(this.TimeToColorInMiliSeconds);
this.dataGridView1.BeginInvoke((MethodInvoker)delegate
{
DateTime lastChanged = (DateTime)(this.dataGridView1[col, row].Tag);
DateTime timeNow = DateTime.Now;
TimeSpan elapsed = timeNow - lastChanged;
if (elapsed.TotalMilliseconds >= this.TimeToColorInMiliSeconds)
{
this.dataGridView1[col, row].Style.BackColor = original;
}
});
}
测试目的
要模拟快速更改,请考虑以下示例,其中所有单元格都初始化为0
,单击按钮会开始递归函数,该函数会每隔N
毫秒递增一个随机选择的单元格的值
private int N = 500;
private Random rand = new Random();
private void Button1_Click(object sender, EventArgs e)
{
Task.Run(() => this.IncrementRandomCell());
}
private void IncrementRandomCell()
{
int col = this.rand.Next(this.dataGridView1.ColumnCount);
int row = this.rand.Next(this.dataGridView1.RowCount);
this.dataGridView1.BeginInvoke((MethodInvoker)delegate
{
int value = int.Parse(this.dataGridView1[col, row].Value.ToString());
this.dataGridView1[col, row].Value = ++value;
});
Thread.Sleep(this.N);
this.IncrementRandomCell();
}
答案 3 :(得分:0)
这是我的方法。通过创建自己的单元格,您可以检查值是否已更改并相应地处理它。使用Forms.Timer可以避免使用线程。
由于DataGridViewCells没有OnValueChanged事件,我们重写Paint以检查值是否已更改。 如果是这样,我们更改BackColor并启动计时器以将BackColor重置为之前的值。
如您所见,我从DataGridViewTextBoxCell派生。但是重写DataGridViewCheckBoxCell或任何其他应该基本上以相同的方式工作。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridViewCustomControls
{
internal class DataGridViewHighlightChangeCell : DataGridViewTextBoxCell
{
public Color HighlightColor { get; set; } = Color.Red;
public int HighlightTime { get; set; } = 1000;
private object PreviousValue;
private Color PreviousColor;
private Timer HighlightTimer = new Timer();
public DataGridViewHighlightChangeCell()
{
HighlightTimer.Tick += HighlightTimer_Tick;
}
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
HighlightOnChange();
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
private void HighlightOnChange()
{
if (RowIndex == -1 || Value == PreviousValue)
{
return;
}
PreviousValue = Value;
if (HighlightTimer.Enabled)
{
HighlightTimer.Stop();
HighlightTimer.Start();
return;
}
PreviousColor = Style.BackColor;
Style.BackColor = HighlightColor;
HighlightTimer.Interval = HighlightTime;
HighlightTimer.Start();
}
private void HighlightTimer_Tick(object sender, EventArgs e)
{
HighlightTimer.Stop();
Style.BackColor = PreviousColor;
}
protected override void Dispose(bool disposing)
{
if (disposing && HighlightTimer != null)
{
HighlightTimer.Dispose();
HighlightTimer = null;
}
base.Dispose(disposing);
}
}
}