从动态创建 class 更新 UI
Update UI from dynamic created class
我动态地创建了几个 classes 和标签。我想更新我的 class 中的标签文本,但我不知道如何实现它。
我的class:
public partial class ScannerUtility : INotifyPropertyChanged
{
public System.Timers.Timer timerHeartBeat = new System.Timers.Timer();
public DateTime lastHeartBeat = new DateTime();
public string heartBeatMessage = string.Empty;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public void EnableScannerUtility()
{
timerHeartBeat = new System.Timers.Timer();
timerHeartBeat.AutoReset = true;
timerHeartBeat.Interval = 5000;// 35000;
timerHeartBeat.Elapsed += TimerHeartBeat_Elapsed;
timerHeartBeat.Start();
}
private void TimerHeartBeat_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeSpan timeSinceLastHeartbeat = DateTime.Now.ToUniversalTime() - lastHeartBeat;
if (timeSinceLastHeartbeat > TimeSpan.FromSeconds(30))
{
HeartBeatMessage = "No Answer from Scanner";
}
else
{
HeartBeatMessage = "Scanner OK";
}
}
public string HeartBeatMessage
{
get { return this.heartBeatMessage; }
set
{
if (value != this.heartBeatMessage)
{
this.heartBeatMessage = value;
NotifyPropertyChanged("heartBeatMessage");
}
}
}
}
以及我从主窗体创建它的循环:
private void CreateSckanners()
{
foreach (BarCodeNodes item in iBarcodeScanners)
{
ScannerUtility util = new ScannerUtility();
util.EnableScannerUtility();
Label lbl = new Label();
lbl.Text = item.IP.ToString();
lbl.Name = item.IP.ToString();
lbl.DataBindings.Add("Text", util, "HeartBeatMessage", false, DataSourceUpdateMode.OnPropertyChanged);
flowLayoutPanel1.Controls.Add(lbl);
flowLayoutPanel1.Update();
}
}
我希望在计时器结束时更新标签。
恐怕您不能在您的情况下使用 DataBindigns
。您必须坚持 InvokeRequired style. Here, SO question 关于在另一个线程中更新控件。
bokibeg 是对的。我放了代码以防有人感兴趣。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
ScannerUtility util = new ScannerUtility(SynchronizationContext.Current);
util.EnableScannerUtility();
util.HeartBeatMessage = "Waiting for scanner...";
this.SuspendLayout();
Label lbl = new Label();
lbl.Text = "Waiting for scanner...";
lbl.Name = "lblTimer";
lbl.Location = new System.Drawing.Point(15, 15);
lbl.AutoSize = true;
lbl.DataBindings.Add("Text", util, "HeartBeatMessage", false, DataSourceUpdateMode.OnPropertyChanged);
this.Controls.Add(lbl);
this.ResumeLayout(true);
}
}
public partial class ScannerUtility : INotifyPropertyChanged
{
private SynchronizationContext _uiThreadContext;
public System.Timers.Timer timerHeartBeat = new System.Timers.Timer();
public DateTime lastHeartBeat = new DateTime();
public string heartBeatMessage = string.Empty;
public event PropertyChangedEventHandler PropertyChanged;
public ScannerUtility(SynchronizationContext uiThreadContext)
{
_uiThreadContext = uiThreadContext;
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
_uiThreadContext.Post(onUIPropertyChanged, new PropertyChangedEventArgs(info));
}
;
}
private void onUIPropertyChanged(object state)
{
PropertyChanged(this, (PropertyChangedEventArgs)state);
}
public void EnableScannerUtility()
{
timerHeartBeat = new System.Timers.Timer();
timerHeartBeat.AutoReset = true;
timerHeartBeat.Interval = 5000;// 35000;
timerHeartBeat.Elapsed += TimerHeartBeat_Elapsed;
timerHeartBeat.Start();
}
private void TimerHeartBeat_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeSpan timeSinceLastHeartbeat = DateTime.Now.ToUniversalTime() - lastHeartBeat;
if (timeSinceLastHeartbeat > TimeSpan.FromSeconds(30))
{
HeartBeatMessage = "No Answer from Scanner";
}
else
{
HeartBeatMessage = "Scanner OK";
}
}
public string HeartBeatMessage
{
get
{
return this.heartBeatMessage;
}
set
{
if (value != this.heartBeatMessage)
{
this.heartBeatMessage = value;
NotifyPropertyChanged("HeartBeatMessage");
}
}
}
}
}
我动态地创建了几个 classes 和标签。我想更新我的 class 中的标签文本,但我不知道如何实现它。
我的class:
public partial class ScannerUtility : INotifyPropertyChanged
{
public System.Timers.Timer timerHeartBeat = new System.Timers.Timer();
public DateTime lastHeartBeat = new DateTime();
public string heartBeatMessage = string.Empty;
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public void EnableScannerUtility()
{
timerHeartBeat = new System.Timers.Timer();
timerHeartBeat.AutoReset = true;
timerHeartBeat.Interval = 5000;// 35000;
timerHeartBeat.Elapsed += TimerHeartBeat_Elapsed;
timerHeartBeat.Start();
}
private void TimerHeartBeat_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeSpan timeSinceLastHeartbeat = DateTime.Now.ToUniversalTime() - lastHeartBeat;
if (timeSinceLastHeartbeat > TimeSpan.FromSeconds(30))
{
HeartBeatMessage = "No Answer from Scanner";
}
else
{
HeartBeatMessage = "Scanner OK";
}
}
public string HeartBeatMessage
{
get { return this.heartBeatMessage; }
set
{
if (value != this.heartBeatMessage)
{
this.heartBeatMessage = value;
NotifyPropertyChanged("heartBeatMessage");
}
}
}
}
以及我从主窗体创建它的循环:
private void CreateSckanners()
{
foreach (BarCodeNodes item in iBarcodeScanners)
{
ScannerUtility util = new ScannerUtility();
util.EnableScannerUtility();
Label lbl = new Label();
lbl.Text = item.IP.ToString();
lbl.Name = item.IP.ToString();
lbl.DataBindings.Add("Text", util, "HeartBeatMessage", false, DataSourceUpdateMode.OnPropertyChanged);
flowLayoutPanel1.Controls.Add(lbl);
flowLayoutPanel1.Update();
}
}
我希望在计时器结束时更新标签。
恐怕您不能在您的情况下使用 DataBindigns
。您必须坚持 InvokeRequired style. Here, SO question 关于在另一个线程中更新控件。
bokibeg 是对的。我放了代码以防有人感兴趣。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
ScannerUtility util = new ScannerUtility(SynchronizationContext.Current);
util.EnableScannerUtility();
util.HeartBeatMessage = "Waiting for scanner...";
this.SuspendLayout();
Label lbl = new Label();
lbl.Text = "Waiting for scanner...";
lbl.Name = "lblTimer";
lbl.Location = new System.Drawing.Point(15, 15);
lbl.AutoSize = true;
lbl.DataBindings.Add("Text", util, "HeartBeatMessage", false, DataSourceUpdateMode.OnPropertyChanged);
this.Controls.Add(lbl);
this.ResumeLayout(true);
}
}
public partial class ScannerUtility : INotifyPropertyChanged
{
private SynchronizationContext _uiThreadContext;
public System.Timers.Timer timerHeartBeat = new System.Timers.Timer();
public DateTime lastHeartBeat = new DateTime();
public string heartBeatMessage = string.Empty;
public event PropertyChangedEventHandler PropertyChanged;
public ScannerUtility(SynchronizationContext uiThreadContext)
{
_uiThreadContext = uiThreadContext;
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
_uiThreadContext.Post(onUIPropertyChanged, new PropertyChangedEventArgs(info));
}
;
}
private void onUIPropertyChanged(object state)
{
PropertyChanged(this, (PropertyChangedEventArgs)state);
}
public void EnableScannerUtility()
{
timerHeartBeat = new System.Timers.Timer();
timerHeartBeat.AutoReset = true;
timerHeartBeat.Interval = 5000;// 35000;
timerHeartBeat.Elapsed += TimerHeartBeat_Elapsed;
timerHeartBeat.Start();
}
private void TimerHeartBeat_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeSpan timeSinceLastHeartbeat = DateTime.Now.ToUniversalTime() - lastHeartBeat;
if (timeSinceLastHeartbeat > TimeSpan.FromSeconds(30))
{
HeartBeatMessage = "No Answer from Scanner";
}
else
{
HeartBeatMessage = "Scanner OK";
}
}
public string HeartBeatMessage
{
get
{
return this.heartBeatMessage;
}
set
{
if (value != this.heartBeatMessage)
{
this.heartBeatMessage = value;
NotifyPropertyChanged("HeartBeatMessage");
}
}
}
}
}