odwołanie sie do obiektu klasy z innej formy

0

Jakos nie znalazłem na tym forum wiec pytam:)
Mam obiekt mojej klasy zadeklarowany i utworzony na Form1
Form1.cs

public partial class Form1 : Form
    {
        public DataBase LocalBase;

         (...)
     
    private void Form1_Load(object sender, EventArgs e)   
     {
          LocalBase= new DataBase();
      }

   }

Jak teraz odwolac sie do tego konkretnego obiektu z Form2?
Cos takiego mi nie dziala
Form2.cs

public innafunkcja()
{
    Form1 F= new Form1();
    F.LocalBase.jakasFunkcjaZDataBase();
}
0

Nie jest to takie proste. Ale można sobie poradzić w inny sposób:

Załóżmy, że mamy taką klasę:

 public class CMyClass
    {
        private string Parameter;
        public CMyClass(string parameter)
        {
            this.Parameter = parameter;
        }
        public void MyMethod()
        {
            MessageBox.Show(this.Parameter);
        }
    }

Obiekt tej klasy znajduje się w Form1:

    public partial class Form1 : Form
    {
        CMyClass MyObject;
        public Form1()
        {
            InitializeComponent();
            MyObject = new CMyClass("Value of parameter");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 frm = new Form2(MyObject);
            frm.Show();
        }
    }

Obiekt przekazujesz w konstruktorze Form2 i wołasz jego metody:

    public partial class Form2 : Form
    {
        CMyClass MyObject;
        public Form2(CMyClass MyObject)
        {
            InitializeComponent();
            this.MyObject = MyObject;
        }

        private void OtherFunction()
        {
            this.MyObject.MyMethod();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OtherFunction();
        }
    }
0

Poza tym jak chcesz go zmienic, to musisz uzyc delegacji i metody Invoke, zeby uniknac konfliktu watkow (dwie formy, dwa watki). To co powyzej i to o czym pisze bylo juz pare razy na forum.

0

dla formularzy najprościej tak jak pisał Darek, przekaż jako parametr w konstruktorze, a obiekty, do których chcesz mieć dostęp, zaimplementuj jako właściwości, public lub internal.

Jeśli podczas wykonywania programu z punktu widzenia logiki aplikacji może/mógłby istnieć tylko jeden obiekt danej klasy, wtedy można pomyśleć o użyciu wzorca singleton (prywatna statyczna składowa klasy przechowująca referencję do obiektu tej klasy, prywatny konstruktor i publiczna statyczna metoda inicjalizująca i zwracająca referencję przechowywaną we wspomnianej składowej) - odpada wtedy potrzeba przechowywania/przekazywania referencji do potrzebnego obiektu do wszystkich innych klas, które będą go potrzebować.

johny_bravo napisał(a)

Poza tym jak chcesz go zmienic, to musisz uzyc delegacji i metody Invoke, zeby uniknac konfliktu watkow (dwie formy, dwa watki). To co powyzej i to o czym pisze bylo juz pare razy na forum.

jeśli się mylę to mnie poprawcie - formularze są tworzone i operują w tym samym wątku - wszelkie odwołania z ich poziomu do składowych / metod są ok.
Problemy pojawią się dopiero wtedy, kiedy zostanie utworzony nowy wątek, który spróbuje odwołać się do np. kontrolek utworzonych przez inny wątek, np. ustawić tekst w textboksie. Aplikacje Windows Forms mają domyślnie metodę Main udekorowaną atrybutem [STAThread] (single thread apartment) co powoduje, że wątek wykonujący Main wchodzi w ten tryb i wywołania do np. kontrolek lub obiektów COM trybu STA z poziomu innych wątków musza być przeszeregowane (marshalled - tak to się tłumaczy?) na ten wątek i wywołane z jego poziomu (np. dla kontrolek - przez dziedziczonę metodę Control.Invoke). To z kolei wynika z architektury Windows, na której oparte są Windows.Forms.

0

Powiem szczerze, ze nie jestem pewien czy rzeczywiscie z dwoma oknami bedzie problem. Kojarzy mi sie, ze mialem, ale nie daje sobie glowy uciac. Na pewno, tak jak piszesz, bedzie problem z osobnym watkiem. Tak czy inaczej nie jest to jakies trudne.

0

odświeżę troszkę temat.

stworzyłem klasę singleton:

public partial class Form1 : Form
    {
        public static readonly Form1 instance = new Form1();

        public static Form1 Instance
        {
            get 
            {
                return instance;
            }
        }

        public Form1()
        {
            InitializeComponent();
        }

        public void Odswiez()
        {   
            MessageBox.Show("halo to ja Odśwież");
            this.DS_otwory = new DataSet("test");
            this.DS_otwory.ReadXml("test.xml");

            this.dataGridView1.DataSource = this.DS_otwory;
            this.dataGridView1.DataMember = "otwor";
        }
    }

i teraz chciałem odpalić funkcję Odswiez z drugiego forma tak:

Form1.Instance.Odswiez();

Funkcja się odpala (wyskakuje "halo to ja Odśwież") ale datagridview nie wypełnia się danymi :/

Wiecie może gdzie jest problem? :/

0

Sprobuj jeszcze dataGridView1.Refresh albo cos w tym stylu, bo datagrid niekoniecznie musi wiedziec, ze cos sie zmienilo.

0

Ale jak wywołuję tą funkcję z tej samej klasy to wszystko działa poprawnie.

Mimo wszystko użyłem refresh i nic się nie zmieniło [glowa]

0

Jest na to troche prostrzy sposób.

Form1:

private void WywolajForme(object sender, EventArgs e)
        {
            Form2 = new Form2(this);
            Form2.Show();
        }

Form 2:

public partial class Form2 : Form
    {

    private Form1 Form1;

    public Form2(Form1 forma)
        {
            InitializeComponent();
            Form1 = forma;
        }
   }

Teraz bedziesz miał dostęp do wszystkich obiektów w Form1. ;]

1 użytkowników online, w tym zalogowanych: 0, gości: 1