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.

Kod w kilku plikach w języku C#

tohimon 08 Mar 2013 15:51 3768 16
  • #1 08 Mar 2013 15:51
    tohimon
    Poziom 10  

    Witam. Przeszukałem już kilka tematów ale zadowalającej odpowiedzi nie znalazłem. Mianowicie.

    Na formie umieściłem ComboBox oraz Panel. W Combo mam 5 pozycji. Po wybraniu jednej z pozycji w Panelu generowane są odpowiednio kontrolki. I to działa prawidłowo. Jednak kodu jest dość sporo. Dlatego też chcę utworzyć dodatkowe pliki, które obsługuja odpowiednie stany ComboBox'a. Problem powstaje kiedy chcę ten działający kod przenieść do pliku test.cs (zakładam osobną klasę).

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    i tu mam błąd. Program nie widzi panel1. I jak w Form.cs odwołać się do test.cs ??

    0 16
  • #2 08 Mar 2013 15:56
    wiesniak
    Poziom 31  

    Nowa klasa musi być jakoś powiązana z miejscem użycia, więc albo metoda będzie statyczna, albo musisz stworzyć obiekt klasy i na nim operować. Poza tym metody najczęściej coś dostają przez parametr i zwracają jakieś wyniki ("klasycznie" albo przez parametr wyjściowy / ref).

    Jeśli chcesz mieć metodę do ładowania GUI, to osobna klasa może być zbędna. Albo przekaż panel do metody.

    0
  • #3 08 Mar 2013 16:03
    tohimon
    Poziom 10  

    Tylko jak przekazać :) Albo może inaczej. Czy muszę ładować kod do pliku class.cs czy jest jakieś inne rozwiązanie?? Chodzi mi o to że w pliku Form.cs jeśli piszę

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    to wywołuję odpowiednie działanie.

    0
  • #4 08 Mar 2013 16:16
    marcinj12
    Poziom 40  

    To Ci Kolega wiesniak opisał jak, nawet na kilka sposobów...
    Jeden z przykładów implementacji:
    klasa Generator.cs

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    w odpowiednim zdarzeniu formy:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    0
  • #5 08 Mar 2013 16:29
    wiesniak
    Poziom 31  

    Można też pomyśleć nad przekazaniem panelu przez konstruktor i użyć klasy do zarządzania formatką :-) Ja bym się jednak zastanowił, czy ta klasa jest w ogóle konieczna, bo być może jest to strzelanie z armaty do muchy i wystarczy jedna czy dwie metody w code behind.

    0
  • #6 08 Mar 2013 16:35
    tohimon
    Poziom 10  

    marcinj12 mam taki błąd: Dla niestatycznego pola, metody lub właściwości „PierwszyProgram.Generator.Main(System.Windows.Forms.Panel)” wymagane jest odwołanie do obiektu.


    Ok działa mój błąd małą literówkę zrobiłem.


    A może macie jakieś podręczniki albo linki do poradników na ten temat z przyjemnością bym sobie poczytał o tym??

    0
  • Pomocny post
    #7 01 Kwi 2013 15:39
    truski
    Poziom 16  

    Do dzielenia klas/struktur/interfejsów na więcej plików służy słowo kluczowe partial.
    Dzięki temu nie będziesz musiał przenosić swoich metod do osobnych klas, bo kompilator zrobi to za ciebie.

    0
  • #8 16 Cze 2013 09:55
    tohimon
    Poziom 10  

    Próbuje wykorzystać 'partial' w WPF w pliku*.cs w miejscu gdzie używam ComboBox. Za pomocą wyboru z listu chcę tworzyć dynamicznie elementy na panelu 'Canvas" (to mam obcykane). Jednak kiedy wpisuję:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    mam błąd: Za pośrednictwem typu zagnieżdżonego „X” nie można uzyskać dostępu do niestatycznego członka typu zewnętrznego „X”.

    Czytałem już kilka poradników na temat stosowania partial ale chyba nadal nie kumam

    0
  • #9 16 Cze 2013 22:53
    Mad.
    Poziom 18  

    Rozbicie klasy za pomocą słowa kluczowego "partial" to prawie zawsze zła praktyka. Wyjątkami są cwane implementacje w różnych frameworkach, aby pewne rzeczy magicznie działały (np. ta sama klasa dla pliku .xaml i code behind w pliku .cs w WPF, atrybuty dla klas modelu generowanych przez ORMy w ASP.NET itp.) lub zamknięta implementacja, która wymusza złe praktyki. W tym przypadku tak nie jest, sam tworzysz wszystko od początku. Jeżeli nie wiesz jak iść do przodu, lub wymyślasz jakiś dziwne rzeczy, to jest to sygnał że coś skopałeś już wcześniej i tam musisz szukać rozwiązania.

    Wracamy więc do początku. Masz ComboBox'a, który podmienia Tobie zawartość panelu. Pierwsze pytanie, dlaczego chcesz dynamicznie generować kontrolki, skoro w Twoim przykładzie widzę, że masz na sztywno podane jakieś parametry? Może nie wiesz o tym, że jeśli ma się "panele" z góry przewidzianą zawartością to wstawia się do głównego okna kontrolkę "Frame" i do niej ładuje się wybrane pliki xaml? W takim przypadku każdy Twój "panel" (jak zrozumiałem masz 5 takich), to osobny plik xaml. Ładujesz zawartość całego pliku do ramki. Ładnie masz wszystko oddzielone, 1 główne okno i 5 stron (page) = 6 plików. Prawym na projekt -> add Page.
    Google -> "C# wpf load page to frame"

    Chcesz jednak dynamicznie generować zawartość panelu. Czyli panel może zawierać inną zawartość w zależności od pewnych parametrów. Jeżeli są to drobne zmiany (kolorki, ułożenie), to równie dobrze możesz to zrobić jak Page (podmieniasz style, szablony strony). Jeżeli zawartość może się całkowicie różnić (różne kontrolki) to zrób generator jako osobną klasę (nie partial). Klasa powinna mieć jedną odpowiedzialność, czyli robić jedną rzecz. Nigdy nie rozbijaj klasy na kilka plików lub nie pisz takiej z tysiącami linii. Nie bój się rozdzielać implementacji na kilka, różnych klas. W przeciwnym przypadku, później tego nie ogarniesz, co już widać - "Jednak kodu jest dość sporo".

    0
  • #10 17 Cze 2013 09:01
    tohimon
    Poziom 10  

    Dokładnie chcę wrzucić tworzenie wszystkich kontrolek do jednej klasy następnie kiedy zostanie wskazana określona pozycja w ComboBox aktywowana jest określona grupa i umieszczana w odpowiednich miejscach. Czyli np. klasa "kontrolki" i za pomocą odpowiedniego kodu generowania w panelu określonego wyglądu. Tylko zastanawiam się jak pobierać dane z innego pliku.

    0
  • #11 17 Cze 2013 10:21
    Mad.
    Poziom 18  

    Nie rozumiem tylko, dlaczego nie chcesz ułożyć sobie kontrolek na formatce i wczytać ją całą (Page), zamiast generować wszystko w runtime, skoro wiesz jak to ma wyglądać?

    0
  • #12 17 Cze 2013 18:40
    tohimon
    Poziom 10  

    Zrobiłem tak jak radziłeś ale mam problem z wczytaniem strony. Próbowałem z trzema kodami i ciągle mam jakieś błędy.

    Kod: csharp
    Zaloguj się, aby zobaczyć kod

    0
  • #14 17 Cze 2013 19:09
    tohimon
    Poziom 10  

    Z tej strony też próbowałem. Jednak zrobiłem mały błąd. Wpisałem:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    a powinienem:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    W projekcie założyłem katalog m_page gdzie mam wszystkie strony. I teraz działa :)

    Z tego co rozumiem wszystkie zdarzenia np. naciśniecie klawisza robię w pliku *.cs strony?

    0
  • Pomocny post
    #15 17 Cze 2013 19:25
    Mad.
    Poziom 18  

    Tak, w zależności na której stronie/oknie znajduje się kontrolka, w niej (plik .cs) obsługujesz zdarzenia. W tej klasie (np. Page1 w pliku Page1.xaml.cs) piszesz tylko to co dotyczy wyglądu (view) - np. zdarzenia, zmiana wyglądu. Takie rzeczy jak zapis czegoś do pliku, obliczanie jakiś rzeczy itp. robisz w osobnych klasach (tam będzie kod). W Page1 tworzysz tylko obiekty tych klas i uruchamiasz metody. To jest najprostsze, a zarazem dobre podejście na początek.

    0
  • #16 18 Cze 2013 08:18
    tohimon
    Poziom 10  

    Podpowiedz mi proszę jeszcze jedną rzecz. Mianowicie jak odwołać się z Page do innego panelu.

    Np. chcę zrobić coś takiego po naciśnięciu przycisku który jest na stronie:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Jednak nie widzi panel1. dokładnie mam błąd, że panel1 nie istnieje w bieżącym kontekście. panel1 jest typu Canvas.

    panel1 -> namespace projekt
    page -> namespace projekt.m_page

    Ale to chyba nie ma znaczenia? Chyba, że muszę dodać jeszcze jakiś using?

    Kod który stosowałem do tej pory przy dynamicznych kontrolkach w WinForm działa teraz po małych przeróbkach w WPF. Jednak jak stosuje Frame i Page nie wiem jak wywołać zdarzenie na innym panelu.

    *------ Mała aktualizacja ------*

    Zamiast ładować dwa odrębne panele połączyłem wszystko na jednej stronie. W Frame mam Canvas na którym mam kontrolki i obsługę i WrapPanel, na którym pojawiają się wprowadzone dane w postaci elementów ułożonych w listę. Każdy nowy element to RadioButton. Dodawanie oraz ograniczenie ilości elementów to nie problem ... jakoś sobie z tym poradziłem :). Problem natomiast mam z usuwaniem elementu. Mam taki kod:

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    i do puki nie mam wstawionego kodu:
    Kod: csharp
    Zaloguj się, aby zobaczyć kod
    wszystko działa jak należy.
    Jednak kiedy fraza jest wstawiona usuwa zaznaczony RadioButton Wyświetla mi MassageBox oraz błąd: Moduł wyliczający jest nieprawidłowy, ponieważ kolekcja uległa zmianie. Jeśli wprowadzę kilka elementów i usunę jeden z ich, w tedy znikają mi wszystkie.Jak mogę to poprawić, żeby działało?

    0
  • #17 19 Cze 2013 14:25
    tohimon
    Poziom 10  

    Przepraszam Moderatorów za to, że nie edytuję starego wpisu ale nie chcę zaśmiecać. Rozwiązanie problemu (nie wiem czy eleganckie czy nie ale działające):
    Projekt pisany w WPF / C#
    Tak jak Mad. pisał zamiast kombinować z kilkoma Panelami wystarczy użyć Frame i Page. Tylko trzeba przemyśleć kwestię co dokładnie ma się generować na każdej stronie. Kod do wprowadzania danych pomiędzy Panelami w Frame:

    Dodawanie nowego elementu na WrapPanel z jednoczesnym sprawdzaniem czy nie ma podobnego:

    (Zliczanie ilości elementów w textbox'ie o nazwie "x:Name ="stan")

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Kod do kasowania wpisu z WrapPanel (ja użyłem do oznaczenia kolejnych wpisów RadioButton)

    Kod: csharp
    Zaloguj się, aby zobaczyć kod


    Mam nadzieję, że komuś się to kiedyś przyda.

    0