Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[C#] - Plik ze stałymi, zmiennymi

tiger1990 05 Wrz 2012 18:04 3288 19
  • #1 05 Wrz 2012 18:04
    tiger1990
    Poziom 12  

    Witam,

    Mam aplikacje która składa się z kilku formatek, kilku plików .cs
    Chciałbym utworzyć jakiś plik ze stałymi, zmiennymi globalnymi - które będą widoczne dla wszystkich plików - tak gdy będe zmieniał jakąś zmienną zmiany były widoczne dla innych plików .cs

    Chciałem to zrobić tak:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Ale wydaje mi się że gdy będe w kazdym pliku robił
    Stałe stale = new Stale()
    to nowa instancja będzie w sobie zawierała zmienną ModułyAktywne która zawsze będzie == 1, a nie tak jak została zmianiona w np innym pliku.

    Jeżeli się mylę proszę o uświadomienie, jeżeli nie proszę o pomoc w rozwiązaniu problemu.
    Irek

    0 19
  • Pomocny post
    #2 05 Wrz 2012 19:05
    mickpr
    Poziom 39  

    Rozwiązanie kiepskie: Zadeklaruj zmienną statyczną przed stworzeniem pozostałych klas (formatek itd).
    Zmienna statyczna w tym zakresie będzie widoczna wszędzie, ale musisz przekazać do niej wskaźnik (przy tworzeniu innych klas/formatek) - bo jakże inaczej byś się do niej "dobrał".
    Rozwiązanie lepsze: Jeśli to ma być zmienna do ustawień programu - lepiej użyj np. rejestru, który właśnie w tym celu istnieje.
    Rozwiązanie trzecie: Poczytaj o singleton'ach.
    http://4programmers.net/In%C5%BCynieria_oprogramowania/Wzorce_projektowe/Singleton
    http://msdn.microsoft.com/en-us/library/ff650316.aspx

    0
  • #3 06 Wrz 2012 00:09
    tiger1990
    Poziom 12  

    Hmm pierwsze chyba odpada bowiem tych zmiennych oraz stałych będzie (może być) dosyć sporo.

    Rozwiązanie drugie - mógłbyś przybliżyć o co come on bo pierwsze słyszę i nie wiem jak użyć.

    Zanim jednak któreś z nich wybiorę, chciałbym się dowiedzieć które z nich osobiście sam być wybrał.

    Irek

    0
  • Pomocny post
    #4 06 Wrz 2012 00:34
    mickpr
    Poziom 39  

    tiger1990 napisał:
    Rozwiązanie drugie - mógłbyś przybliżyć o co come on bo pierwsze słyszę i nie wiem jak użyć.

    Zapis i odczyt rejestru Windows. tam są "trzymane" ustawienia większości rzeczy w Windows + ustawienia programów.

    Pierwszy lepszy przykład z Google:
    http://www.miotk.eu/informatyka-mainmenu-45/39-c/164-wspopraca-z-rejestrem-windows-w-c

    Ja wybrał bym 2 (do konfiguracji).
    Singletony stosuje się do innych rzeczy, choć mógłbyś wykorzystać je jako wspólna klasa konfiguracyjna (z metodami itp).
    Ale moim zdaniem to jest gorsze rozwiązanie, niż rejestr.

    Pamiętaj przy rejestrze, że sam z siebie określony klucz nie będzie istniał.
    Twój program musi sprawdzić, czy określony klucz istnieje, a jak nie - to go stworzyć.

    Pseudokod :)
    Code:
    if (klucz_istnieje==true)
    
    {
       opcja = klucz;
    }
    else
    {
       klucz=opcja_domyslna;
       opcja=klucz;
    }

    0
  • Pomocny post
    #5 06 Wrz 2012 01:23
    marcinj12
    Poziom 40  

    Ja bym do tego wykorzystał plik .settings - np. ten domyślnie tworzony w katalogu Properties projektu. Zalety: prosty zapis i odczyt wartości typu: klucz - wartość, zgodność z typami .NET, z pewnością szybszy niż praca na rejestrze no i do tego właśnie został stworzony - do trzymania stałych, które nie będą się zmieniać w trakcie pracy programu, (scope: Application) oraz ustawień użytkownika, które mogą się zmieniać (scope: User).
    Wady: trzeba potem "ciągnąć" domyślny plik .config (tj. ten który utworzy się w katalogu) za programem, no i wartości są zapisywane zwykłym tekstem w XMLu, co czasami może stanowić problem...
    Zakładam też, że te zmienne to jakieś ustawienia i nie będą zbyt często odczytywane/zapisywane, jeżeli tak - to raczej jak radził Kolega - klasa statyczna, ewentualnie wczytanie ich z pliku settings do klasy/zmiennych, częste operacje na nich, ewentualnie zapis do pliku przy wyjściu.
    http://msdn.microsoft.com/en-us/library/aa730869%28v=vs.80%29.aspx

    0
  • Pomocny post
    #6 06 Wrz 2012 08:22
    gaskoin
    Poziom 38  

    Nie wiem skąd kolega mickpr czerpie pomysły ale wole nie wiedzieć :) Dla zmiennych statycznych/stałych nie potrzebujesz referencji, można się do nich odwołać po nazwie klasy. Sama klasa nie musi być nawet statyczna.

    Można to zrobić albo tak:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    albo jak pisze kolega wyżej:

    plik app.config:
    Kod: xml
    Zaloguj się, aby zobaczyć kod


    plik Keys.cs:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    plik AppSettings.cs:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod




    albo dodac sobie plik Resources (add -> new item -> Resources file) w którym można trzymać stringi, pliki, obrazki, dzwieku, cokolwiek. i wyciagac z nich dane. Nazywasz go np MyResources i potem:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    To są chyba wszystkie możliwe sposoby. Wszystko zależy po co Ci to. Generalnie możesz używać czegokolwiek, jak sobie tam chcesz, ale zamysł jest taki:

    - plik settings służy do ustawień programu i w nim trzymamy rzeczy związane z działaniem rzeczy. Flagi, które coś zmieniają, czy inne konfigurowywalne stałe, lecz niezmienne w trakcie działania programu
    - Resources sama nazwa wskazuje :) pliki z rzeczami wymaganymi do np wyświetlenia na ekranie. Jakieś reużywalne w stu miejscach rzeczy. Głównie do stringów, obrazków, dźwięków itd
    - constants - tu trzymasz stałe które się nie zmieniają nigdy, np rozmiar ramki komunikacyjnej, czy inne cuda.

    To chyba tyle.



    Btw widzę chyba jakie to ma mieć zastosowanie. W takim przypadku zamiast inta lepiej trzymać boola, albo jeszcze lepiej - zrezygnować ze stałych i użyć pluginów (MEF MAF, CastleWindsor czy cokolwiek innego do DI/IoC).

    0
  • Pomocny post
    #7 06 Wrz 2012 09:18
    mickpr
    Poziom 39  

    gaskoin napisał:
    Nie wiem skąd kolega mickpr czerpie pomysły ale wole nie wiedzieć

    Faktycznie co do zmiennych statycznych wyraziłem się błędnie. Myślałem o zmiennej globalnej - nie będącej zmienną statyczną, a napisałem "statycznej".
    Zadeklarowanie zmiennej statycznej oznacza współdzielenie jej danym bloku programu.
    Naśmiewanie się z innych - kolego gaskoin - nie jest niczym lepszym, niż popełnianie błędów. Rozumiem, że kolega ich nie popełnia.

    0
  • Pomocny post
    #8 06 Wrz 2012 14:22
    gaskoin
    Poziom 38  

    Nie śmieję się, ale przecież zapisywanie stałych w rejestrze systemu nie jest najlepszym pomysłem. Kto potem będzie ten rejestr odśmiecał ? Użytkownik usuwa aplikację a śmieci w rejestrze niestety zostają. Bez zrobienia instalatora/deinstalatora nie wolno robić takich rzeczy :)

    Z kolei niestatyczna zmienna globalna to zło zabijające obiektowość języka obiektowego. Chociażby dlatego, że mając dostęp do referencji na taki obiekt, ktokolwiek kto go używa może go sobie chociażby znullować. Z punktu widzenia programisty, musisz udostępniać na zewnątrz jak najmniej, w przypadku o którym mówisz jest zupełnie odwrotnie.

    Wiem, że to dlatego, że kolega chce mieć zmienne globalne, ale na chwilę obecną nie wiadomo po co mu to :)

    0
  • #9 06 Wrz 2012 15:38
    tiger1990
    Poziom 12  

    Pliku settings używam do trzymania ustawień okien, danych które raczej nie zmieniają się zbyt często.

    Zainteresowało mnie to:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Mógłbyś napisać jak potem używać tego w innych plikach? Rozumiem ze gdzieś trzeba stworzyć instancje tej klasy, która jest potem widziana przez wsztkie inne pliki?

    0
  • #10 06 Wrz 2012 17:12
    gaskoin
    Poziom 38  

    Źle zrozumiałeś moją wypowiedź.

    Pierwszy kod (klasa Constants) jaki wkleiłem dotyczy pierwszego sposobu. Wszelkie zmiany w niej wymagają ponownej kompilacji.

    użycie:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod






    Drugi sposób - plik app.config oraz klasy: Keys, AppSettings. Zaleta jest taka, że wystarczy zmienić wartość w pliku app.config bez ponownej kompilacji. Ten plik powinieneś raczej wykorzystać niż zapisywać do niego rzeczy które się nie zmieniają.

    użycie takie samo:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod





    Trzeci przypadek to plik resources, użycie takie samo

    Kod: csharp
    Zaloguj się, aby zobaczyć kod



    Wszystko używa się tak samo, ale "zastosowanie" jest inne. Zastosowanie w cudzysłowie bo możesz to wykorzystać jak Ci się żywnie podoba. Nie trzeba nigdzie tworzyć instancji klasy, można się odwołać do niej bezpośrednio. Tak jest ze wszystkimi constami i staticami.

    0
  • #11 06 Wrz 2012 17:34
    marcinj12
    Poziom 40  

    Ja tylko przypomnę o czym autor pisał na początku:

    Cytat:
    Ale wydaje mi się że gdy będe w kazdym pliku robił
    Stałe stale = new Stale()
    to nowa instancja będzie w sobie zawierała zmienną ModułyAktywne która zawsze będzie == 1, a nie tak jak została zmianiona w np innym pliku.

    Jeśli dobrze rozumiem, to chcesz modyfikować te zmienne w jednym pliku (formie), i odczytywać zmodyfikowaną wartość w drugim.
    W takim wypadku użycie stałych (const) z wiadomych przyczyn odpada, podobnie jak zastosowanie pliku Resources (wartości nie można modyfikować w trakcie).
    Do zastosowania jako źródło dla stałych wartości - jak najbardziej tak, ale nie w przypadku gdy chcesz je zmieniać w trakcie działania programu.

    Pozostaje m.in. sposób z plikiem .settings, singletonem lub klasą statyczną, ale bez const.
    Jeżeli nie zależy Ci na podążaniu za wzorcami obiektowymi czy ścisłym trzymaniu się zasad obiektowości (a mam wrażenie, że stosując wiele zmiennych globalnych, tak właśnie jest ;P), możesz wykorzystać klasę statyczną (lub sealed z polami statycznymi) jak sugerowano wcześniej:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    Wtedy w jednej formie możesz to zmienić:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    a w drugiej odczytać:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    Do klas lub pól statycznych nie musisz tworzyć nowej instancji klasy - to a'propo Twojego pytania jak to potem wykorzystać...

    Oczywiście taki sposób nie gwarantuje zapisania danych po wyłączeniu programu - po ponownym uruchomieniu, znowu będziesz miał domyślną wartość zmiennej = ABC. Jednak w trakcie działania programu zmienna będzie swój stan zachowywać.

    Bardziej eleganckie rozwiązanie to użycie wspominanego singletonu, czyli klasy mającej tylko jedną instancję.

    Ciągle nie wiemy do czego Ci to potrzebne i czy stan zmiennych musi zostać zapamiętany pomiędzy kolejnymi uruchomieniami aplikacji, więc ciężko doradzić konkretne rozwiązanie ;)

    0
  • #12 06 Wrz 2012 18:36
    tiger1990
    Poziom 12  

    Na początku chciałbym wszystkim bardzo podziękować za pomoc. Mam wrażenie, że przez ten miesiąc przy pisaniu tej aplikacji, nie raz mi jeszcze pomożecie, o ile nie skończą mi się punkty na zakładanie nowych tematów (:

    marcinj12 wielkie dzięki za Twój ostatni post - chyba o to chodziło. No ale opiszę problem.

    Na samym początku mam 2 formy - okno główne i moduły. W menu okna głównego mam opcje "pokaż moduły" - w przypadku jak by ktoś wyłączył i chciał ponownie włączyć - ale nie może być tak że jeżeli "moduły" są włączone i ktoś naciśnie opcje "pokaż moduły" to odpali się drugi egzemplarz tej formatki. Właśnie po to są mi potrzebne flagi - które będą zawierały 1 lub 0 ( true, false ) moduły włączone/wyłączone (status ma się zmieniać podczas dzialania programu, ale po zakończeniu ma mieć początkową wartość). Zmiana flag (włączanie/wyłączanie formatki moduły) już na chwile obecną - a dopiero zacząłem pisać aplikacje odbyw a się w kilku plikach .cs

    Drugą rzeczą do której chciałbym wykorzystać tą klasę to trzymanie const stringów. Aplikacja ma działać na bazie danych i jak robie zapytanie to zamiast pisać w pełne zapytanie stringowe "select pole1,pole2 from baza danych" chciałbym robić łączenia w ten sposób "select" + pole1 +"," + pole2+ "from baza danych" - gdzie pole1 i pole2 to zmienne. Dlaczego tak? Bowiem gdyby w przyszłości była jakaś zmiana nazw w polach tabeli musiałbym przeszukiwać cały ogromny kod i zmieniać nazwy pól - a tak wystarczy ze zmienie to tylko w jednym miejscu.

    Mam nadzieję ze nie namąciłem - opisałem najlepiej jak potrafiłem. Rozwiązanie z Klasą statyczną wydaje się bardzo fajne... Co o tym sądzicie?

    0
  • #13 06 Wrz 2012 20:09
    marcinj12
    Poziom 40  

    No i wreszcie wiemy o co chodzi :) I nie, nie jest to dobry pomysł :)
    Myślę że mógłbyś bez problemu się obejść bez trzymania tych danych gdzieś zapisanych.

    Pierwsza rzecz - moduły:
    Jeżeli na formatce głównej (form1) masz przycisk PokazModuly (albo jest to opcja w menu, obojętnie...), a po uruchomieniu programu masz już okno z modułami (form2) otwarte, to domyślnie wyłączasz (enabled = false) lub w ogóle ukrywasz (visible = false) ten przycisk lub opcję w menu. Możesz to zrobić w designerze albo w form_load.
    Natomiast w momencie zamknięcia form2 (zdarzenie: FormClosed(...)) robisz sytuację odwrotną: włączasz lub pokazujesz tą opcję/przycisk.

    Ja bym to zrobił w ten sposób, z wykorzystaniem właściwości (wiem że pokazujesz formę z modułami za pomocą form2.Show(this)):

    Forma główna (Form1) z menuStrip z jedną opcją:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    Natomiast Form2 (menu modułów) tak:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    Tak naprawdę całym "problemem" jest dobranie się do kontrolek jednej formy z poziomu drugiej, ale z wykorzystaniem właściwości można tak elegancko do tego podejść (równie dobrze mogła by to być publiczna metoda).

    Jest to tylko jeden z wielu sposobów rozwiązania tego problemu...
    Poza tym: zamiast flag 0 i 1 używaj typu boolean: true lub false.

    Drugi problem: trzymanie nazw pól bazy danych jako stałych.
    Tak się raczej nie robi :)
    Po pierwsze - siadając do projektu należało by najpierw zaprojektować bazę danych. Jak już masz gotową bazę - wtedy zabierasz się za pisanie aplikacji. Wtedy nazwy pól nie będą się zmieniać, a jeśli już to na etapie projektowania, kiedy to jeszcze ogarniesz.
    Po drugie: jakoś ciężko mi sobie wyobrazić sytuację, kiedy ktoś dochodzi nagle do wniosku: "hej, przez pięć lat ta baza działała jak trzeba, zmieńmy sobie teraz parę nazw pól żeby było śmieszniej..." :) Czemu by to miało służyć? Jak już baza zostanie zaprojektowana i oddana do produkcji, to po co zmieniać jej nazwy pól? A jak dojdą jakieś nowe pola do tabeli, i tak będziesz musiał przerobić wszystkie zapytania do tabeli, więc nic nie zyskujesz...

    Nie wiem jaki sposób komunikacji z bazą wybrałeś, jeśli jest to ADO.NET i samemu piszesz zapytania, to zastosuj lepiej architekturę n-warstwową - na poziomie logicznym organizacji plików w projekcie. Żeby nie mieszać Ci w głowie z trzema warstwami, spróbuj chociaż dwuwarstwową, gdzie oddzielasz warstwę dostępu do danych od reszty. Załóż sobie osobny katalog, do którego wrzucisz wszystkie klasy odpowiadające za komunikację z bazą danych (gdzie operacje na bazie będą jako metody). W praktyce można to ładnie ująć w klasy, np. klasa OsobaDAL (DAL = DataAccessLayer) może mieć metody: PobierzWszystkie(), PobierzWgId(int id), Dodaj(...parametry...), Modyfikuj(...prametry...), Usun(int id) etc.




    W przypadku zapytania SELECT - metody mogą zwracać wypełnioną danymi klasę, obiekt DataTable lub DataSet, INSERT, UPDATE i DELETE - mogą zwracać ilość wierszy "dotkniętych" zapytaniem (recordsAffected) lub bool (true lub false) informujący o sukcesie bądź nie zapytania. A wszystkie parametry potrzebne do wykonania zapytania przekazujesz do metody jako argumenty.

    Dzięki temu zgrupujesz cały kod odpowiedzialny za komunikację z bazą danych w jednym miejscu, co ułatwi późniejsze ewentualne zmiany (wyszukiwanie i zastępowanie to standardowe opcje edytora).

    Gdyby baza miała być naprawdę często zmieniana, wtedy należało by się zastanowić nad jakimś rozwiązaniem typu ORM (np. NHibernate). Tam raz "projektujesz" schemat bazy danych, a zapytania są konstruowane automatycznie. Jeżeli coś się zmieni w schemacie, poprawiasz go, kompilujesz ponownie, a reszta zmian odbywa się też automatycznie. Tyle że żeby to ogarnąć trzeba nad tym trochę posiedzieć, także nie polecam na początek...

    Last but not least - jeżeli już, to Twój pomysł z nazwami pól nadaje się do wykorzystania pliku Resources, jako że nie muszą one być zmieniane w trakcie pracy programu. Dodajesz taki plik do projektu, umieszczasz w nim pola i ich nazwy w tabeli, a potem robisz coś w stylu (string.Format(), żadne plusiki!):
    Kod: csharp
    Zaloguj się, aby zobaczyć kod
    Jak coś się potem zmieni - zmieniasz tylko nazwę pola (wartość) w pliku Resources, identyfikator zostawiając bez zmian.
    Ale, jak wspomniałem, nie widzę sensu żeby tak to robić, tylko zaciemnia to kod...

    0
  • #14 06 Wrz 2012 23:31
    gaskoin
    Poziom 38  

    Trochę chyba schodzimy z tematu. Dodam jeszcze, że schemat połączeń z bazą w idealnym przypadku wygląda tak:

    1. SQLów nie trzymasz w kodzie, tylko w bazie danych w postaci funkcji, lub lepiej paczek.

    2. Masz klasę, która jest adapterem na połączenie z bazą. Ta klasa jest odpowiedzialna za mapowanie tego co przyszło z bazy na obiekty reprezentujące tabele w bazie danych (np obiekt osoba, która ma tylko właściwości imie, nazwisko, itd). Mapowanie powinno być wykonywane automatycznie, czyli inwersja kontroli jak ulał. Jak ma się odbywać mapowanie może być zapisane w XML w postaci nazwa_property_danego_obiektu - nazwa_tabeli

    3. Masz obiekty DataAccess, osobno dla każdej tabeli. Taki obiekt nic innego nie robi tylko przekształca Twoje obiekty na parametry i wywołuje metodę adaptera (po którym dziedziczy) razem z nazwą procedury z paczki. Metoda ta zwraca kolekcję gotowych obiektów.

    4. Powinieneś mieć coś w rodzaju serwisu, który tylko zarządza DataAccessami (bo w większości przypadków nie potrzebujesz wszystkich szczegółów z bazy danych), DataAccess nie powinien być dostępny nigdzie indziej niż w tym serwisie (kilku serwisach dla odpowiednich grup danych, czy nawet poszczególnych tabel).

    Może to być bardzo trudne do napisania dla osoby z Twoim doświadczeniem. Może się wydawać "na grzyba mi to, skoro to będę pisał sto lat, a tak w 10 sekund mam gotowe zapytanie i obiekt", ale takie rozwiązanie jest bardzo elastyczne, i gdy już powstanie, dodanie zapytania dla nowego obiektu wymaga jedynie dodania sqla do bazy danych, dodania tego obiektu i dodania prostego dataaccessa (nic więcej, żadnego składania danych etc).

    Opisałem trochę po łebkach, ale żeby wdać się w szczegóły musiałbym pisać do jutra :)

    0
  • #15 07 Wrz 2012 23:04
    tiger1990
    Poziom 12  

    Dobra musiałem ogarnąć co napisaliście i tak:
    marcinj12 Co do flag i tego menu z blokowaniem opcji - Twoje rozwiązanie jest super (:
    Zapytam jednak co oznacza zapis: Form1 formaGlowna = this.Owner as Form1;
    bo nie rozumiem.
    Tutaj mam od razu pytanie bo tak postępując mam dostęp do zmiennych i funkcji z formy Głównej które są public ( czy jest możliwość zeby dobrać się do guzika czy pola menu? zeby napisać po prostu button1.enabled - false) ?

    Co do zapytań do bazy danych to chciałem zrobić w tym samym projekcie plik.cs który bedzie odpowiedzialny za konstruowanie zapytań do bazy - były by tam funkcje a w kodzie przekazywałbym tylko co trzeba wyciągnąć, warunki itd...

    Zastanawia mnie jednak bo napisałeś że powinienem stworzyć osobny katalog... Czy to oznacza nowy projekt który jakoś załączę do pierwotnego czy może po prostu są tam pliki .cs i jakoś sprytnie się to załącza.

    Gaskoin - Szczerze powiem - fajnie się to czyta, ale niewiele z tego rozumiem, tzn nawet nie wiedziałbym jak się za to zabrać. Może na tym etapie poprzestać na stworzeniu osobnego pliku odpowiedzialnego za konstruowaniu zapytań do bazy.
    Twoje rozwiązanie jest na pewno fachowe, ale nie wiem czy wykonalne dla mnie.

    Teraz tak. Pomyślałem bo projekt nie jest jeszcze duży - są tam 3 formatki - forma główna, moduły i logowanie - porządkował bym kod spakował projekt i wrzucił Tutaj - zobaczylibyście zarys i stwierdzili - jest ok, albo dostaw pliki odpowiedzialne za to, za to i za to albo coś innego...

    //Nowe pytanie. Robie logowanie i chciałbym zeby wpisywane hasło zamieniało się w *. Czy muszę to samemu obsłużyć w metodzie on Change czy jest już coś gotowego co to załatwia?

    0
  • #16 07 Wrz 2012 23:51
    marcinj12
    Poziom 40  

    tiger1990 napisał:
    Zapytam jednak co oznacza zapis: Form1 formaGlowna = this.Owner as Form1;
    Ponieważ z poziomu form2 chcesz modyfikować obiekty znajdujące się na form1, to form2 musi mieć jakiś dostęp do form1.
    W tym celu do form2 musisz przekazać istniejącą instancję form1: można to zrobić na kilka sposobów, np. stworzyć konstruktor form2 z parametrem, który wywołasz poleceniem new podając jako parametr instancję form1, albo wykorzystać fakt, że jeżeli pokazujesz okno form2 podając rodzica (właściciela):
    Kod: csharp
    Zaloguj się, aby zobaczyć kod
    , to instancja na tego właściciela (Owner) jest już przekazana do form2. Cytowany przez Ciebie fragment to nic innego jak rzutowanie: this.Owner jest typu ogólnego Form, a po zrzutowaniu operatorem as na typ bardziej szczegółowy Form1 zmienna formaGlowna stanie się referencją (jakby wskaźnikiem) na istniejącą instancję form1 (lub przybierze wartość null gdyby this.Owner nie było typu Form1).

    tiger1990 napisał:
    czy jest możliwość zeby dobrać się do guzika czy pola menu? zeby napisać po prostu button1.enabled - false
    Można, jeśli ustawisz je na public, ale tak nie powinno się robić - formy czy klasy generalnie powinny być od siebie możliwie niezależne. Ustawiając właściwości kontrolek jednej formy z poziomu drugiej, szybko pogubisz się co gdzie jest ustawiane. Sposób z właściwościami jest lepszy, choć pozornie zajmuje trochę więcej linii. Efekt ten sam, a lepiej uczyć się dobrych nawyków od początku...

    tiger1990 napisał:
    Zastanawia mnie jednak bo napisałeś że powinienem stworzyć osobny katalog...
    To tylko sugestia, szkół na oddzielenie warstwy danych jest kilka: o paru wspomniał przedmówca, ja na początek zaproponowałem zwykły katalog, jak na tej stronie na drugim obrazku (katalog: DAL). Nie musisz tego dzielić na osobne projekty jeśli nie planujesz umieścić ich na osobnych serwerach czy pisać testy (a nie planujesz), chodzie jedynie o jakąś logiczną organizację i zgrupowanie razem plików w obrębie jednego programu. (przy okazji: na cytowanej stronie masz jaki taki ogląd na architekturę 3-warstwową)

    tiger1990 napisał:
    porządkował bym kod spakował projekt i wrzucił Tutaj - zobaczylibyście zarys i stwierdzili - jest ok, albo dostaw pliki odpowiedzialne za to, za to i za to
    Nie wiem czy jest sens - na początku na pewno są jakieś błędy, w zależności od tego jak kto jest zaawansowany każdy Ci może wytknąć że tak by było lepiej albo tak się nie powinno robić zgodnie ze sztuką - na początku rób tak, żeby działało...

    tiger1990 napisał:
    Robie logowanie i chciałbym zeby wpisywane hasło zamieniało się w *
    Pole TextBox ma właściwość PasswordChar. Jak ustawisz ją na gwiazdkę, to wpisywany tekst będzie zagwiazdkowany.

    I mocno sugeruję jednak zaopatrzeć się w jakąś książkę o C# która przeprowadzi Cię przez początki programowania, bo np. to o co pytasz to podstawowe właściwości kontrolek. Na razie jest prosto, ale przy takich lukach wkrótce zaczniesz się wykładać albo będziesz tworzył ręcznie obejścia problemów, które można rozwiązać jedną linijką...

    0
  • #17 08 Wrz 2012 00:54
    tiger1990
    Poziom 12  

    W twoim sposobie z odpalaniem Show(this) jest jakiś kruczek bowiem u mnie wyskakuje coś takiego:

    (...)/34nl4dj.jpg Proszę się zastosować do Instrukcja zamieszczania obrazków [adamas_nt]

    ZSITopDance to moja forma główna
    a moduły to moduły..
    Przedstawiona wyżej funkcja to funkcja on Load z ZSITopDance

    0
  • #18 08 Wrz 2012 00:59
    marcinj12
    Poziom 40  

    A co tam robi MdiParent? Chyba nie zdecydowałeś się w końcu na uruchamianie tych okien w oknie MDI? PS. Nie używaj polskich znaków w zmiennych czy w ogóle w kodzie :)

    0
  • #19 08 Wrz 2012 01:09
    tiger1990
    Poziom 12  

    No zdecydowałem - sam podsunąłeś mi to rozwiązanie, które swoją drogą jest świetne. W takim wypadku może da się jakoś z tego MDI wyciągnąć rodzica? bowiem w tym wypadku gdy usunę z show(this)


    Kod: csharp
    Zaloguj się, aby zobaczyć kod
    <- zwraca - zwraca mi null

    0
  • #20 08 Wrz 2012 01:16
    marcinj12
    Poziom 40  

    A, to w takim razie jeszcze prościej: formę otwierasz w oknie MDI normalnym Show(), bez parametru, a w form2 zmieniasz this.Owner na this.MdiParent. Znaczenie takie samo, tylko nazwa pól inna. Reszta bez zmian.

    0