DockPanelSuite - interakcja między panelami

0

Witam

Stworzyłem sobie malutką aplikację z użyciem biblioteki DockpanelSuite:

http://sourceforge.net/projects/dockpanelsuite/

Na podstawie tego tutoriala:

http://www.rtarnas.com/poradnik.php

Stworzyłem w niej dwa panele: Panel1 i Panel2 (nazwy są umowne - żeby było jaśniej). W tutorialu jest jeden panel powtórzony trzy razy. Ja stworzyłem dwa różne oczywiście.
Wyświetlają się bez problemu. W Panelu1 umieściłem dwa buttony, a w Panelu2 objekt pictureBox. I teraz moje pytanie. Jak spowodować, żeby przyciśnięcie przycisku w Panelu1 spowodowało zmianę obrazka w objekcie pictureBox w Panelu2? Czyli chodzi o interakcję między panelami (obiektami różnych klas).

0

domyslam sie ze ten DockContent dziedziczy z Form,
domyslnie kontrolki na form sa private

brzydkie rozwiazanie
upublicznic kontrolke do ktorej chcesz sie dobrac, w tym przypadku picture box, z poziomu designera wlasciwosc kontrolki Modifiers (w grupie Desing) lub recznie w pliku *.Designer.cs

ladne rozwiazanie
strorzyc publiczne wlasciwosci, metody do modyfikacji danych na form (DockContent)
w tym przypadku wlasciwosc, ktora przyjmie/zwroci Image, ktory bedzie w picturebox

0

Problem właśnie w tym, że nawet jak udostępniam jak public, to i tak nie chce mi to działać. Pisanie kodu odwołującego się do odpowiednich pól i metod też jakoś mi się gryzie.
Próbowałem odwoływać się do odpowiednich pól przez referencje, ale samo słowo "ref" było wywalane jako błąd :(
A może inaczej... Tutaj:

http://free.of.pl/a/aajgor/temp/Slideshower.zip

wrzuciłem kompletną solucję. Plik ma 406kb i jest spakowany Zip-em. Może ktoś zajrzy, i dopisze najprostszą metodę wyświetlającą jakiś obrazek po kliknięciu w przycisk, i mi ją pokaże, lub odeśle?

Z góry dzięki.

0

ale mogles choc troche kodu napisac :/ a nie na totalnego gotowca liczyc

przede wszystkim skad okno z przyciskami ma wiedziec o oknie z obrazkiem?
oczywiscie mozna przez parenta etc. ale to malo eleganckie

jesli chcesz zeby okno z przycikami wiedzialo o oknie z obrazkiem to najlepiej najpierw stworz okno z obrazkiem, pozniej w konstruktorze kolejnego okna (z przyciskami) przekaz referencje do okna z obrazkiem, teraz okno z przyciskami bedzie moglo odwolac sie do okna z obrazkiem

a obrazek mozesz wczytac np. za pomoca Image.FromFile
mozesz tez dolaczyc jakies obrazki do resources i z nich pobierac

wygodnie bedzie jesli stworzysz sobie jakis interface np. IImageDisplayer z wlasciwoscia public Image DisplayedItem
twoj form z obrazkiem (Obraz) niech go implementuje, a form z przyciskami niech wymaga w konstruktorze obiektu implemtujacego IImageDisplayer, dzieki temu bedzie bardziej elastyczny

0

Ja od dziś rana napisałem tyle kodu, że mi się literki z klawiszy już ścierają. Niestety wszystko źle. Nie wpisywałem tu swoich funkcji wczytujących obrazek po kliknięciu, żeby sobie obciachu nie robić :)
Ale fakt - o umieszczeniu referencji w konstruktorze nie pomyślałem. Niestety wszystkie próby wstawienia referencji w obsłudze przycisku wywalały błędy. Nawet w obsłudze rodzica przesłanie danej z jednego dziecka do drugiego nie chciało mi działać.
Tu jest solucja, w której jest panel z przyciskami i panel w obiektem pictureBox. Dodatkowo w rodzicu jest menu, a w nim File/Open, która.. działa prawidłowo (wczytuje obrazek i go umieszcza w panelu - dziecku). Z poziomu rodzica wszystko działa prawidłowo, a przesyłanie między panelami równorzędnymi już nie. I to właśnie mój problem.
Kodu własnego nie wstawiałem, bo nawet nie wiem, od czego zacząć. Wszystko, co próbowałem po prostu nie działało. Niestety za 3 minuty wychodzę do pracy, więc teraz już nie wypiszę listy błędów, jakie mi się pokazywały :)

No więc tak... Obiekt klasy zawierającej przyciski nazywa się "okno1", a klasy zawierającej
pictureBox nazywa się "okno2".

W klasie zawierającej obiekt pictureBox1 wstawiam kod:

public void zmienObraz(String nazwaObrazu)
        {
            pictureBox1.Image = Image.FromFile(nazwaObrazu);
        }

A w klasie zawierającej przycisk wstawiam:

  private void button1_Click(object sender, EventArgs e)
        {
          okno2.zmienObraz("ścieżka_do_obrazka/nazwa/obrazka");  //okno2 to jest obiekt - panel zawierający "pictureBox1".
        }

Kiedy próbuję to wywołać, otrzymuję błąd:

"The name 'okno2' does not exist in the current context".
Dokładnie wiem, co to oznacza. Ale za diabła nie mogę sobie z tym poradzić. Żeby w "okno1" było widać "okno2". Wstawiałem ref-a gdzie tylko udało mi się wymyśleć, ale zawsze dawało to błędy, albo po prostu nie działało.

W klasie nadrzędnej (czyli w Form1) mam toolStripMenu, i metody:


 private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileDialog1.Filter = "jpg files (*.jpg)|*.jpg|Gif files (*.gif)|*.gif|All files (*.*)|*.*";
            openFileDialog1.ShowDialog();
        }

private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            okno2.zmienObraz(openFileDialog1.FileName);
        }

I to mi działa bez zarzutu.

BYĆ MOŻE w samym DockpanelSuite są odpowiednie mechanizmy do tego. Ale biblioteka ta właściwie w ogóle nie jest udokumentowana. Na każde pytanie o dokumentację dostaje się odpowiedź "Zajrzyj do załączonego przykładu". Tyle, że w przykładzie są tylko wyświetlone różne panele, a nie ma w ogóle żadnych akcji.

0

Haaa...
Udało się.
Po długich trudach i męce znalazłem rozwiązanie, które jest tak proste, jak konstrukcja cepa. Rozwiązaniem jest.... Jedna (słownie JEDNA) linijka kodu :)

W obsłudze zdarzenia wstawiamy kod odczytujący uchwyt do parenta (czyli głównego panelu):

Form1 ojciec = (Form1)this.ParentForm;

I w tej chwili w zmiennej "ojciec" mamy uchwyt do klasy nadrzędnej, i możemy zrobić wszystko. Możemy wywoływać metody klasy nadrzędnej, możemy przez klasę nadrzędną wywoływać metody, albo zmieniać pola w innych klasach potomnych itd. Jedyne ograniczenie - te metody lub pola muszą mieć modyfikator dostępu ustawiony na public, lub Internal, a same obiekty klas potomnych muszą być zdefiniowane jako publik PRZED konstruktorem parenta. W przypadku metod jest to OK, a w przypadku pól "brzydko wygląda". Przynajmniej ze strony programisty (bo ze strony użytkownika nie koniecznie:) ).

Piszemy w panelu2 publiczną metodę zmieniającą obrazek:

 public void zmienObraz(String nazwaObrazu)
        {
            pictureBox1.Image = Image.FromFile(nazwaObrazu);
        }

A w panelu1 w obsłudze przycisku odwołujemy się do niej przez ojca:

        private void button1_Click(object sender, EventArgs e)
        {
            Form1 ojciec = (Form1)this.ParentForm;
            ojciec.okno2.zmienObraz("nazwa_obrazka.jpg");
        }

I to działa.
Acha... Odwołanie do parenta nie chce działać wstawione w konstruktor klasy podrzędnej. Musi być wywoływane każdorazowo od nowa.

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