私はこれについて数日間困惑していて、かなり殴られましたが、正直なところ、私はまだそれほど経験がなく、DataGridViewに問題があります-これは一般的なトピックのようです。
public partial class frmMain : Form
{
ServerConnection sabCom;
private BindingSource jobSource = new BindingSource();
private void timer1_Tick(object sender, EventArgs e)
{
if (bgUpdateThread.IsBusy == false)
{
bgUpdateThread.RunWorkerAsync(sabCom);
}
}
}
private void frmMain_Load(object sender, EventArgs e)
{
timer1.Interval = 3000;
timer1.Start();
}
private void bgUpdateThread_DoWork(object sender, DoWorkEventArgs e)
{
ServerConnection s = e.Argument as ServerConnection;
s.update();
e.Result = s;
}
private void bgUpdateThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.sabCom = e.Result as ServerConnection;
if (dgvQueueFormatted == false)
{
dgvQueue_Init(); //Applies formatting and loads column width. Inits data sources.
}
else
{
dgvQueue_Update();
}
}
private void dgvQueue_Update()
{
dgvQueue.Refresh();
}
private void dgvQueue_Init()
{
try
{
jobSource.DataSource = sabCom.queue.jobs;
dgvQueue.DataSource = jobSource;
try
{
//Apply saved column spacing to the dgvQueue
//Uses reflection to set dgvQueue to DoubleBuffer
}
catch
{ }
}
catch
{ }
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
//Saves information about the dgvQueue on shutdown.
}
キュークラス:
public class Queue
{
private string _status;
public string status { get { return _status; } set { _status = value; } }
private string _eta;
public string eta { get { return _eta; } set { _eta = value; } }
private List<Job> _jobs;
public List<Job> jobs
{
get
{
return _jobs;
}
set
{
_jobs = value;
}
}
private List<string> _categories;
public List<string> categories { get { return _categories; } set { _categories = value; } }
private XmlDocument xmld;
private ServerConnection m_parent;
private XmlNodeList _xmljobs;
public Queue(ServerConnection srvConn)
{
//fetch the Queue xml
m_parent = srvConn;
xmld = new XmlDocument();
_jobs = new List<Job>();
}
public void update()
{
updateXml();
updateQueue();
updateJobs();
}
private void updateXml()
{
//Loads xml file into xmld
}
private void updateQueue()
{
XmlNodeList elements = xmld.SelectNodes("queue");
foreach (XmlNode element in elements)
{
_status = element.SelectSingleNode("status").InnerText;
_eta = element.SelectSingleNode("eta").InnerText;
}
}
private void updateJobs()
{
_xmljobs = xmld.SelectNodes("queue/job");
jobs.Clear();
foreach (XmlNode xmljob in _xmljobs)
{
Job t_job;
_status = xmljob.SelectSingleNode("status").InnerText;
_eta = xmljob.SelectSingleNode("eta").InnerText;
//Create temp job to match against list.
t_job = new Job(_status, _eta);
jobs.Add(t_job);
}
}
ジョブクラス:実際には、さまざまなタイプの約30の値を保持しますが、それらはすべて同じ形式です。
public class Job
{
private int _status;
public int status { get { return _status; } set { _status = value; } }
private string _eta;
public string eta { get { return _eta; } set { _eta = value; } }
public Job(string status, string eta)
{
_status = status;
_eta = eta;
}
}
DataGridViewを操作すると、次のエラーが発生します。
DataGridViewで次の例外が発生しました。
System.IndexOutOfRangeException:インデックスに値がありません。System.Windows.Forms.CurrencyManager.get_Item(Int32 index)at System.Windows.Forms.DataGridViewDataConnection.GetError(Int32 boundColumnIndex、Int32 columnIndex、Int32 rowIndex)
そして、デバッガーに入ると、最初のApplication.Run(new frmMain()でトリガーされます。一体何が間違っているのでしょうか。プログラムは正常に機能して更新されますが、デフォルトのエラーメッセージを抑制するためにイベントを処理することさえできません。
編集-回答!リストをクリアして再作成する代わりに、リスト内の値を更新するだけの方が効果的です。今のところ私はこのコードを持っています:
t_job = _jobs.FirstOrDefault(c => c.nzo_id == t_nzo_id);
if (t_job == null) //Job not in list, insert
{
t_job = new Job(t_status, i_index, t_eta, i_timeLeft, t_age, i_mbleft, i_mb, t_filename, i_priority, t_category, i_percentage, t_nzo_id, this);
jobs.Add(t_job);
}
else //update object in current list
{
jobs[t_job.Index].status = t_status;
jobs[t_job.Index].priority = i_priority;
jobs[t_job.Index].category = t_category;
jobs[t_job.Index].percentage = i_percentage;
jobs[t_job.Index].timeleft = i_timeLeft;
jobs[t_job.Index].mbleft = i_mbleft;
}
それを防ぎます!