Dynamiczna zmiana zawartości okna Form

Chyba może się zmienić, ale na pewno dwa różne obiekty nie będą miały tego samego jednocześnie.

Aha rozumiem, bo ty posługujesz się tylko 1 zdarzeniem Click dla wszystkich buttonów i “podpinasz” za pomocą własności Tag referencję obiektu (tzn. w zależności od tego jaki button nacisnę to on jest źródłem zdarzenia i przekazuje swój Tag) :wink:

No to chyba faktycznie lepsze rozwiązanie - nie trzeba wiele pisać (tzn. robić osobnych zdarzeń).

Myślę, że skorzystam z obu sposobów tzn. z tworzeniem obiektów za każdym razem (a więc i niszczeniem ich), ale także stworzę je w programie i zapamiętam - tak aby wpisane wartości tam były. Może mi to posłużyć np. do przechowywania informacji o konfiguracji np. ktoś wpisał swój login, hasło, albo lokalizację pliku i mógłby tam później zajrzeć i zobaczyć co poprzednio wpisał - te dane będą bardzo rzadko (o ile) w ogóle zmieniane, więc myślę że to ma sens :slight_smile:

Faktycznie - takie proste :slight_smile: Rozumiem, że w C# jest tak, że obiekt jest niszczony w momencie gdy nie ma do niego żadnego przypisania.

Tzn. Jeżeli miałem Button nowy = new Button(); i inicjowałem nowe obiekty - to poprzednie są usuwane (czy zalegają one w pamięci …) ???

Rozumiem, że chodziło o to co jest zawarte w drugim programie matzu - ale jest to bardzo zbliżone do pierwszego sposobu (tylko nieco inaczej zapisane)…

Rozumiem, że tutaj zadaniem słownika (Dictionary) jest kojarzenie nazwy Buttonu z jego referencją tzn. za pomocą nazwy wywołuję referencje (czy coś podobnego)…

Myślę, że okno będzie faktycznie miało możliwość powiększania - czy w takim wypadku, jeżeli zrobię np. button w UserControl1 o rozmiarach 100x100 to po powiększeniu okna zwiększy on proporcjonalnie swoje rozmiary ?

Nie chciałbym sytuacji, aby ktoś po powiększeniu okna zastał mikroskopijne przyciski …

Program nie będzie przechowywał tylko ustawień, ale będzie miał właśnie np. funkcje dodawania klienta itp…czyli wartości będą kasowane i przechowywane (w zależności od okna - ale teraz już wiem jak to zrobić :stuck_out_tongue: ).

A jak w takim razie zrobić w tym drugim programie, aby słownik był po referencji do obiektu a nie po nazwie ?

Naszło mnie jeszcze jedno pytanie - nie związane do końca z problemem tego tematu - chodzi o to, że chciałbym zrobić aby jakiś obiekt np. obrazek przesuwał się z lewego rogu na prawy i aby możliwa była cały czas interakcja.

Tzn. jeżeli zrobię to w pętli for - to cały program aktualnie przestaje działać, dopóty zakończy się wykonywanie pętli - a ja chciałbym aby ktoś mógł w międzyczasie np. zatrzymać przesuwanie obrazka czy wykonać kilka innych funkcji (pomijam tutaj raczej if’y w pętli for - może jest inny sposób) ?

Myślałem o zastosowaniu timera, ale wydaje mi się to także trochę “naciągane” :smiley: ?

PS : A znacie może jakieś fajne “ładne” dodatki do urozmaicenia programu np. aby zrobić jakieś ładne menu, albo efekty (jak np. z

) - oczywiście chodzi o Visual Studio C# 2010 ) ?

Nie wiem, czy dobrze mnie zrozumiałeś. Ja pisałem o sytuacji, w której nie wiesz, czy obiekt jest już stworzony czy nie, a to można stwierdzić sprawdzając czy jest nullem. Dopóki nie ustawisz wartości jakiejś zmiennej (referencyjnej), to jest ona nullem. Oto przykład:

TextBox textBox;


private void CośtamClick(object sender, EventArgs e)

{

    if (this.textBox != null) // jeśli kontrolki jeszcze nie było

    {

        this.textBox = new TextBox(); // tutaj też trzeba ustawić Size, Location, itd

        this.panel.Add(this.textBox);

    }

    this.textBox.Show(); // bo tego potrzebujesz zawsze do pokazania kontrolki

}

Pytasz, kiedy w C# niszczony jest jakiś obiekt, to dość skomplikowana kwestia, bo zajmuje się tym GarbageCollector, który działa według własnego uznania. Ale jeśli ustawiasz dla swojego obiektu wartość null, to pamięć po nim zostanie za jakiś czas zwolniona.

Niezupełnie. Słownik, o którym pisałem ma kojarzyć referencję Buttona z referencją odpowiedniej UserControl, zamiast trzymania jej jako Tag Buttona.

Jeśli ustawisz w UserControl1 właściwość Dock na Fill, to po zwiększeniu zostanie ona rozciągnięta w Panelu, na którym się znajduje.

Przyciski nie zmieniają swoich rozmiarów przy zmianie rozmiarów okna. Jeśli chcesz osiągnąć taki niespotykany efekt (chociaż jak znam @matzu, to zaraz znajdzie program, w którym to się dzieje ;P), to chyba powinieneś ustawić właściwość Anchor buttona na wszystkie cztery strony.

Myślę, że to w miarę dobry pomysł. Działanie Timera nie zamrozi aplikacji, więc powinna być możliwa interakcja.

Tam przede wszystkim masz aplikację WPF, w których łatwiej robić takie cuda niż w WinFormsach, o których piszemy. Dla tej technologii istnieją biblioteki, które umożliwiają ulepszanie wyglądu kontrolek, ale są one zazwyczaj płatne (DevExpress, Telerik, itp.).

Dokładnie o to chodziło.

Obiekt form-y powinien być niszczony, gdy już nie jest potrzebny. Nie ma sensu trzymać go w aplikacji, bo nie wiesz kiedy ponownie - i czy w ogóle - użytkownik z niego skorzysta. Wartości wprowadzone przez użytkownika w polach form-y powinieneś zapamiętywać w innym miejscu np. w pliku konfiguracyjnym użytkownika (Settings), bazie danych, jakimś swoim pliku XML (lub zwykłym tekstowym), czy chociażby w obiekcie specjalnej klasy (jeśli dane te nie muszą być dostępne po zakończeniu działania aplikacji). W momencie, gdy użytkownik ponownie otworzy formę, to wypełnisz jej pola (kontrolki) w oparciu o dane zgromadzone w jednym z ww. miejsc.

Tak długo jak masz dostęp do obiektu, tak długo będzie on trzymany w pamięci. W momencie, gdy do zmiennej nowy przypisujesz nowy obiekt, tracisz dostęp do tego wcześniej utworzonego, tym samym zostanie on usunięty z pamięci. Sęk w tym, że nie masz kontroli nad tym kiedy dokładnie to nastąpi. Tak jak pisał somekind zajmuje się tym Garbage Collector.

I jeszcze jedno … o ile to możliwe staraj się zwalniać zasoby ręcznie poprzez wywołanie metody Dispose. Kiedy należy wywoływać tą metodę możesz przeczytać m.in. tutaj http://blogs.msdn.com/b/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx

Jeśli będzie możliwa zmiana rozmiaru okna to musisz (albo raczej możesz) używać właściwości Dock i Anchor (właśnie dzięki nim uzyskasz zwiększanie rozmiaru poszczególnych kontrolek). Zrób sobie ten prosty przykład http://msdn.microsoft.com/en-us/library/991eahec%28v=VS.100%29.aspx to Ci się to rozjaśni.

Wciąż możesz korzystać ze szkieletu, który wcześniej wrzuciłem. Wprowadź tylko w kodzie drobną poprawkę

if (!mainPanel.Controls.Contains(userControl))

{

    mainPanel.Controls.Add(userControl);

    userControl.Dock = DockStyle.Fill;

}

Dodam tutaj, że możliwe jest zablokowanie zmniejszania rozmiaru okna do pewnego ustalonego (właściwość MinimumSize). Możesz to ustawić po to, aby uniemożliwić użytkownikowi zmniejszanie rozmiaru okna do takiego, przy którym nie widać wszystkich kontrolek (możesz, ale nie musisz). Takim punktem odniesienia może być domyślny rozmiar Form-y (czyli ten, który masz aktualnie ustawiony w Visual Studio).

Wystarczy, że zamienisz private Dictionary userControlDictionary; na private Dictionary userControlDictionary; . Kompilator wskaże Ci gdzie jeszcze musisz wprowadzić poprawki.

Timer jak już pisał somekind jest OK. Może to też być pętla (choć Timer daje Ci w sumie większą kontrolę). Generalnie chodzi o to, żeby to przesuwanie obrazka puścić w innym wątku niż główny wątek aplikacji.

Ale może lepiej wykorzystać w tym celu wątki - jeszcze nie wiem jak to zrobić… (czy byłoby to ciężkie) ?

A może faktycznie lepszym rozwiązaniem jest timer, ale gdybym chciał poruszać kilka obiektów to musiałbym dać kilka timerów (jeżeli każdy ma działać w innym takcie zegara).

Program będę robił właśnie w WPF (dopiero zaczynam z nim przygodę), a nie ma jakiś darmowych komponentów, albo rzeczy które to ułatwią :slight_smile: Może jednak się coś znajdzie, aby urozmaicić wygląd aplikacji np. jakieś efekty, wygląd lub animacje …?

O wątkach muszę jeszcze poczytać, chyba że macie jakiś prosty przykład jak zrobić nowy wątek - tak aby cała aplikacja się nie zatrzymała (tylko coś działało w tle).

Żeby zrobić to na wątkach musiałbyś je opakować tak, aby bezpiecznie synchronizowały się z interfejsem i były w miarę zgrabne w użyciu. Czyli w efekcie napisałbyś coś, co już jest - Timera.

W takim razie cały ten wątek do niczego Ci się nie przyda. To dziwne, że pytasz o jedną technologię, a chcesz robić w innej.

A to dlaczego - przecież w WPF wszystko działa tak samo tylko dochodzi XAML z tego co kojarzę ? Dla mnie przydało się i to bardzo co tutaj jest napisane :slight_smile:

W WPF zupełnie inaczej tworzy się GUI, inaczej wygląda zagnieżdżanie kontrolek i ich pozycjonowanie na ekranie. Nie stworzysz Panela, a kontrolki nie mają właściwości Dock ani Anochor, do podkontrolek nie odwołuje się poprzez kolekcję Controls. Co zatem działa tak samo, skoro wszystko odbywa się inaczej?

W takim razie lepiej pisać Windows Forms czy WPF ?