Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Доступ к переменным внутри проекта


Автор: crang 2.6.2005, 16:36
Есть проект из двух форм, в первой определяются переменные для использования во второй . Пробовал объявить в первой форме, после объявления класса формы
Код

public class MainForm : System.Windows.Forms.Form
    {
                 public string someVar;
                ... 
                 }

и без "public" и с инициализацией и без:
Код

   public string someVar;
   //или
   string someVar;
   //или
   string someVar  =  "";


и вот из другой формы никак не могу найти эти someVar'ы smile
пытался обратиться напрямую по имени - говорит нет такого объекта в данном нэймспейсе, пробовал как к объекту главной формы - и там нету такого объекта smile

Код

public class Tunes : System.Windows.Forms.Form
    {
         public void someObject_Event(object sender, System.EventArgs e)
        {
                                     Form tmplnk = new MainForm();
                                     tmplnk.someVar 
             
        }
                 }


подскажите плз - как должно быть?

Автор: redrick 2.6.2005, 16:49
какие ошибки валятся ? сам объект создается ?

Автор: crang 2.6.2005, 17:10
Если в первой форме написать
Код

public class MainForm : System.Windows.Forms.Form
    {
    /// <summary>
    /// Required designer variable.
    /// </summary>
    public Form tunes = new Tunes();
    public string klbhost = "";
    public string klbuser = "";
    public string klbpass = "";
    public string klbpath = "";
......................
     }


а во второй
Код

public class Tunes : System.Windows.Forms.Form
       {
.............
         public void button1_Click(object sender, System.EventArgs e)
    {
            klbhost = txthost.Text;
            klbuser = txtuser.Text;
            klbpass = txtpass.Text;
                        klbpath = txtpath.Text;
            Form tmpfrm = new Tunes();
            tmpfrm.Close();
    }
        }

то пишет :
The name 'klbhost' does not exist in the class or namespace 'clbftp_daemon.Tunes'

Автор: simanyay 2.6.2005, 17:21
Ну дык ты же переменные класса создаешь в классе MainForm, а в методе button1_Click(...) класса Tunes ты пытаешься вызвать их, как если бы они были объявлены внутри класса Tunes. Это всё относилось ко второму примеру, поскольку первый я не очень понял smile

Автор: crang 2.6.2005, 17:27
simanyay
так об этом я и спрашиваю - а где их тогда объявлять чтоб было видно отовсюду?

Автор: simanyay 2.6.2005, 17:30
Код

public class MainForm : System.Windows.Forms.Form {
    // bla-bla
    
    public string klbhost = "";

    // bla-bla
}

public class Tunes :  System.Windows.Forms.Form {
    // bla-bla

    public void button1_Click(object sender, System.EventArgs e) {
        // Если объект класса MainForm не был создан заранее, то создай его
        MainForm myform = new MainForm();
        string host = myform.klbhost; // Должно работать
    }

    // bla-bla
}


А вообще лучше тебе создать свойства для public переменных. ИМХО, все переменные должны быть закрыты, а доступ к ним должен быть только из методов или свойств.

Цитата(crang @ 2.6.2005, 19:27)
simanyay
так об этом я и спрашиваю - а где их тогда объявлять чтоб было видно отовсюду?


А вот глобальных переменных в C#, насколько я знаю, нет. Что и правильно.

Ещё почитай вот это: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vclrftypesaccessmodifiers.asp

Автор: Kurt 2.6.2005, 18:24
Цитата(simanyay)
    public void button1_Click(object sender, System.EventArgs e) {
        // Если объект класса MainForm не был создан заранее, то создай его
        MainForm myform = new MainForm();
        string host = myform.klbhost; // Должно работать
    }

Думаю, это не будет работать.
Этим кодом ты во второй форме создаешь ДРУГОЙ объект класса MainForm, к-й будет иметь СВОИ значения соотв. полей.
Как я понимаю, задача сводится к следующему:
есть две формы. Form1 вызывает Form2. Причем в Form2 нужно получить значение некоторого поля из Form1.
Я бы решил эту задачу так.
1) объявил бы private-переменную в классе Form1:
Код
private int _someValue = 777;

2) написал бы Property для доступа у этому полю:
Код

        public int SomeValue
        {
            get{return this._someValue;}
            set{this._someValue = value;}
        }

3) В классе Form2 создал бы конструктор, к-й бы в качестве входного параметра принимал ссылку на Form1:
Код

public class Form2 : Form{
  private Form1 _frm1; //будет хранить ссылку на экземпляр класса Form1, создавшего этот класс

        public Form2(Form1 frm1)
        {
                           .....
            this._frm1 = frm1;
        }
}

4) Все. Теперь я могу обращаться к полям первой формы:
Код

    this.label1.Text = this._frm1.SomeValue.ToString(); //просто пример


З.Ы. Кстати, в Java то же самое.

Автор: Tomcat 2.6.2005, 18:25
Цитата(simanyay @ 2.6.2005, 16:30)
А вот глобальных переменных в C#, насколько я знаю, нет. Что и правильно.

Свои пять копеек...

Для этих целей в ООП обычно используют открытые статические переменные.

Вот хорошая конструкция Singleton-класса (класса, для которого может существовать только один экземпляр объекта). Грубо говоря, глобальная переменная строго определенного типа.
Код

    public sealed class SingletonClass1
    {
        private static SingletonClass1 instance = new SingletonClass1();
        
        public static SingletonClass1 Instance {
            get {
                return instance;
            }
        }
        
        private SingletonClass1()
        {
        }
    }

Автор: simanyay 2.6.2005, 18:31
Цитата(Kurt @ 2.6.2005, 20:24)
есть две формы. Form1 вызывает Form2. Причем в Form2 нужно получить значение некоторого поля из Form1.


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

Автор: crang 3.6.2005, 10:09
Ух уж это ООП..

Kurt
Спасибо за разъяснение, технологию я понял.

Простите за невнятное описание проблемы - учусь ведь вот smile

Автор: Дрон 3.6.2005, 12:38
Цитата(crang @ 3.6.2005, 11:09)
Ух уж это ООП..

Вообще, то что ты делаешь это очень плохо. Дочерняя форма не должна зависеть от родительской... Но это уже детали smile

Автор: crang 3.6.2005, 15:11
Дрон
я это уже понял - использую tabControl

Автор: Zdvig 4.9.2005, 14:30
Как к textBox первой формы присвоить значение textBox воторой формы. У первого текстового поля видимость выставлена public. Ни одн из вышеперечисленных способов не помогает...
То же отностится и к текстовым переменным. Во всех случаях они возвращают пустоту, вместо строки...

Автор: Kurt 4.9.2005, 14:37
Цитата
То же отностится и к текстовым переменным. Во всех случаях они возвращают пустоту, вместо строки...

А ну, покажи как ты это делаешь. Есессно, убрав не относящиеся к делу строчки. smile

Автор: Zdvig 4.9.2005, 15:13
Цитата(Kurt @ 4.9.2005, 14:37)
А ну, покажи как ты это делаешь. Есессно, убрав не относящиеся к делу строчки. smile

Использую компонент GmailNotifierControl с CodeProject.com, но не как отдельную dll, а интегрированный в мой проект.

Из ннего:

Делаю экземпляр класса Form1.

Код

namespace GmailNotifierControl
{
    public class GmailNotifierInfo : System.Windows.Forms.Form
    {    
        #region DesignTimeMembers
        ...
        private WindowsApplication3.Form1 frm1;
        #endregion
...


Далее в программе:

Код


private void lblInfo_Click(object sender, System.EventArgs e)
        {
            frm1 = new WindowsApplication3.Form1();
            MessageBox.Show(frm1.Message1); // не показывает ничего!
        }

Автор: mr.DUDA 4.9.2005, 15:28
Цитата(Zdvig @ 4.9.2005, 15:13)
#region DesignTimeMembers
...
private WindowsApplication3.Form1 frm1;
#endregion

Вот это интересно. Какой тут может быть "design time" ? В дизайнере добавил на свой GmailNotifierControl форму, что ли ? Если да, посмотри InitializeComponent, может там экземпляр формы уже создаётся автоматически, и код:

Цитата(Zdvig @ 4.9.2005, 15:13)
private void lblInfo_Click(object sender, System.EventArgs e)
{
frm1 = new WindowsApplication3.Form1();

просто создаёт ещё одну форму, не относящуюся к делу.

Автор: Kurt 4.9.2005, 15:42
Zdvig
Постарайся все-таки сделать так, как я http://forum.vingrad.ru/index.php?showtopic=54207&view=findpost&p=430124. То есть передавай ссылку на форму через конструктор, а не создавай еще одну форму.


Автор: Zdvig 4.9.2005, 15:59
Я так пробовал, уже просто незнаю что делать.... Конструкции типа private Form1 frm1 и дальнейшее обращение к frm1 вообще не работают. Пишет не найден Form1 в неймспейсе. smile smile smile


Выкладываю всю программу, может посмотрите что так как. Я просто бессилен тут....

Автор: mr.DUDA 4.9.2005, 17:38
Держи, вот твоя программа с исправлениями:

Автор: Zdvig 4.9.2005, 18:26
Значит все беда была из за

Код

frm1 = new WindowsApplication3.Form1();


Меня щас расплющит от моего ламерства smile



mr.DUDA
Спасибо тебе огромное!!

Автор: mr.DUDA 4.9.2005, 20:45
Да нет, просто ты форму создавал по новой, хотя форма уже была. Контрол твой "NotifierInfo" нужно было создавать конструктором, принимающим параметр типа "форма" со значением, указывающим родительскую форму:
Код
public Form1()
{
    InitializeComponent();
    NotifierInfo1 = new NotifierControl.NotifierInfo(this);
}


соответственно:
Код
public NotifierInfo(WindowsApplication3.Form1 formParent)
{
    InitializeComponent();
    this.frm1 = formParent;
}


и далее, обработчик события "клик по label1 внутри балуна NotifierInfo" должен не создавать новый объект "форма", а использовать реально существующий, т.е. тот который был передан в параметре конструктора NotifierInfo:

Код
private void lblInfo_Click(object sender, System.EventArgs e)
{
    MessageBox.Show(frm1.SomeValue);
    // никаких других действий типа this.frm1=new Form() не нужно !
}

Автор: Zdvig 4.9.2005, 20:56
Код

public NotifierInfo(WindowsApplication3.Form1 formParent)    
{    
    InitializeComponent();    
    this.frm1 = formParent;    
}


Этого я даже предположить не мог smile

PS: сложно как-то в C# обстоят дела с доступом к переменным. smile

Автор: mr.DUDA 4.9.2005, 23:14
Да всё логично.
В конструктор подчинённого объекта передаётся ссылка на вышестоящий объект. Далее подчинённый объект (NotifierInfo) общается с вышестоящим (Form1) только через эту ссылку.

Почему ? Ну представь себе, к примеру, такой случай. Есть дерево, состоящее из узлов. Узлами в дереве являются объекты. Друг о друге они почти ничего не знают, и не должны, т.к. в дереве порядок следования объектов - совершенно произвольный. Теперь попробуй сделать так, чтобы объекты могли взаимодействовать между собой. Как организовать связи между вышестоящими и подчинёнными объектами ? Естественным решением является наличие в объекте таких полей как Parent и Children. В твоём примере тоже как бы дерево, но состоящее всего из двух узлов - Form1 и NotifierInfo.

Ну а теперь самое главное: откуда узел "NotifierInfo" узнаёт об узле "Form1", который для него как-бы Parent ? Другими словами, как получить информацию для сохранения в поле Parent (у тебя это NotifierInfo.frm1) ? Открыть свойство Parent на запись всему миру ? Это абсолютно неприемлемо с точки зрения объектно-ориентированного программирования, потому что такое свойство инкапсулировано в объекте и внешнему миру должно быть открыто только для чтения !

Вот поэтому и приходим к такой парадигме: если у объекта есть данные, которые инициализируются один раз при создании объекта, эти данные должны быть проинициализированы в конструкторе (явно либо неявно). Отсюда и вытекает код, принимающий в конструкторе NotifierInfo ссылку на форму и сохраняющий эту ссылку в поле frm1.

P.S. надеюсь, понятно объяснил smile

Автор: Zdvig 5.9.2005, 15:28
mr.DUDA

Ага, пример удачный smile Теперь буду воплощать это в жизнь, чтобы закрепить smile

Автор: xsb3 2.12.2006, 03:16
Народ вот ссылка на мой проект. http://xsb3.ifolder.ru/544137 в нем необходимо из формы 1 вызвать форму 2
в форме 2 есть поля textBox.  находящийся текст в которых должен после нажатия кнопки ОК записаться в listView формы 1. 
Если кто сможет исправить выложите потом ссылку на фаилы наверно всем пример будет интересен.

Автор: Дрон 2.12.2006, 11:41
Цитата(xsb3 @  2.12.2006,  03:16 Найти цитируемый пост)
Если кто сможет исправить выложите потом ссылку на фаилы наверно всем пример будет интересен. 

Модератор: А почитать эту и закреплённые в этом разделе темы не пробовал?
Я так смотрю у тебя в том проекте ничего не сделано.
А всё интересное уже было в теме http://forum.vingrad.ru/topic-52713.html

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)