从C#代码更改图片框可见性
所以我尝试创建一个新的表单并引用它…编译器并不介意,但它显然没有改变我picturebox的可见性。这就是我调用表单中的方法的方式,从我的c#脚本 它称之为方法,而且似乎有效!直到我读到一篇关于实例化表单的文章,以及如何通过创建Form1的“新”实例,我的updateForm引用的任何内容都不会改变我在Form1上看到的内容 因此,我需要做的是在我的表单1中调用setLights()中的函数,并让它从我的C#代码更改该表单上我的图像的可见性。请参见下面的内容(我理解上面提到的实例化问题,但我将其保留了下来,希望它能更好地了解我“尝试”做什么:)另外,请记住,setLightCall()是在一个单独的线程中运行的。提前谢谢 这段代码也在我的主c#脚本中,是我用来调用线程的主要函数从C#代码更改图片框可见性,c#,multithreading,forms,picturebox,C#,Multithreading,Forms,Picturebox,所以我尝试创建一个新的表单并引用它…编译器并不介意,但它显然没有改变我picturebox的可见性。这就是我调用表单中的方法的方式,从我的c#脚本 它称之为方法,而且似乎有效!直到我读到一篇关于实例化表单的文章,以及如何通过创建Form1的“新”实例,我的updateForm引用的任何内容都不会改变我在Form1上看到的内容 因此,我需要做的是在我的表单1中调用setLights()中的函数,并让它从我的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++,但多亏了像你这样的人,我可以继续努力,让我的头脑围绕着这种简洁的语言。我明天会试试并跟进。马克,我刚刚实现了你的代码,它工作得非常完美,我非常感谢你。很明显,我需要更多地阅读调用/委托…感谢您的评论。我很高兴代码为您工作。