如題
void _MainLoop(object sender, System.Timers.ElapsedEventArgs e)
{
float Value;
if (!WebAccessFunction.GetTagValue(strTag_Name, out Value))
{
#region 委派 textbox
UpdateUI("讀取Tag失敗", listBox);
#endregion
Thread.Sleep(1000);
}
else if (Value == 1)
{
#region 委派 textbox
UpdateUI(DateTime.Now.ToString() + " 火警發生中", listBox);
#endregion
if (_EventTimer.Enabled == false)
{
this._EventTimer = new System.Timers.Timer();
this._EventTimer.Interval = Convert.ToInt32(time) * 1000;
this._EventTimer.Elapsed += new System.Timers.ElapsedEventHandler(_EventLoop);
this._EventTimer.Start();
if (Flage)
{
RunUrl();
Flage = false;
}
}
}
else
{
Flage = true;
UpdateUI("火警點復歸", listBox);
if (_EventTimer.Enabled)
_EventTimer.Stop();
}
}
#region 委派 textbox
private delegate void UpdateUICallBack(string value, Control ctl);
private void UpdateUI(string value, Control ctl)
{
if (this.InvokeRequired)
{
UpdateUICallBack uu = new UpdateUICallBack(UpdateUI);
this.Invoke(uu, value, ctl);
}
else
{
ctl.Text = value;
}
}
#endregion
部分code如上
請教各位先進
小弟因程式中有跑兩個timer以及需要ui form的顯示
所以網路上google了delegate委派這個方法
範例中是使用textbox
我實際測試確實也沒有問題
但若我要換成使用listbox顯示卻是無法顯示
想請教各位先進我有什麼地方弄錯或是遺漏了
像是
ctl.Text = value;
這裡我有嘗試想要寫成
ctl.items.add(value);
但是ctl下並沒有items
所以想請各位先進指點一下
你的ctl 沒cast成ListBox
using System;
using System.Windows.Forms;
namespace 兩個時鐘
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Interval = 2000;
timer2.Interval = 2000;
timer1.Enabled = true;
timer2.Enabled = true;
}
private void timer2_Tick(object sender, EventArgs e)
{
UpdateUI(DateTime.Now.ToString("Timer2=>hh:mm:ss"), listBox1);
}
private void timer1_Tick(object sender, EventArgs e)
{
UpdateUI(DateTime.Now.ToString("Timer1=>hh:mm:ss"), listBox1);
}
private void UpdateUI(string value, Control ctl)
{
if (((ListBox)ctl).InvokeRequired)
{
((ListBox)ctl).Invoke(new MethodInvoker(delegate
{
((ListBox)ctl).Items.Add(value);
}));
}
else
{
((ListBox)ctl).Items.Add(value);
}
}
}
}
感謝大大的相助
這個問題解決了
但是遇到另一個問題
若是一般非委派的做法我下
ListBox1.SelectedIndex = ListBox1.Items.Count - 1
就可以讓資料都是顯示最新的
但若是目前這種寫法
我卻不清楚該如何讓資料持續顯示最新
是指你要讓最後一行被標示並顯示在畫面上嗎?
items.add下面加一行
((ListBox)ctl).SetSelected(((ListBox)ctl).Items.Count - 1, true);
}
private void UpdateUI(string value, Control ctl)
{
if (this.InvokeRequired)
{
UpdateUICallBack uu = new UpdateUICallBack(UpdateUI);
this.Invoke(uu, value, (ListBox)ctl);
}
else
{
((ListBox)ctl).Items.Add(value);
}
((ListBox)ctl).SetSelected(((ListBox)ctl).Items.Count - 1, true);
}
大大 我現在是寫成這樣
但是他還是會報跨執行續錯誤,如下
System.InvalidOperationException: '跨執行緒作業無效: 存取控制項 'listBox' 時所使用的執行緒與建立控制項的執行緒不同。'
我這樣寫不對嗎
OK 感謝大大 問題解決了
Control沒有items這個屬性,
你必須要指定ListBox才可以,
如果硬要寫在同一個Function的話,
可以嘗試這樣
else
{
if(ctl is ListBox)
((ListBox)ctl).items.add(value);
else
ctl.Text = value;
}
將 UpdateUI 換成下列的 AddToList
private void AddToList(object value)
{
if (listBox1.InvokeRequired)
{
var callback = new Action<object>(AddToList);
callback.BeginInvoke(value, ar => callback.EndInvoke(ar), callback);
return;
}
listBox1.Items.Add(value.ToString());
}