Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как обратиться к объекту другой формы, очень часто задаваемый вопрос 
V
    Опции темы
mr.DUDA
Дата 14.8.2006, 10:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



Цитата(Сергей Плоткин @  13.8.2006,  22:13 Найти цитируемый пост)
 Т.е. даже свойство "Name" у формы (допустим Form1) в дизайн-тайм - это имя не класса, а именно экземпляра класса TForm1. А класс TForm1 (наследник TForm) создает автоматом. К такому-то принципу я и привык.

Всё понятно. Класс называется TForm1, а экземпляр - Form1. Переменная экземпляра формы, наверно, даже где-то объявлена smile, поэтому можно к ней обращаться из кода. Всё, что заполняется в дизайнере и Properties-ах, автоматом кладётся в исходник и ресурсы, насколько мне помнится из общения с делфями.

В WinForms похожий подход, дизайнером тоже создаётся специальный метод InitializeComponent, в который кладётся всё, что мы дизайним и настраиваем в Properties. Вот только экземпляр типа Form1 не создаётся автоматически - мы должны позаботиться об этом сами, т.к. изначально есть возможность создать много экземпляров одного класса (TForm1). К примеру, главная форма приложения создаётся в методе Main():
Код
Application.Run(new Form1());


Конечно, дельфисту поначалу это может показаться непривычным, но со временем привычки изменятся, и всё станет на свои места smile.

З.Ы. можно в принципе замутить статик-переменную с экземпляром формы, заполнять её в конструкторе формы, и тогда вполне можно обратиться к формам так (при условии, что указанная форма существует в данный момент времени):
Код
Form1.Instance.textBox1.Text = "bla-bla-bla";

или так:
Код
((Form1)Application.OpenForms["Form1"]).textBox1.Text = "bla-bla-bla";


НО однозначно более правильным способом остаётся передача экземпляра одной формы в конструктор другой.


--------------------
user posted image
PM MAIL WWW   Вверх
3me1
Дата 14.8.2006, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 14.8.2006
Где: Киев, Украина

Репутация: нет
Всего: нет



Все предельно просто.
создаем в классе формы указатель на "родительскую" форму

public class ChildForm
{
        private ParentForm parentForm;
        ///ctor
         public child(ParentForm link)
        {
              this.parentForm=link;
        }
 .................
}

вот и все...
теперь создаем э.ф.

...
{
       ChildForm childForm=new ChildForm(this);
       childForm.Show();
}

и соответственно обращаемся к родителю просто 
parentForm. ....;
PM MAIL   Вверх
mr.DUDA
Дата 14.8.2006, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



3me1, это то о чём неоднократно говорилось:  smile 
Цитата(mr.DUDA @  14.8.2006,  10:50 Найти цитируемый пост)
передача экземпляра одной формы в конструктор другой




--------------------
user posted image
PM MAIL WWW   Вверх
kobra
Дата 14.8.2006, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: нет
Всего: 9



Цитата(mr.DUDA @  14.8.2006,  10:50 Найти цитируемый пост)
Всё понятно. Класс называется TForm1, а экземпляр - Form1. Переменная экземпляра формы, наверно, даже где-то объявлена , поэтому можно к ней обращаться из кода.
в принципе одно и тоже, просто в делфиях чуть упрощено, вот и все.
в этои теме несколько раз прозвучало что компоненти входящие в состав формы нужно осавлять приватними, а для работы с ними писать своии паблик методы. честно говоря я в первые такое слышу. может обясните почему так? если по мне, ето не совсем правилно, из однои формы часто управляю елементами на другои форме. и зачем писать при етом собственные методы, когда ети методы уже есть?

PM MAIL   Вверх
ivashkanet
Дата 14.8.2006, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



Цитата(kobra @  14.8.2006,  15:00 Найти цитируемый пост)
в этои теме несколько раз прозвучало что компоненти входящие в состав формы нужно осавлять приватними, а для работы с ними писать своии паблик методы. честно говоря я в первые такое слышу. может обясните почему так? если по мне, ето не совсем правилно, из однои формы часто управляю елементами на другои форме. и зачем писать при етом собственные методы, когда ети методы уже есть?

kobra, есть принцип ООП -- инкапсуляция называется. Звучит он примерно так: Никакие данные внутри класса изменять нельзя. Можно только попросить класс изменить что-то, и если эти изменения согласуются с внутренней политикой класса, то он их сделает.
Определение, конечно, бестолковое, но суть проясняет smile
Например тебе в классе формы хочется, чтобы в ее заголовке отображалось содержимое некоторого текстБокса. Если теперь напрямую поменять значение текстбокса, то не факт что форма его подхватит.
Конечно можно подписаться на событие смены текста в текстбоксе. Но это только пример  smile  
PM MAIL WWW ICQ   Вверх
kobra
Дата 14.8.2006, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: нет
Всего: 9



Цитата(ivashkanet @  14.8.2006,  15:13 Найти цитируемый пост)
есть принцип ООП -- инкапсуляция называется
 на счет инкапсулации все понятно. и пример твои вполне коректен. так как загаловок формы это своиство класа формы. 
я спрашиваю про то что менять например текст текстбокса расположенного на форме. в подобнои теме недавно было, что законы ООП и инкапсулация требуют создать метод класса формы. 
но по моему текстбокс не входит в клас формы, он ползуится этим класом как контеинером. и исходя из этого нужно работать с ним напримую а не через клас формы (правда при этом приходится указывать какои егземпляр формы содержит этот текстбокс, но кажется эта другая песня). 

PM MAIL   Вверх
ivashkanet
Дата 14.8.2006, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



Цитата(kobra @  14.8.2006,  16:57 Найти цитируемый пост)
инкапсулация требуют создать метод класса формы

Вот именно (кстати свойство --- это тот же метод, только синтаксис другой).
Когда ты кидаешь на форму текстБокс. Ты получаешь новый класс -- твоя форма, а не отдельно класс и отдельно форму. И поэтому лучше обращаться ко всему классу. Хотя удобнее к его компоненту. 
Хорошо когда ты сам писал класс формы и знаешь его внутреннюю кухню. А если нет. Даже на простом примере (см. предыдущий пост) видно, что лучше такого не допускать.

Но с другой стороны. Принципы ООП, ИМХО, жестко относятся только к повторно используемому коду. Если ты точно знаешь, что твоим классом никто не воспользуется (например кому нужна форма с конретным положением конкретных элементов на ней), то на ООП можно забить  smile
PM MAIL WWW ICQ   Вверх
kobra
Дата 14.8.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: нет
Всего: 9



Цитата(ivashkanet @  14.8.2006,  17:14 Найти цитируемый пост)
Когда ты кидаешь на форму текстБокс. Ты получаешь новый класс -- твоя форма, а не отдельно класс и отдельно форму.
99% всех форм, которые я делаю, мне нужны не как клас, а как один егземпляр (ну не совсем правилно выразился но надеюс поимете), так что
Цитата(ivashkanet @  14.8.2006,  17:14 Найти цитируемый пост)
Если ты точно знаешь, что твоим классом никто не воспользуется (например кому нужна форма с конретным положением конкретных элементов на ней), то на ООП можно забить   smile 
я о том же smile  


PM MAIL   Вверх
3me1
Дата 15.8.2006, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 14.8.2006
Где: Киев, Украина

Репутация: нет
Всего: нет



Цитата
 3me1, это то о чём неоднократно говорилось:    

сорри smile я завтыкал smile
PM MAIL   Вверх
mr.DUDA
Дата 15.8.2006, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232




M
mr.DUDA
Тема закреплена.

Все аналогичные вопросы будут перенаправляться в эту тему, с автоматическим закрытием исходной темы.



--------------------
user posted image
PM MAIL WWW   Вверх
Colloseum
Дата 2.9.2006, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 71
Регистрация: 4.7.2006

Репутация: нет
Всего: нет



При открытии понятно.
Код

        Form EP;
        EP = new ExtendedParams();
        EP.textBox1.Text = "111";
        EP.ShowDialog();


А наоборот..
При закрытии окна нужно передать данные(из textBox'a) в другую форму.

PM MAIL   Вверх
marcusmae
Дата 2.9.2006, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Цитата

При закрытии окна нужно передать данные(из textBox'a) в другую форму.


Colloseum,
классическое решение - то, что называется callback, обратный вызов, или делегат в C#.
Можно, например, создать класс

Код

public static class CallBack
{
    public delegate void callbackEvent(string textFromTextBox);
    public static callbackEvent callbackEventHandler;
}


Далее, в форме, которая должна получать текст из диалога, инициализировать слушателя события callbackEvent :

Код

...
public string textBoxText;
...
// инициализацию можно поместить, например, в конструктор
public Form1()
{
    ...
    CallBack.callbackEventHandler = new Callback.callbackEvent(this.getText);
    ...
}
...
// функция-обработчик
private void getText(string textReturnedFromDialog)
{
    // нужная функциональность, допустим, запись в поле класса
    this.textBoxText = textReturnedFromDialog;
}



А в диалоге при его закрытии создавать событие :

Код

...
Callback.callbackEventHandler(textBox.Text);
...


Таким образом, при закрытии диалога произойдёт событие, аргумент которого - текст из TextBox'a. Другая форма зарегестрировалась на прослушку этого события, поэтому вызовется обработчик getText, в параметре которого и будет долгожданый текст.

Показанная конструкция - наиболее общая : делегат и его тип находятся в отдельном классе. Конечно, всегда лучше, если они находятся в одном из использующих классов. Всё зависит от того, как ты хочешь организовать программу.

Это сообщение отредактировал(а) marcusmae - 2.9.2006, 20:36


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
reloni
Дата 2.9.2006, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 10.5.2006
Где: Москва

Репутация: нет
Всего: 4



Есть, на мой взгляд, более простое решение.
Есть две формы: MainForm - главная форма, и Form1 - форма, из которой нужно вытащить данные.
Кидаем на вторую форму текст-бокс и кнопку. Пишем своиство:
Код

public string TextInTextBox
{
    get { return this.textBox1.Text; }
}

Обработчик нажатия на кнопку:
Код

private void button1_Click(object sender, EventArgs e)
{
    this.DialogResult = DialogResult.OK;
}

Ну и на главной форме кнопка, по нажатию на которую создается Form1:
Код

private void button1_Click(object sender, EventArgs e)
{
    Form1 frm = new Form1();
    if (frm.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show(frm.TextInTextBox);
    }
}

Смотрим, что за DialogResult нам вернули, и если это ОК, то в мессаджбоксе видим то, что было введено в текстбокс в дочерней форме.

Это сообщение отредактировал(а) reloni - 2.9.2006, 22:18
PM MAIL ICQ   Вверх
marcusmae
Дата 2.9.2006, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 5
Всего: 39



Если уж на то пошло, DialogResult тут, по-моему, мало нужен. Достаточно будет создать public - поле/свойство с текстом в форме и отправлять туда текст при закрытии диалога.
Думаю, ничто не мешает вообще переопределить в наследуемом классе DialogResult, сделать его string и возвращать текст. Да вот только, всё это будет работать только когда возвращать нужно туда же, откуда диалог вызвали... 

В любом случае, речь идёт о степени корявости кода программы, которую разработчики могут увеличивать до тех пор, пока программа не начнёт казаться интеллектуальной по части разнообразия возникающих ошибок. Общепринятый подход к созданию корявости - это, всё-таки, делегаты  smile 


Это сообщение отредактировал(а) marcusmae - 3.9.2006, 01:13


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
reloni
Дата 2.9.2006, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 10.5.2006
Где: Москва

Репутация: нет
Всего: 4



marcusmae, это если нужно выполнять какие-то действия если результ ОК, а другие, если он Cancel допустим. А про делегаты спасибо, не зналsmile
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1819 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.