Wątek przeniesiony 2015-03-02 16:47 z C# i .NET przez somekind.

C# Odwłania pomiędzy plikami cs

0

Witam!

Struktura mojego projektu wygląda następująco.

Pierwszy plik to okno formy.

Drugi plik to kontrolka w którym mam menu. Menu to wczytuje się do formy po uruchomieniu programu. Tutaj jest sytuacja prosta:

menu uc1 = new menu();
panel_menu.Controls.Add(uc1);

Trzeci plik zawiera okno z danymi do wprowadzenia. Chciałbym by to okno pokazywało się dopiero wtedy gdy użytkownik kliknie w menu na przycisk czyli okno z trzeciego pliku (spr_nowa) musi pokazywać się w formie w "panel_nowa" gdy zostanie wciśnięty przycisk w drugim pliku :-) Próbowałem tej metody:

public void ToolStripButton1Click(object sender, EventArgs e)
{
	spr_nowa uc2 = new spr_nowa();
	MainForm.panel_nowa.Controls.Add(uc2);
}

ale niestety kompilator wyrzuca mi błąd: Dla niestatycznego pola, metody lub właściwości „rejest.MainForm.panel_nowa” wymagane jest odwołanie do obiektu. (CS0120)

Byłbym wdzięczny za naprowadzenie na rozwiązanie.

dodanie znaczników <code class="csharp"> - @furious programming

0
  1. Koloruj skladnie bo przyjdzie @furious programming i bedzie zjeba;p
  2. Nazewnictwo obiektow/zmiennych. Kod fajniej sie czyta jak ma normalne nazwy, typu sideMenu, controlPanel, itd - bez podkreslen.
  3. W C# nie ma kompletnie zadnego znaczenia jak klasy, ktore piszesz sa ulozone w pliki. Mozesz napisac 100 klas w jednym pliku, albo zrobic jedna klase partialem i rozwalic ja na 100 plikow
  4. Kodowanie po polsku/polskie ustawienia visuala to tak troche nie bardzo, lepiej sobie przestaw na angielski i przyzwyczajaj sie do angielskiego, jesli chcesz programowaniem zajmowac sie dluzszy czas
  5. Twoj blad polega na tym, ze wywolujesz .panel_nowa na nazwie klasy, czyli w taki statyczny sposob - potrzebujesz tutaj instancji obiektu:
var myMainForm = new MainForm()
myMainForm .panel_nowa.Controls.Add(uc2);
0

Poza tym co kolega wyżej napisał, to źle do tego podchodzisz. Zauważ, że kontrolka na formie będzie grzebać i dodawać elementy na tej formie. Dodaj jeszcze kilkanaście takich kontrolek, a osiągniesz w pełni satysfakcjonujący stan chaosu. W tym przypadku obsługę zdarzenia kliknięcia powinieneś obsłużyć w MainForm.

EDIT: Jeżeli dobrze zrozumiałem w MainForm masz kontrolkę menu, która ma dodawać coś do panelu znajdującego się na MainForm. Jeżeli jest inaczej rozpisz dokładniej, bo opis nie pokrywa się z kodem.

0

Dzięki za rady. Od kilku lat ze względu na specyfikę pracy programuje w VBA i staram się od jakiegoś czasu przejść na obiektowy język. Jak na razie ze skutkiem marnym, ale jestem uparty ;-)

Już tłumaczę. Chciałem projekt podzielić na osobne pliki, który każdy odpowiada za swoją działkę. Plik Main czyli plik z oknem Form odpowiada za ich wyświetlanie. Takie podejście wydawało mi się o tyle lepsze, że mam plik menu.cs gdzie będzie menu aplikacji wraz z instrukcjami co ma zrobić w momencie kliknięcia w poszczególne elementy. W tym przypadku chciałbym by po kliknięciu w przycisk "nowa sprawa" pojawiły się textboxy do wprowadzania danych. Te textboxy mam umieszczone w kolejnym pliku "spr_nowa". Wydaje mi się, że tak stworzony projekt jest dość przejrzysty chociaż nie upieram się. Zrobiłem jak podpowiadał kolega, kompilator już się nie rzuca o deklaracje, ale niestety po kliknięciu w przycisk nie wyświetla danych. Poniższy kod mam umieszczony w pliku menu.cs

 		public void ToolStripButton1Click(object sender, EventArgs e)
		{
			spr_nowa uc2 = new spr_nowa();
			var myMainForm = new MainForm();
			myMainForm.panel_nowa.Controls.Add(uc2);
		}

Zdaje sobie sprawę, że moje tłumaczenie może być nieudolne dlatego podrzucam załącznik. Gdyby ktoś mógł rzucić okiem i wskazać błąd byłbym wdzięczny :-)

0

A, o to chodzi;p No to tutaj blad jest taki, ze w tym kodzie wyzej tworzysz nowy obiekt klasy MainForm (tak pod spodem go tworzysz, bo nie wywolujesz na nim Show(), wiec sie nie pokaze). Musisz zrobic to w ten sposob, zeby klasa menu, ta ktora tworzy te kontrolki, wiedziala o obiekcie okna glownego. Jednym ze sposob (prostym ale srednim) jest wstrzykniecie referencji przez konstruktor. Trzeba tutaj zrobic kilka rzeczy:

  1. w klasie glownej, gdzie tworzysz menu, zamieniasz to:
menu uc1 = new menu();

na to:

menu uc1 = new menu(this);
  1. w klasie menu dodajesz dwie rzeczy: pole klasy do przechowywania referencji do okna glownego:
private MainForm mainForm;

i dodatkowy konstruktor do ustawienia tej referencji (ewentualnie modyfikujesz ten, ktory juz jest):

public menu(MainForm main)
		{
			InitializeComponent();
            mainForm = main;
		}
  1. W klasie glownej dodajesz metode do ustawiania tego Twojego czegos i wywolujesz ta metode w click handlerze:
<code class="csharp">public void ToolStripButton1Click(object sender, EventArgs e)
		{
			spr_nowa uc2 = new spr_nowa();
            mainForm.setPanel(uc2);
		}

w MainForm:

```csharp
public void setPanel(UserControl uc)
        {
            panel_nowa.Controls.Add(uc);
        }

dziala, ale to jest taki brzydki sposob, generalnie nie powinno sie tak kombinowac

0

Dziękuje bardzo. Faktycznie działa i faktycznie bardziej to sprawę komplikuje niż upraszcza. Teraz zgodzę się z tym, że dodając do tego klika innych opcji zrobi się chaos totalny. Mimo wszystko nauczyłem się dzięki temu bardzo dużo i za to bardzo dziękuje :-)

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