简体   繁体   English

刷新后的'ListView'位置

[英]'ListView' position after refresh

I am populating a ListView with two data sets from SQL. 我正在使用SQL中的两个数据集填充ListView This happens every 15 seconds. 这种情况每15秒发生一次。 How can I keep the scrolled-to position and still refresh the data? 如何保持滚动位置并仍然刷新数据? I have seen some questions here with related issues but none really address my specific issue. 我在这里看到了一些问题和相关问题,但没有一个真正解决我的具体问题。 I have tried the TopMost option with limited success. 我尝试过TopMost选项但成效有限。

Any suggestions on how I can keep the scrolled-to position? 关于如何保持滚动位置的任何建议? Here is a bit of code that I use to populate the data for the ListBox . 这里有一些代码用于填充ListBox的数据。

private void PopulateData()
{        
    _agent.Stop();
    listView1.Items.Clear();
    listView1.Groups.Clear();
    listView1.BeginUpdate();
    string filter;

    DataTable dt1 = new DataTable();
    DataTable dt2 = new DataTable();

    dt1.Columns.Add("Name", typeof(string));
    dt1.Columns.Add("Status", typeof(string));
    dt1.Columns.Add("Time", typeof(double));
    dt1.Columns.Add("Calls", typeof(double));
    dt1.Columns.Add("InProgress", typeof(double));
    dt1.Columns.Add("Region", typeof(string));

    dt2.Columns.Add("Name", typeof(string));
    dt2.Columns.Add("CChats", typeof(double));
    dt2.Columns.Add("AChats", typeof(double));

    foreach (DataRow dr in _agentStates.Rows)
    {
        DataRow row = dt1.NewRow();
        row["Name"] = dr[0].ToString();
        row["Status"] = dr[1].ToString();
        row["Time"] = Convert.ToDouble(dr[2].ToString());
        row["Calls"] = Convert.ToDouble(dr[3].ToString());
        row["InProgress"] = Convert.ToDouble(dr[4].ToString());
        row["Region"] = dr[5].ToString();
        dt1.Rows.Add(row);
    }

    foreach (DataRow dr in _chatCount.Rows)
    {
        DataRow row = dt2.NewRow();
        row["Name"] = dr[0].ToString();
        row["CChats"] = Convert.ToDouble(dr[1].ToString());
        row["AChats"] = Convert.ToDouble(dr[2].ToString());
        dt2.Rows.Add(row);

    }

    var result = from table1 in dt1.AsEnumerable()
                 join table2 in dt2.AsEnumerable()
                 on (string)table1["Name"] equals (string)table2["Name"]
                 into joinedDt
                 from table2 in joinedDt.DefaultIfEmpty()
                 select new
                 {
                     Name = (string)table1["Name"],
                     Status = (string)table1["Status"],
                     Time = (double)table1["Time"],
                     Calls = (double)table1["Calls"],
                     InProgress = (double)table1["InProgress"],
                     Region = (string)table1["Region"],
                     CChats = (table2 != null ? (double)table2["CChats"] : 0),
                     AChats = (table2 != null ? (double)table2["AChats"] : 0)
                 };

    foreach (var item in result)
    {
        if (item.Status != "NLO" && item.Status !="Webchat Account")
        {
            var calls = item.Calls + item.CChats;
            var lvi = new ListViewItem(item.Name);
            lvi.SubItems.Add(item.Status);
            lvi.SubItems.Add(Conv.Time(item.Time));
            lvi.SubItems.Add(item.Calls.ToString());
            lvi.SubItems.Add(item.CChats.ToString());
            lvi.SubItems.Add((item.AChats + item.InProgress).ToString());
            lvi.SubItems.Add(calls.ToString());
            this.listView1.Items.Add(lvi);
        }
    }

    listView1.EndUpdate();
    _agent.Start();
}

Use the listview in VirtualMode mode and implement the RetrieveVirtualItem event . VirtualMode模式下使用listview并实现RetrieveVirtualItem事件

It will give you a better control over what is visible, and you don't need to clear all items to get it updated. 它可以让您更好地控制可见内容,并且您无需清除所有项目以使其更新。

If VirtualMode is set to true , you just set the VirtualListSize to the number of items you want to display in the list. 如果将VirtualMode设置为true ,则只需将VirtualListSize设置为要在列表中显示的项目数。 The RetrieveVirtualItem event will be fired for each item the listview wants to show to the user. 将为listview要向用户显示的每个项触发RetrieveVirtualItem事件。 So if your data changes, you can call the Refresh method of the listview and your RetrieveVirtualItem handler will return the new item data. 因此,如果数据发生更改,则可以调用listview的Refresh方法, RetrieveVirtualItem处理程序将返回新项数据。

Consider this example: 考虑这个例子:

public partial class Form1 : Form
{
    private int i = 0;

    public Form1()
    {
        InitializeComponent();
        listView1.View = View.Details;
        listView1.Columns.Add("Col", 250);
        listView1.VirtualMode = true;
        listView1.RetrieveVirtualItem += listView1_RetrieveVirtualItem;
        listView1.VirtualListSize = 25;
        button1.Click += button1_Click;
    }

    private void listView1_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
    {
        e.Item = new ListViewItem((i + e.ItemIndex).ToString());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // simulate data update
        i += 10;
        //listView1.VirtualListSize += 5; // you can even change the virtual list size while keeping current scroll position
        listView1.Refresh();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM