我有一个程序,它在Form1中创建一个pictureBox,然后创建一个我称为InitialState的类的实例。 InitialState将源放到Image中以便显示它,经过一段时间后,我使用了Timer,它创建了下一个类MainMenuState。现在,在我创建的MainMenuState类中,我想创建另一个pictureBox并使其显示在该Form1上。后来,我想让它里面的图片改变一点,然后(可能)破坏那个pictureBox。之后,程序进入下一个状态(在另一个类中),并且我希望该类将图片框添加到原始表单中,依此类推。
基本上,我想动态地将控件添加到主Form1,但不是在所述表单中,而是从我稍后创建的类中添加。我一直在互联网上寻找一种方法来做到这一点,似乎我必须使用委托才能调用Form1类的Controls.Add方法。我试过了,代码编译了,但是pictureBox仍然没有显示出来。
这是我的代码:
Form1类:
public const string RESOURCE_PATH = "C:/Users/Noel/Documents/Visual Studio 2010/Projects/A/Resources/Animations/"; public Form1() { InitializeComponent(); //here, the first pictureBox shows iInitializeComponent(); zacetnaAnimacija.Dock = DockStyle.Fill; //zacetnaAnimacija is the first pictureBox that appears zacetnaAnimacija.Anchor = AnchorStyles.Top | AnchorStyles.Left; zacetnaAnimacija.SizeMode = PictureBoxSizeMode.StretchImage; InitialState intialState = new InitialState(this, zacetnaAnimacija); //entering InitialState }
InitialState类:
class InitialState : State { System.Timers.Timer initialTimer; PictureBox pictureBox1; Form1 form; public InitialState (Form1 form, PictureBox pictureBox1) { this.form = form; GifImage zacetnaSlika = new GifImage(Form1.RESOURCE_PATH + "Presenting.gif"); //this is just a .gif picture I'm displaying Image trenutnaSlika = zacetnaSlika.GetFrame(0); //a method that plays the .gif pictureBox1.Image = trenutnaSlika; //makes the first .gif display this.pictureBox1 = pictureBox1; initialTimer = new System.Timers.Timer(2500); initialTimer.Enabled = true; initialTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); } private void OnTimedEvent(object source, ElapsedEventArgs e) { initialTimer.Enabled = false; MainMenuState menuState = new MainMenuState(form, pictureBox1); //enters main menu state with the Form1 argument passed on }
MainMenuState类:
class MainMenuState : State { Form1 form; public MainMenuState (Form1 form, PictureBox pictureBox1) { this.form = form; GifImage zacetnaSlika = new GifImage(Form1.RESOURCE_PATH + "animated.gif"); Image trenutnaSlika = zacetnaSlika.GetFrame(0); pictureBox1.Image = trenutnaSlika; //this simply makes another .gif appear in the picture box instead of the first one PictureBox a = new PictureBox(); //HERE'S my problem, when I want to add ANOTHER pictureBox to that form. a.BackgroundImage = trenutnaSlika; a.Location = new System.Drawing.Point(0, 0); a.Name = "zacetnaAnimacija"; a.Size = new System.Drawing.Size(150, 150); a.TabIndex = 1; a.TabStop = false; AddControl(a); //calling the delegate } public delegate void AddControls(PictureBox a); public void AddControl(PictureBox a) { if (form.InvokeRequired) { AddControls del = new AddControls(AddControl); form.Invoke(del, new object[] { a }); } else { form.Controls.Add(a); } }
正如我所说,代码编译,但是当创建MainMenuState时,它不会在Form1上创建PictureBox。问题是,如果我不在MainMenuState中使用委托,只是尝试做类似form.Controls.Add(a)的事情,那么我得到一个“跨线程操作无效”异常,它不会甚至编译。这就是我使用代表的原因,但即使是现在,它也无效。
有人可以帮帮我吗?
答案 0 :(得分:1)
天啊,我刚刚找到了原因X_x
事实是,由于第一个pictureBox覆盖了整个表单,而第二个是由代表创建的,显示在后面它!我只需要把它带到前面!
谢谢你们,尽管如此,如果没有你,我可能不会那么做。
编辑:不过,请问如何将控件带到前面? a.BringToFront()函数似乎不起作用。
答案 1 :(得分:1)
initialTimer = new System.Timers.Timer(2500);
这是你遇到麻烦的部分原因。 Elapsed事件在线程池线程上运行,强制您进行BeginInvoke歌曲和舞蹈。使用System.Windows.Forms.Timer,它的Tick事件在UI线程上运行。
你也会遇到内存管理问题,这些类需要实现IDisposable。
答案 2 :(得分:0)
而不是
form.Invoke(del, new object[]{a});
尝试:
form.Invoke(new ThreadStart(delegate
{
form.Controls.Add(a);
}
));