从C#代码更改图片框可见性

从C#代码更改图片框可见性,c#,multithreading,forms,picturebox,C#,Multithreading,Forms,Picturebox,所以我尝试创建一个新的表单并引用它…编译器并不介意,但它显然没有改变我picturebox的可见性。这就是我调用表单中的方法的方式,从我的c#脚本 它称之为方法,而且似乎有效!直到我读到一篇关于实例化表单的文章,以及如何通过创建Form1的“新”实例,我的updateForm引用的任何内容都不会改变我在Form1上看到的内容 因此,我需要做的是在我的表单1中调用setLights()中的函数,并让它从我的C#代码更改该表单上我的图像的可见性。请参见下面的内容(我理解上面提到的实例化问题,但我将其

所以我尝试创建一个新的表单并引用它…编译器并不介意,但它显然没有改变我picturebox的可见性。这就是我调用表单中的方法的方式,从我的c#脚本

它称之为方法,而且似乎有效!直到我读到一篇关于实例化表单的文章,以及如何通过创建Form1的“新”实例,我的updateForm引用的任何内容都不会改变我在Form1上看到的内容

因此,我需要做的是在我的表单1中调用setLights()中的函数,并让它从我的C#代码更改该表单上我的图像的可见性。请参见下面的内容(我理解上面提到的实例化问题,但我将其保留了下来,希望它能更好地了解我“尝试”做什么:)另外,请记住,setLightCall()是在一个单独的线程中运行的。提前谢谢

这段代码也在我的主c#脚本中,是我用来调用线程的主要函数

static void Main(string[] args)
    {
        Thread FormThread = new Thread(FormCall);
        FormThread.Start();

        Thread setLightThread = new Thread(setLightCall);
        setLightThread.Start();

        log4net.Config.XmlConfigurator.Configure();
        StartModbusSerialRtuSlave();
    }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;

namespace ConsoleApplication59
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread FormThread = new Thread(FormCall);
            FormThread.Start();

            Thread.Sleep(2000); //Sleep to allow form to be created

            Thread setLightThread = new Thread(setLightCall);
            setLightThread.Start(Application.OpenForms[0]); //We can get by with this because just one form

            Console.ReadLine();

        }

        public static void setLightCall(object parent)
        {
            Form1 updateForm = (Form1)parent;
            while (true)
            {
               updateForm.Invoke(updateForm.setLights, new object[] { false });

            }

        }

        public static void FormCall()
        {
            Application.Run(new Form1());

        }
    }
}
这段代码在我的主C#脚本中

public  void setLightCall(Form1 parent)
    {
        Form1 updateForm = new Form1();
        while(true)
        {
            updateForm.setLights();

        }


    }
以下代码是我的表格1

public void setLights()
    {
        Input1GreenLight.Visible = false;
    }
public partial class Form1 : Form
{
    public delegate void Lights(bool state);
    public Lights setLights;
    public Form1()
    {
        InitializeComponent();
        setLights = new Lights(setLightsDelegate);
    }




    public void setLightsDelegate(bool state)
    {
        Input1GreenLight.Visible = state;
    }

}

这是一个我认为你想要尝试的例子。注意调用和委托的使用,以便能够访问PictureBox的Visible方法。我必须将System.Windows.Forms命名空间添加到控制台应用程序中,以便能够访问在FormThread方法中创建的表单实例,这是假设您的FormCollection中只有1个表单

Program.cs

static void Main(string[] args)
    {
        Thread FormThread = new Thread(FormCall);
        FormThread.Start();

        Thread setLightThread = new Thread(setLightCall);
        setLightThread.Start();

        log4net.Config.XmlConfigurator.Configure();
        StartModbusSerialRtuSlave();
    }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Windows.Forms;

namespace ConsoleApplication59
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread FormThread = new Thread(FormCall);
            FormThread.Start();

            Thread.Sleep(2000); //Sleep to allow form to be created

            Thread setLightThread = new Thread(setLightCall);
            setLightThread.Start(Application.OpenForms[0]); //We can get by with this because just one form

            Console.ReadLine();

        }

        public static void setLightCall(object parent)
        {
            Form1 updateForm = (Form1)parent;
            while (true)
            {
               updateForm.Invoke(updateForm.setLights, new object[] { false });

            }

        }

        public static void FormCall()
        {
            Application.Run(new Form1());

        }
    }
}
表格1

public void setLights()
    {
        Input1GreenLight.Visible = false;
    }
public partial class Form1 : Form
{
    public delegate void Lights(bool state);
    public Lights setLights;
    public Form1()
    {
        InitializeComponent();
        setLights = new Lights(setLightsDelegate);
    }




    public void setLightsDelegate(bool state)
    {
        Input1GreenLight.Visible = state;
    }

}

你是如何将表单引用传递给setLightCall方法的?我不确定我是否在回答你的问题,但我正在通过我的主c#脚本传递它,并且setLightCall正在从我的主方法调用。你能展示你用来调用方法的代码吗?下一步,你不能启动WinForms程序(这就是为什么,不是吗?)只需在Main()方法中实例化一个表单。您需要通过调用Application.Run()启动Windows消息泵。但这通常不是你自己在程序中写的。如果您使用VisualStudio创建一个新的WinForms项目,那么VisualStudio会自动为您的项目创建所有的锅炉板代码。除非这对你来说是不可能的,否则这就是出路。即使这在您的项目中是不可能的,但如果您创建了一个这样的项目来进行研究也会有所帮助。最后,正如您所意识到的,使用WinForms时存在多线程限制。修改WinForms UI控件的所有代码都必须在UI线程上运行(通常为零线程)。因此,当您需要从另一个线程上运行的代码更改WinForms控件时,需要使用WinForms Invoke()或BeginInvoke()方法。在互联网上有很多关于如何做到这一点的信息。这里有一个链接让你开始:非常感谢你花时间提供这个精彩的例子!!你是一个a级演员,老实说,我在示例中看到了你的代码片段,这些代码与我正在尝试做的事情有关。虽然我不能立即检查,但我明天一定会尝试。C#对我来说是新的,因为我已经习惯了C/C++,但多亏了像你这样的人,我可以继续努力,让我的头脑围绕着这种简洁的语言。我明天会试试并跟进。马克,我刚刚实现了你的代码,它工作得非常完美,我非常感谢你。很明显,我需要更多地阅读调用/委托…感谢您的评论。我很高兴代码为您工作。