所以我有一个有趣的问题(无论如何)。我正在编写一个运行扫描的应用程序,并将类中的信息发布回Windows窗体。现在我正在创建一个表单实例,访问ActiveForm,然后将一些文本发布到该表单中的公共函数。
Scan.cs
// Sets the text of scan history in the ui
private void SetScanHistory(string text)
{
MyWinForm1 form = (MyWinForm1)MyWinForm1.ActiveForm;
if (form != null)
{
form.SetText(text);
}
}
MyWinForm1.cs
// Sets the text of txtScanHistory to the text
public void SetText(string text)
{
this.Invoke((MethodInvoker)delegate
{
// txtScanHistory is a TextBox
txtScanHistory.Text += text + Environment.NewLine;
});
}
所以现在这个效果非常好。问题是当用户将焦点从Windows窗体更改为文本停止更新时,这就是为什么我有“if(form!= null)”。我知道这不是我想要做的事情的理想方式,所以我的问题是如何将此代码更改为“MyWinForm1”中的自定义事件?或者,如果还有其他方法可以做到这一点,我很乐意看到一些替代方案。
答案 0 :(得分:1)
有几种方法可以达到你想要的效果。
1)您可以添加对目标表单的引用作为Scan.cs类的属性
public MyWinForm1 WinFormReference { get; set; }
// Sets the text of scan history in the ui
private void SetScanHistory(string text)
{
if (this.WinFormReference != null)
{
this.WinFormReference.SetText(text);
}
}
然后你可以将你的扫描类的引用传递给WinForm1实例并设置相应的属性[在这种情况下我使用WinForm构造函数传递扫描器类]:
public void WinForm1(Scan scanner)
{
if (scanner != null) scanner.WinFormReference = this;
}
2)您可以将自定义事件添加到扫描类,然后将代理挂钩到WinForm中的回调[再次,您的WinForm将需要引用您的扫描类]:
public class SetScanHistoryEvents: EventArgs
{
public SetScanHistoryEvents(string text)
{
this.Text = text;
}
public string Text { get; set; }
}
public class Scan
{
public event EventHandler<SetScanHistoryEvents> ScanHistoryEvent;
// Sets the text of scan history in the ui
private void SetScanHistory(string text)
{
if (this.ScanHistoryEvent != null)
{
this.ScanHistoryEvent(this, new SetScanHistoryEvents(text));
}
}
}
然后你在表单的构造函数(或其他地方)中挂钩回调:
public MyWinForm1(Scan scanner)
{
if (scanner != null)
scanner.ScanHistoryEvent += new EventHandler<SetScanHistoryEvents>(scanner_ScanHistoryEvent);
}
private void scanner_ScanHistoryEvent(object sender, SetScanHistoryEvents e)
{
this.Invoke((MethodInvoker)delegate
{
// txtScanHistory is a TextBox
txtScanHistory.Text += text + Environment.NewLine;
});
}
答案 1 :(得分:0)
您可以使用SynchronizationContext
public partial class Form1 : Form
{
SynchronizationContext context;
public Form1()
{
InitializeComponent();
context = SynchronizationContext.Current;
}
// Sets the text of scan history in the ui
private void SetScanHistory(string text)
{
CallFunc(text);
}
private void CallFunc(string TextValue)
{
context.Post(new SendOrPostCallback(
delegate
{
textBox1.Text += TextValue + Environment.NewLine;
}), TextValue);
}
}