首页 > 解决方案 > c# 从另一个类/事件更新 WinForm GUI 文本框

问题描述

我正在学习使用 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 之后,我设法按照此处的链接更新文本框。但是,它涉及修改 program.cs 文件。

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

我确实尝试过使用委托/事件等,但每次我都在我的主窗体 (Form1) 实例上遇到空引用异常。我肯定做错了什么。

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

程序.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 的情况下使用他的方法。:-)

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

干杯,非常感谢!:-)

标签: c#winformsdesktop-application

解决方案


代替:

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

采用:

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

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

上面的 linq 行检查 OpenForms 列表中是否有任何 MainForm 类型,然后拉出第一个(如果存在),并在其上调用 AppendTextBox。

操作员会?.为您进行空值检查。它相当于这段代码:

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

推荐阅读