Добавление элементов управления в форму из другого класса - PullRequest
1 голос
/ 19 ноября 2010

У меня есть программа, которая создает один pictureBox в Form1, а затем создает экземпляр класса, который я назвал InitialState.InitialState помещает источник в изображение так, чтобы оно отображалось, и по прошествии некоторого времени, для которого я использовал таймер, он создает следующий класс, MainMenuState.Теперь в том классе MainMenuState, который я создал, я хотел бы создать еще один pictureBox и отобразить его в этой форме Form1.Позже я бы хотел немного изменить картинки внутри, а затем (возможно) уничтожить этот pictureBox.После этого программа переходит в следующее состояние (которое находится в еще одном классе), и я снова хотел бы, чтобы этот класс добавил графическую рамку к исходной форме и т. Д.

В принципе, я хотел быдинамически добавлять элементы управления в основную форму Form1, но не в указанной форме, а из классов, которые я создаю позже.Я искал в интернете способ сделать это, и, похоже, мне пришлось бы использовать делегата для вызова метода Controls.Add класса Form1.Я попробовал это, и код компилируется, но 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);
            }
        }

Как я уже сказал, код компилируется, но он не создает PictureBox a в Form1, когда создается MainMenuState.Дело в том, что если я не использую делегат в MainMenuState и просто пытаюсь сделать что-то вроде form.Controls.Add (a), то я получаю исключение «операция между потоками не действительна», и это недаже компилировать.Вот почему я использовал делегата, но даже сейчас он не работает.

Может кто-нибудь помочь мне?

Ответы [ 3 ]

1 голос
/ 19 ноября 2010

Боже мой, я только что нашел причину X_x

Это был тот факт, что поскольку первый pictureBox покрывал всю форму, а второй, созданный делегатом, показывал за это! Мне просто нужно вынести это на фронт!

Спасибо, ребята, тем не менее, я бы, наверное, не пришел к этому без вас.

Редактировать: Однако могу ли я спросить, как перенести этот контроль на фронт? Функция a.BringToFront () не работает.

1 голос
/ 19 ноября 2010
        initialTimer = new System.Timers.Timer(2500);

Это одна из причин, по которой у вас проблемы. Событие Elapsed запускается в потоке потоков, заставляя вас исполнять песню и танец BeginInvoke. Вместо этого используйте System.Windows.Forms.Timer, его событие Tick выполняется в потоке пользовательского интерфейса.

Вы также столкнетесь с проблемами управления памятью, эти классы должны реализовать IDisposable.

0 голосов
/ 19 ноября 2010

вместо

form.Invoke(del, new object[]{a});

попробовать:

form.Invoke(new ThreadStart(delegate
   {
      form.Controls.Add(a);
   }
));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...