我使用SQL中的两个数据集填充ListView
。这种情况每15秒发生一次。如何保持滚动位置并仍然刷新数据?我在这里看到了一些问题和相关问题,但没有一个真正解决我的具体问题。我尝试过TopMost选项但收效甚微。
有关如何保持滚动位置的任何建议?以下是我用来填充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();
}
答案 0 :(得分:2)
在VirtualMode
模式下使用listview并实施RetrieveVirtualItem
event。
它可以让您更好地控制可见内容,并且您无需清除所有项目以使其更新。
如果VirtualMode
设置为true
,您只需将VirtualListSize
设置为要在列表中显示的项目数。将为列表视图要向用户显示的每个项目触发RetrieveVirtualItem
事件。因此,如果您的数据发生变化,您可以调用listview的Refresh
方法,而RetrieveVirtualItem
处理程序将返回新项目数据。
考虑这个例子:
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();
}
}