c#从另一个类/事件更新WinForm GUI文本框

时间:2018-09-25 11:37:10

标签: c# winforms desktop-application

我正在学习使用PtGrey相机的API。

我有公司提供的以下用于设备到达和移除的类示例。

    Class SystemEventListener: ManagedInterfaceEvent
    {
        private IManagedSystem system;

        public SystemEventListener(IManagedSystem sys) { system = sys; }


        protected override void OnDeviceArrival(UInt64 serialNumber)
        {
            int count = system.GetCameras().Count;

            Console.WriteLine("System event listener:");
            Console.WriteLine("\tThere {0} {1} {2} on the system.", (count == 1 ? "is" : "are"), count, (count == 1 ? "device" : "devices"));
        }

        protected override void OnDeviceRemoval(UInt64 serialNumber)
        {
            int count = system.GetCameras().Count;

            Console.WriteLine("System event listener:");
            Console.WriteLine("\tThere {0} {1} {2} on the system.", (count == 1 ? "is" : "are"), count, (count == 1 ? "device" : "devices"));
        }
    }

我正在尝试使其适应我的获胜形式环境。在努力从此类中更新GUI之后,我设法通过链接here来更新文本框。但是,它涉及到修改program.cs文件。

我的问题是如何从另一个类的这些事件中更新文本框,最好不要触摸Program.cs。

我确实尝试使用委托/事件等。但是每次,我在主窗体(Form1)实例上遇到Null Reference Exception。我显然做错了。

下面是我当前的实现方式,但是我希望通过另一种方式来修改program.cs。

Program.cs

    public static Form1 MainForm;
    [STAThread]
    static void Main()
    {

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        MainForm = new Form1();
        Application.Run(MainForm);
    }

Form1.cs

    public Form1()
    {
        InitializeComponent();

        SystemEventListener systemEventListener = new SystemEventListener(system);
        system.RegisterInterfaceEvent(systemEventListener);
    }

    private void AppendTextBox(string value)
    {
        if (InvokeRequired)
        {
            this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
            return;
        }
        textBoxCamProperties.AppendText(DateTime.Now.ToString("h:mm:ss tt") + "-" + value + Environment.NewLine);
    }

    public class SystemEventListener : ManagedInterfaceEvent
    {
        private IManagedSystem system;

        public SystemEventListener(IManagedSystem sys) { system = sys; }

        protected override void OnDeviceArrival(UInt64 serialNumber)
        {
            //int count = system.GetCameras().Count;

            Program.MainForm.AppendTextBox("Device attached\r\n");


        }

       protected override void OnDeviceRemoval(UInt64 serialNumber)
        {
            //int count = system.GetCameras().Count;

            Program.MainForm.AppendTextBox("Device removed\r\n");

        }
    }

谢谢。

更新:对#Handbag Crab表示敬意!我可以使用他的方法而无需接触Program.cs。 :-)

在这种特殊情况下,有人还能告诉我如何正确使用事件/委托吗?

非常感谢,谢谢! :-)

2 个答案:

答案 0 :(得分:0)

代替:

Program.MainForm.AppendTextBox("Device removed\r\n");

使用:

Application.OpenForms.OfType<MainForm>().FirstOrDefault()?.AppendTextBox("Device removed\r\n");

Application.OpenForms是一个静态属性,使您可以访问在应用程序中打开的所有表单。

上面的linq行检查MainForm类型的OpenForms列表,然后提取第一个(如果存在),并在其上调用AppendTextBox。

?.运算符为您执行空检查。等效于以下代码:

MainForm form = Application.OpenForms.OfType<MainForm>().FirstOrDefault();
if (form != null)
    form.AppendTextBox("Device removed\r\n");

答案 1 :(得分:-1)

您需要使用参考词:阅读此链接https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ref

因此,在Form1的构造函数中,您可以像这样引用程序:

public Form1(ref Program myProgram){
    myProgram.MainForm.AppendTextBox("Device removed \r\n");
}

在Program.CS中,您可以添加以下内容:

static void Main()
{
    Program myProgram = this;

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    MainForm = new Form1(ref myProgram);

    Application.Run(MainForm);
}

希望它会有所帮助:)