C#ObjectListView在刷新对象上闪烁

问题描述 投票:0回答:1

我使用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();

我不确定为行着色或更新行时会出错吗?

c# objectlistview
1个回答
2
投票

解决您的问题

问题出在使用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; }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.