我使用ObjectListView总体上不错,但是我发现了一个使我感到困扰的问题,因为它是视觉缺陷。我有一种方法,它每2秒运行一次,并根据条件以当前时间更新某些列。但是,在更新对象并使用RefreshObject方法之后,该行将获得默认的背景色,以获得一小段时间,然后将其行颜色恢复为原来的颜色,这将导致闪烁。如果我不使用RefreshObject,它会在该行中更新我的模型,但不会在视觉上更新。我得到行项目的方式是:
rowItem GG = OLVa.GetItem(i).RowObject as rowItem;
GG.Time = "something";
OLVa.Refreshobject(GG);
以及我为行着色的方式是这样的:
OLVa.GetItem(i).BackColor = Color.Pink;
根据条件更改行的背景色后,我只使用OLVa.Refresh();
我不确定为行着色或更新行时会出错吗?
解决您的问题
问题出在使用GetItem
,它返回UI控件元素。使用对象列表视图,您应该基于对象执行所有操作,而不更改实际的Control元素。基本上,您是使用这种方法来对抗API,而不是使用它。
我认为您应该使用RowFormatter
设置背景色:
OLVa.RowFormatter = (o) =>
{
if(o.RowObject == "B")
o.BackColor = Color.Pink;
};
重现问题
我能够使用以下(错误的)代码重现您描述的问题。它会像您描述的那样闪烁:
public class MainForm : Form
{
public MainForm()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(284, 261);
this.Name = "MainForm";
this.ResumeLayout(false);
this.PerformLayout();
var OLVa = new ObjectListView();
OLVa.Dock = DockStyle.Fill;
OLVa.Columns.Add(new OLVColumn("Name", "ToString"));
this.Controls.Add(OLVa);
OLVa.AddObject("A");
OLVa.AddObject("B");
OLVa.AddObject("C");
Timer t = new Timer();
t.Interval = 100;
t.Tick += (s,e)=>OLVa.RefreshObject("B");
t.Start();
Timer t2 = new Timer();
t2.Interval = 200;
t2.Tick += (s,e)=>OLVa.GetItem(1).BackColor = Color.Pink;
t2.Start();
}
}
将第二个计时器更改为行格式化程序可解决此问题。
根据条件更改行高亮显示
调用RefreshObject
会自动触发RowFormatter
和方面,因此,如果您想随着时间的推移更改行的状态(例如,按照注释中的要求,您可以执行以下操作:
public class MainForm : Form
{
public MainForm()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(300, 300);
this.Name = "MainForm";
this.ResumeLayout(false);
this.PerformLayout();
var OLVa = new FastObjectListView();
OLVa.Width = 250;
OLVa.Height = 250;
OLVa.Columns.Add(new OLVColumn("Done", "Done"));
OLVa.Columns.Add(new OLVColumn("Percent", "PercentComplete"));
this.Controls.Add(OLVa);
Video v = new Video();
OLVa.AddObject(v);
var t = new Timer();
t.Interval = 1000;
t.Start();
OLVa.RowFormatter = (s) => s.BackColor = ((Video) s.RowObject).Done ? Color.Green : Color.Red;
t.Tick += (s,e)=>
{
v.PercentComplete = Math.Min(v.PercentComplete += 10, 100);
if (v.PercentComplete == 100)
v.Done = true;
OLVa.RefreshObject(v);
};
}
private class Video
{
public bool Done { get; set; }
public int PercentComplete { get; set; }
}
}