none
Обращение к функции другой формы (Visual C++ .Net) RRS feed

  • Вопрос

  • Приветствую!

    Есть две формы: Form1 и Form2(Дочерняя). Необходимо из дочерней формы обратиться к функции родительской.

    Если обращаться к функции дочерней из родительской:

    frm2->set(a); то всё работает

    Если же обращаться к функции в родительской из дочерней, естественно предварительно прописав эту функцию, то это уже не работает.

    parentForm->get();

    get не является членом "System::Windows::Forms::Form" Что делать?

    25 сентября 2011 г. 18:08

Ответы

  • Сделаем изменение текста в форме1 из формы2:

    1) Имеются 2 формы - Form1 и Form2, на Form1 располагаются Button (button1, будет открывать вторую форму) и Label (label1, здесь будем менять текст). На Form2 - button1, по нажатию на которую будет происходить смена текста в label1.

    2) Так как нам из первой формы нужно иметь доступ ко второй, а из второй к первой, то будет возникать проблема перекрестных ссылок (когда Form1.h ссылается на Form2.h, который в свою очередь опять ссылается на Form1.h). Для того, чтобы этого избежать, код первой формы (Form1), который будет иметь доступ ко второй форме (Form2) мы вынесем из h-файла в cpp файл. Таким образом нужно создать файл Form1.cpp.

    3) Объявить открытый метод Set в Form1.h для того, чтобы можно было изменить текст label1:

        public: void Set(String^ text)
        {
            label1->Text = text;
        }
    

    4) В файле Form2.h подключаем Form1.h:

    #include "Form1.h"
    

    и создаем конструктор, который будет принимать и сохранять ссылку на первую форму для дальнейшего использования:

        Form2(Form1^ parent)
        {
            InitializeComponent();		
            parentForm = parent;
        }
    
        //...
    
        private: Form1^ parentForm;
    
    

    По клику кнопки, будем вызывать метод Set родительской формы:

        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
            parentForm->Set("hello from form2");
        }
    


    5) Осталось в первой форме сделать открытие второй формы. Для этого из Form1.h обработчик нажатия кнопки переносим в Form1.cpp, а в h-файле оставляем только его объявление:

    Form1.cpp:

        #include "StdAfx.h"
        #include "Form1.h"
        #include "Form2.h"
        namespace testApp {
            System::Void Form1::button1_Click(System::Object^  sender, System::EventArgs^  e) {
                Form2^ f2 = gcnew Form2(this);
                f2->Show();
                this->Hide();
            }
        }
    

    В Form1.h вставляем только:

        private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e);
    

    На этом все. Можно скомпилировать и проверить проект.

    Еще можно посмотреть обсуждение на зарубежном форуме по этой же проблеме - Submitting Form2 and changing Form1 by it's value


    Для связи [mail]
    • Помечено в качестве ответа AntiCamper 26 сентября 2011 г. 12:08
    26 сентября 2011 г. 8:36

Все ответы

  • Нужно подключить первую форму во вторую:

    #include "Form1.h"
    


    И вызывать ту функцию у экземпляра Form1.

    P.S. предвижу возникновение перекрёстных ссылок ;) ванга.жпг

    25 сентября 2011 г. 19:00
  • Сделаем изменение текста в форме1 из формы2:

    1) Имеются 2 формы - Form1 и Form2, на Form1 располагаются Button (button1, будет открывать вторую форму) и Label (label1, здесь будем менять текст). На Form2 - button1, по нажатию на которую будет происходить смена текста в label1.

    2) Так как нам из первой формы нужно иметь доступ ко второй, а из второй к первой, то будет возникать проблема перекрестных ссылок (когда Form1.h ссылается на Form2.h, который в свою очередь опять ссылается на Form1.h). Для того, чтобы этого избежать, код первой формы (Form1), который будет иметь доступ ко второй форме (Form2) мы вынесем из h-файла в cpp файл. Таким образом нужно создать файл Form1.cpp.

    3) Объявить открытый метод Set в Form1.h для того, чтобы можно было изменить текст label1:

        public: void Set(String^ text)
        {
            label1->Text = text;
        }
    

    4) В файле Form2.h подключаем Form1.h:

    #include "Form1.h"
    

    и создаем конструктор, который будет принимать и сохранять ссылку на первую форму для дальнейшего использования:

        Form2(Form1^ parent)
        {
            InitializeComponent();		
            parentForm = parent;
        }
    
        //...
    
        private: Form1^ parentForm;
    
    

    По клику кнопки, будем вызывать метод Set родительской формы:

        private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
            parentForm->Set("hello from form2");
        }
    


    5) Осталось в первой форме сделать открытие второй формы. Для этого из Form1.h обработчик нажатия кнопки переносим в Form1.cpp, а в h-файле оставляем только его объявление:

    Form1.cpp:

        #include "StdAfx.h"
        #include "Form1.h"
        #include "Form2.h"
        namespace testApp {
            System::Void Form1::button1_Click(System::Object^  sender, System::EventArgs^  e) {
                Form2^ f2 = gcnew Form2(this);
                f2->Show();
                this->Hide();
            }
        }
    

    В Form1.h вставляем только:

        private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e);
    

    На этом все. Можно скомпилировать и проверить проект.

    Еще можно посмотреть обсуждение на зарубежном форуме по этой же проблеме - Submitting Form2 and changing Form1 by it's value


    Для связи [mail]
    • Помечено в качестве ответа AntiCamper 26 сентября 2011 г. 12:08
    26 сентября 2011 г. 8:36
  • Вопрос. Если мы храним указатель на родительскую форму в Form2 и можем всегда обращаться к методам Form1, то обратная связь так не получается - мы объявляем указатель на дочернюю форму в обработчике. А как сохранить указатель на дочернюю форму для дальнейшего доступа к ней в других функциях?
    6 марта 2012 г. 11:55
  • Объявить его как поле класса формы Form1, а инициализировать уже в обработчике. А везде где используется проверять на null и на то, что форма еще существует.


    Для связи [mail]

    6 марта 2012 г. 12:03
  • Для того, чтобы объявить Form2 ^form; в классе Form1

    надо включить #include "Form2.h" в файл Form1.h, а у нас уже включён

    #include "Form1.h" в файл Form2.h - будет перекрёстная ссылка и ошибка.

    В приложении должна быть главная форма FormMain, определённая в файле FormMain.h

    этот файл включается #include в .h-файлы всех дочерних форм, классы которых хранят ссылку на родительскую форму (указатель на класс-родитель) как поле класса

    указатель на родительскую форму передаётся в конструкторе дочерних форм. Каждая дочерняя форма может обратиться к методам родительской через этот указатель.

    Если одна дочерняя форма хочет обратиться к другой дочерней форме, она должна вызвать метод родительской формы, который что-то сделает со второй, нужной дочерней формой. Но для этого родительская форма должна где-то хранить все указатели на все дочерние формы.

    Вот, допустим, как это происходит в Photoshop: в одном окне (Tools) мы выбираем нужный нам цвет кисти, и теперь он действует в другом окне (там где происходит рисование). Оба этих окна - дочерние по отношению к главному окну приложения (MDI-контейнеру). Как сделать нечто подобное?


    • Изменено donaire 7 марта 2012 г. 0:56
    7 марта 2012 г. 0:54
  • Можно реализовать через события.

    Можно вернуть значение через открытое поле (свойство).


    Для связи [mail]

    7 марта 2012 г. 8:57
  • Через события - через SendMessage? Стоило изобретать велосипед, создавать чуть ли не новый язык программирования, который всё равно ничего не может-))

    а через открытое поле опять таки надо объявлять указатель на класс и... всё с начала

    7 марта 2012 г. 9:09
  • Через события, которые Events.

    Ну или просто сделать между классами ссылки в обе стороны. Держите пример: https://bitbucket.org/pashapash/twoformssample/src

    13 марта 2012 г. 14:54
    Модератор