C# 基于侦听器类实现在运行时更改的Windows窗体
我目前正在为Leap Motion设备设计GUI(尽管我的问题可能会出现在任何类型的侦听器设备上) 我正在Windows窗体中运行应用程序,代码如下:C# 基于侦听器类实现在运行时更改的Windows窗体,c#,winforms,leap-motion,C#,Winforms,Leap Motion,我目前正在为Leap Motion设备设计GUI(尽管我的问题可能会出现在任何类型的侦听器设备上) 我正在Windows窗体中运行应用程序,代码如下: public partial class FormRecord : Form { public FormRecord() { InitializeComponent(); } public void UpdateGUI(Frame frame) { //get informat
public partial class FormRecord : Form
{
public FormRecord()
{
InitializeComponent();
}
public void UpdateGUI(Frame frame)
{
//get information from captured frame
//update the GUI (specifically labels)
customLabel0.Text = someValueFromFrame.ToString();
}
//该方法代码由Leap Motion在其网站上提供
public static void RunMain()
{
// Create a sample listener and controller
SampleListener listener = new SampleListener();
Controller controller = new Controller();
//Controller is included in Leap.dll (from SDK) and is an instance of controller
// Have the sample listener receive events from the controller
controller.AddListener(listener);
Console.WriteLine("Press Enter to quit...");
Console.ReadLine();
// Remove the sample listener when done
controller.RemoveListener(listener);
controller.Dispose();
}
//该类也在Leap Motion SDK中提供
class SampleListener : Listener
{
private Object thisLock = new Object();
private void SafeWriteLine(String line)
{
lock (thisLock)
{
Console.WriteLine(line);
}
}
public override void OnInit(Controller controller)
{
SafeWriteLine("Initialized");
}
public override void OnConnect(Controller controller)
{
SafeWriteLine("Connected");
}
public override void OnDisconnect(Controller controller)
{
//Note: not dispatched when running in a debugger.
SafeWriteLine("Disconnected");
}
public override void OnExit(Controller controller)
{
SafeWriteLine("Exited");
}
public override void OnFrame(Controller controller) //
//public void OnFrame(Controller controller)
{
SafeWriteLine("Framed");
//Do something useful with the captured frame
// get the current frame
Frame frame = controller.Frame();
/* This is where my problem occurs */
// attempt to use information from this form and call UpdateGUI(Frame frame)
}
}
}
基本上,这个问题是由于两个类在静态和非静态性质上的差异而产生的。例如,我的应用程序(Windows窗体)是非静态的,因为它是一个窗体,您必须能够自然地创建多个实例。然而,这就是为什么我不能简单地称之为:
Form aForm = new Form();
aForm.UpdateGUI();
^^这将创建一个新的表单。我希望能够在原始表单上使用UpdateGUI()方法
我也试过了
guiForm = ActiveForm;
然后从那里给标签打电话
ActiveForm.customlbl0.Text = valueToDisplay;
更一般地说,我尝试根据从侦听器接收的数据更新Windows窗体。这给我带来了麻烦,因为我不得不在静态和非静态成员之间挣扎。我将使它成为一个类,但是我需要为这两个组件实现表单和侦听器。如何使用侦听器中的实时数据更新显示
编辑:监听器是SDK文件“LeapCSharp.Net4.0dll”中的一个实现。我会让SampleListener的构造函数获取表单类的一个实例。创建侦听器时,传入对表单的引用并将其存储在私有字段中。这样,您就可以从侦听器内部对其调用方法
另一个选项是让SampleListener类为每个事件引发事件。然后,您可以从表单内部钩住事件。类似于:
public partial class FormRecord : Form
{
Controller controller;
public FormRecord()
{
InitializeComponent();
controller = new Controller();
}
public void UpdateGUI()
{
Frame frame = controller.frame();
//get information from captured frame
//update the GUI (specifically labels)
customLabel0.Text = someValueFromFrame.ToString();
}
如果使用侦听器,请注意每个侦听器回调都是在其自己的线程上调用的。通常不能从主线程以外的任何线程更新GUI框架(如Windows窗体等)直接访问的对象。(不过,我不知道在Windows窗体中进行跨线程通信的最佳方法。)我会选择事件,因此
SampleListener
不依赖Form
类。您有没有可能收集一些代码来帮我解决问题?我不太确定如何实现这些解决方案。侦听器无法更新表单,因为它的回调是在非GUI线程上调用的。您必须将事件/委托用于此方法。我添加了一个将代理用于Leap Motion文档的示例:成功了!我的印象是,它必须使用一个倾听者,但事实并非如此。我对这段代码的唯一更正是,从技术上讲,按照您提出的解决方案的方式,使用第二种方法更有意义,如下所示:public void UpdateGUI(Controller)
,因为您将在下一行重新定义帧,覆盖引入的内容。侦听器只是获取帧的一种方法,而且由于线程问题,通常不是最直接的方法。另外,我在修改现有代码(现在已编辑)时忽略了框架参数。您也不需要传入控制器对象,因为它是一个实例属性(除非调用UpdateGUI()的对象拥有控制器实例而不是FormRecord类)。。