Zamykanie okien w C#


(Jarek P) #1

Cześć.

Piszę pewien program, w którym mam dwa okna. (C#)

I teraz pytanie:

Mam okno główne, po którego wyłączeniu program kończy się.

Ale co trzeba zrobić, żeby program zakończył działanie po zamknięciu okna pobocznego ?


(slepcu) #2

dodaj do tego bocznego okna zdarzenie Form.onClose (albo podobnego bo nie pamietam juz) w którym wywołaj:

Application.Exit();

(Tomek Matz) #3
  1. Dlaczego chcesz zamykać program po zamknięciu okna pobocznego?

  2. To okno poboczne to okno dialogowe, czy okno aplikacji MDI?


(Jarek P) #4

Dzięki Slepcu. Działa.

ad do matzu:

  1. Robię okno hasła

2.Zwykła formatka


(Tomek Matz) #5

AD 1. Czyli w momencie, gdy użytkownik się już zaloguje, to nie może zamknąć tego okna, bo wyłączy całą aplikację?


(somekind) #6

Jeszcze nie widziałem, żeby okno hasła było dostępne po zalogowaniu, ono zawsze znika.


(Tomek Matz) #7

Niby mnie zacytowałeś, ale to co napisałeś ma się nijak do tego co ja pisałem :expressionless:

Dodam jeszcze tylko (choć nie ma to nic do rzeczy odnośnie problemu autora tematu), że można napisać aplikację, w której użytkownik będzie posiadać możliwość zalogowania się w dowolnym momencie w celu podniesienia uprawnień, a jeśli tego nie zrobi, to będzie po prostu posiadać domyślne uprawnienia, tzn. takie jak każdy inny użytkownik, który uruchomi daną aplikację. Na prawdę nie jest to nic niezwykłego.


(somekind) #8

Tak? To o które okno Ci chodziło w poście z 07.10.2011 (Pt) 20:34?

Dla mnie sprawa wygląda tak, że uruchamia się okno aplikacji oraz okno logowania. Po poprawnym zalogowaniu, okno logowania znika, a okno aplikacji zostaje. Jeśli jednak zamiast się zalogować użytkownik zamknie okno logowania, to zamknięta zostaje cała aplikacja. I nic w tym dziwnego nie ma.


(Tomek Matz) #9

O okno logowania, ale powtarzam jeszcze raz ... to co napisałeś ma się nijak do tego co ja napisałem (a przynajmniej do tego o co mi chodziło). Być może dlatego autor tematu mi nie odpisał, bo niejasno się wyraziłem. W każdym bądź razie oba rozwiązania jakie można tu zastosować opisałem poniżej.

Moim zdaniem są dwie możliwości zaimplementowania takiego logowania:

  1. Pojawia się okno dialogowe i w zależności od reakcji (OK lub Cancel) pojawi lub nie pojawi się główne okno aplikacji. Oczywiście w sytuacji podania niepoprawnych danych potencjalny użytkownik aplikacji zostanie jeszcze raz poproszony o podanie loginu i hasła (czynność będzie powtarzana aż do skutku, blokady programu lub naciśnięcia przycisku Cancel). Istotne przy tym jest, że niepojawienie się głównego okna aplikacji zostanie załatwione przez wywołanie metody Close w zdarzeniu Load tego okna, a nie przez wywołanie Application.Exit gdzieś tam nie wiadomo gdzie.

  2. Rozwiązanie, które opisywałem przed chwilą. Pojawia się od razu główne okno aplikacji. Użytkownik otrzymuje domyślne ograniczone uprawnienia (np. tylko możliwość przeglądania danych). W momencie, gdy użytkownik zaloguje się w oknie, które otworzy z poziomu menu aplikacji, jego uprawnienia zostaną zwiększone (np. pojawi się możliwość edycji danych). Użytkownik w dowolnym momencie może się wylogować lub zalogować jako zupełnie inny użytkownik. Istotne przy tym jest, że nie będzie występować sytuacja, w której główne okno aplikacji nie zostanie wyświetlone. Jeśli użytkownik się wyloguje, to ponownie zostaną mu przyznane domyślne uprawnienia.

Co do tego co Ty napisałeś (a przede wszystkim autor tematu). Ja osobiście nie widziałem aplikacji, w której na raz użytkownikowi pojawiają się dwa zwykłe okna (dwie zwykłe formatki) i jedno z nich to okno logowania. Wynika z tego, że użytkownik może sobie dłubać w aplikacji bez logowania, ale jeśli zamknie okno logowania to zamknie okno aplikacji. To się nie trzyma kupy.


(somekind) #10

Piszesz o wywołaniu Close w Load jednej formatki? Bardzo dziwne i nieładne rozwiązanie.

Po pierwsze, to w takiej sytuacji Prezenter (albo inna klasa z warstwy odpowiedzialnej za sterowanie GUI) nie powinna wywołać głównego okna aplikacji. A jeśli mamy do czynienia z jednowarstwowym programikiem, to po prostu jeśli Form logowania zwróci DialogResult.Cancel, nie jest nawet tworzony obiekt głównej formatki, a wszystko to może odbyć się w metodzie Main.

Takiego rozwiązania ja z kolei nigdy nie widziałem. Aplikacje okienkowe wymagające logowania, wymagają go do jakiejkolwiek czynności, bo są one jakimiś stosowanymi wewnątrz firm systemami do jej obsługi, więc siłą rzeczy dostęp do firmowych danych i operacji na nich mogą mieć tylko zalogowani pracownicy. Natomiast szerokodostępne programy użytkowe typu edytor tekstu czy odtwarzacz audio funkcji logowania w ogóle nie potrzebują. W zasadzie jednymi tego typu programami są chyba komunikatory internetowe dające możliwość zabezpieczenia swojego profilu hasłem. Co innego aplikacje internetowe, których cała masa ma część funkcjonalności dostępną dla zwykłych, a część dla zalogowanych użytkowników.

Nie neguję istnienia programów desktopowych z częścią funkcjonalności dostępną od razu, a częścią po zalogowaniu, ale ani nigdy się z takimi nie spotkałem, ani nie bardzo widzę sensu takiego rozwiązania. Możesz podać jakiś przykład?

Oczywiście, że nie trzyma się kupy. Ale tylko dlatego, że wyciągnąłeś bezpodstawny wniosek, że użytkownik ma dostęp do funkcji aplikacji bez zalogowania, mimo że wcale tak nie jest. Okno logowania w takiej sytuacji jest modalne i użytkownik nie ma dostępu do reszty programu.

Dlaczego takie rozwiązania się stosuje, to nie wiem, być może użytkownikowi łatwiej jest zauważyć na ekranie duże okno programu niż małe okienko logowania, albo po prostu ktoś kiedyś zrobił taki prototyp aplikacji, a klient to zaakceptował i tak już zostało. W każdym razie takie aplikacje są na świecie.

Zresztą, podobny efekt można zaobserwować w przypadku niektórych triali po wygaśnięciu okresu testowego. Pojawia się wówczas główne okno aplikacji oraz okno modalne z prośbą o podanie klucza rejestracyjnego. W przypadku kliknięcia "Anuluj" albo zamknięcia tego okienka zamyka się również cała aplikacja.


(Tomek Matz) #11

AD 1. Można prosić o krótki fragment kodu z modyfikacją Main? Z góry dzięki.

AD 2. Jeśli chodzi o przykład aplikacji, w której zastosowano by ten drugi sposób logowania opisany przeze mnie wyżej ... w sumie już podałem, ale powtórzę :slight_smile: Aplikacja bazodanowa, w której niezalogowany użytkownik może sobie np. tylko przeglądać dane/raporty/wykresy (i to niekoniecznie od razu wszystkie), a zalogowany może np. mieć dostęp do pozostałych danych/raportów/wykresów, i dodatkowo może edytować dane.

AD 3. Autor tematu wyraźnie napisał, że ma dwie zwykłe formatki, a nie formatkę i okno dialogowe. Pytałem przecież o to w jednym z poprzednich postów. Wnioski nie były więc bezpodstawne. Jeśli Ty (w przeciwieństwie do autora tematu) miałeś na myśli sytuację, w której jedno z dwóch okien, to okno dialogowe, to oczywiście jest to trochę inna sytuacja. Wciąż jednak nie widzę sensu wyświetlania użytkownikowi czegoś, do czego i tak nie powinien mieć dostępu dopóki się nie zaloguje. Mnie osobiście nie przekonuje stwierdzenie "być może użytkownikowi łatwiej jest zauważyć na ekranie duże okno programu niż małe okienko logowania, albo po prostu ktoś kiedyś zrobił taki prototyp aplikacji, a klient to zaakceptował i tak już zostało". Mocno naciągane wyjaśnienie.


(somekind) #12

Ad 1. Proszę bardzo.

Oto kod okna logowania:

using System;

using System.Windows.Forms;


namespace LoginSample

{

    public partial class FormLogin : Form

    {

        public FormLogin()

        {

            InitializeComponent();

            this.DialogResult = DialogResult.Cancel;

        }


        private void btnOk_Click(object sender, EventArgs e)

        {

            // tutaj oczywiście sprawdzenie czy login i hasło istnieją w bazie, jeśli nie to komunikat i prośba o poprawienie danych, itp.

            if (true) // dla przykładu zakładamy, że się udało

            {

                this.DialogResult = DialogResult.OK;

                this.Close();

            }

        }

    }

}

A to w Program.cs:

using System;

using System.Windows.Forms;


namespace LoginSample

{

    static class Program

    {

        [STAThread]

        static void Main()

        {

            Application.EnableVisualStyles();

            Application.SetCompatibleTextRenderingDefault(false);


            using (FormLogin fl = new FormLogin())

            {

                fl.ShowDialog();

                if (fl.DialogResult == DialogResult.OK)

                {

                    Application.Run(new FormMain());

                }

            }

        }

    }

}

Ad. 2. Chodziło mi bardziej o konkretny przykład programu użytkowego, a z Twojego opisu wynika jedynie założenie istnienia takiego programu gdzieś na świecie. Naprawdę nie sądzę, aby taka aplikacja wewnątrzfirmowa miała rację bytu, bo w ten sposób dostęp do danych firmy mogłaby uzyskać nawet sprzątaczka. Coś takiego byłoby czymś naprawdę niezwykłym.

Ad. 3.:

1) Autor odpowiadając na Twoje pytanie stwierdził, że jego formatka nie jest oknem MDI, a o to pytałeś, prawda? W ogóle Twoje pytanie było źle skonstruowane, bo zakłada istnienie jedynie dwóch typów okien, co nie jest prawdą.

2) Okno logowania jest oknem dialogowym z definicji, bo służy do uzyskania od użytkownika pewnych danych.

3) Nie ma znaczenia, czy formatka jest "zwykła" czy nie, bo każdą da się wyświetlić jako okno modalne lub niemodalne, odpowiednio metodami "ShowDialog" lub "Show".

Czy ja wiem, czy naciągane, takie rzeczy się po prostu zdarzają. A jeśli klientowi to pasuje, jest do tego przyzwyczajony, płaci za to i nie chce zmian, to tak ma być i już. Nikomu to nie szkodzi, ani nie powoduje żadnych problemów.


(Tomek Matz) #13

AD 1. Dzięki za przykład, choć w sumie dziś już na ten temat poczytałem ciekawą dyskusję http://stackoverflow.com/questions/1629205/windows-forms-create-the-main-application-after-login-which-form-to-run. Rozwiązanie oparte o ApplicationContext jest ciekawe.

Mam pytanie do Twojego kodu ... czemu zakres using (FormLogin fl = new FormLogin()) obejmuje też Application.Run?

AD 2. Do każdego komputera firmowego trzeba się wpierw zalogować. Nie wyobrażam sobie sytuacji, w której dostęp do danego komputera ma każda osoba.

AD 3. Tu się robi do niczego nie prowadząca dyskusja.

Pytanie było, czy jest to okno aplikacji MDI, czy okno dialogowe (pierwszy mój post w tym temacie). W odpowiedzi dostałem, że jest to zwykła formatka. No przecież to jest wyraźnie napisane, nie powtarzajmy się :slight_smile: BTW jakie typy okien masz na myśli?

Moje pytania miały na celu naprowadzić autora tematu na ten sam wniosek (niestety mi się to nie udało).

Zgadza się, ale zapomniałeś o jednym. Okno dialogowe charakteryzuje się innymi właściwościami, np. brakiem przycisku min/max.

To, że coś występuje, nie oznacza, że jest dobrym rozwiązaniem. Jeśli klient sobie takie coś zażyczy, to trzeba go przekonać, że takie rozwiązanie nie ma sensu.


(somekind) #14

Nie rozumiem zastosowania ApplicationContext tutaj, podobnie jak nie widzę sensu jest tworzenie jednego okna w konstruktorze drugiego. To tylko niepotrzebne komplikacje. Przecież jeśli ktoś zamknie okno logowania, to znaczy, że nie chce się zalogować i proces aplikacji nie jest mu do niczego potrzebny.

Bo to jest prosty przykład mający na celu pokazanie koncepcji. :slight_smile:

Oczywiście, że trzeba. Tak samo jak trzeba się zalogować do programu pocztowego, jak i do wszelkich używanych przez firmę systemów. A przynajmniej zazwyczaj trzeba.

Też bym Ci tak być może odpowiedział, bo dla mnie zwykła formatka, to formatka, która nie jest MDI, ale nadal może być oknem dialogowym. Masz pewność, że autor zrozumiał Twoje nieprecyzyjne pytanie?

Potrafię sobie wyobrazić okno dialogowe dla opcji zaawansowanego szukania z kilkudziesięcioma kontrolkami do nakładania filtrów i wyposażone w przycisk maksymalizacji. :slight_smile:

Pod warunkiem, że faktycznie nie ma sensu i jest złym rozwiązaniem, czyli np. niepotrzebnie komplikuje działanie aplikacji albo powoduje zagrożenie bezpieczeństwa. A to jest po prostu kwestia gustu. Gdyby klient chciał różowy program z zielonymi tekstami, to też trzeba mu taki zrobić, a nie tłumaczyć, że będą go bolały oczy. :wink:


(Tomek Matz) #15

Mimo tego, że możliwy jest anonimowy dostęp do aplikacji (a przynajmniej do niektórych jej elementów), to wciąż nie jest tak, że dosłownie każdy może z niej skorzystać, co sugerowałeś w swoim poprzednim komentarzu.

Dla mnie zwykła formatka, to taka, która nie powoduje zablokowania głównego okna aplikacji (w przeciwieństwie do okna dialogowego). Rozumiem, że się z tym nie zgadzasz, no cóż :slight_smile: Sęk w tym, że powinieneś ten problem poruszyć w swoim pierwszym poście skierowanym do mnie. Oszczędzilibyśmy sobie czasu, bo tak Ty mówiłeś o jednym, a ja o drugim. Pytanie wydawało mi się jasno postawione - czy to okno poboczne to jest okno dialogowe, czy okno aplikacji MDI?. W odpowiedzi dostałem wariant trzeci, że zwykła formatka, którą faktycznie też można uczynić oknem pobocznym (choć w sumie osobiście nie pamiętam kiedy takie rozwiązanie stosowałem, ale teoretycznie może ono mieć zastosowanie).

Ja sobie też potrafię takie coś wyobrazić. Sęk w tym, że tak się po prostu nie robi. Jeśli okno dialogowe zawiera kilkadziesiąt różnych kontrolek, to rozmieszcza się je w różnych sekcjach. To jest powszechnie przyjęta praktyka. Przykład masz przecież chociażby w Visual Studio. Przejdź do Tools -> Options.

No cóż, to jest Twoja opinia. Ja się z nią zupełnie nie zgadzam, ale w sumie napisałem to już w poprzednim swoim komentarzu. Gdyby ktoś kazał mi w pracy nieustannie wyczyniać takie cuda przy tworzonych programach, to zacząłbym szukać nowej.


(somekind) #16

A jeśli użytkownik nie zablokuje stacji? Dla takich właśnie sytuacji stosuje się klika poziomów logowania.

To nie ja się z tym nie zgadzam. Po prostu Ty uważasz okno dialogowe i modalne za jedno, i to samo, tymczasem wcale tak nie jest. Okno dialogowe nie musi być modalne, chociaż zapewne większość taka jest. Widziałeś może program, który nazywa się GIMP? Tam obok głównego okna jest bardzo dużo okien dialogowych i nie są one modalne. Zresztą, w innych programach graficznych jest podobnie.

Albo wariant pierwszy, czyli okno dialogowe, które też jest zwykłą formatką, a nie formatką MDI. :slight_smile:

To, że Ty czegoś takiego nie robiłeś, to nie znaczy, że się nie robi. :slight_smile: Mi się zdarzało pracować z takimi systemami, a skoro tak były skonstruowane, to widocznie było to wygodne dla użytkownika. (Być może dlatego, że szybciej jest przeskakiwać między polami TABem niż rozwijać różne podgrupy.)

Nie wiem jakie masz doświadczenie zawodowe, ale taki komentarz świadczy o tym, że raczej niewielkie, bo cuda to słowo, którego używa się dla dużo dziwniejszych rzeczy.

Inny niż uznawany przez Ciebie sposób tworzenia okna logowania absolutnie na to słowo nie zasługuje.


(Tomek Matz) #17

A jeśli użytkownik nie wyloguje się z aplikacji? A jeśli użytkownik poda swoje hasło innemu użytkownikowi? A jeśli użytkownik wyniesie dane z firmy na pendrvie/CD lub nawet cały dysk twardy? Od tego są procedury bezpieczeństwa, aby się do nich stosować. Pewnych rzeczy nie jesteś w stanie zabezpieczyć na poziomie aplikacji, choćbyś bardzo tego chciał.

Fakt, masz rację, okno dialogowe nie musi być wcale modalne. Rzeczywiście pytanie było przeze mnie źle postawione. Szkoda, że dopiero po kilkunastu postach do tego doszliśmy, ale to nic :slight_smile:

Patrz wyżej.

Patrz wyżej. Pisząc o oknach dialogowych miałem cały czas na myśli okna modalne. Ty zapewne pracowałeś ze zwykłą formatką. Niemniej umieszczanie kilkudziesięciu pól na jednym oknie, to ciekawy pomysł. Z pewnością znajdowanie jednego z tych pól, które w danym momencie jest potrzebne, to niezła zabawa :slight_smile: Generalnie takie rozwiązanie (jeśli faktycznie takie sobie zażyczył klient) nadaje nowe znaczenie terminowi user-friendly. Ale chociaż te kontrolki były podzielone na jakieś grupy/sekcje (przy użyciu, np. kontrolki GroupBox)? Czy po prostu wszystko zostało wrzucone do jednego worka?

Jeszcze raz, bo się nie zrozumieliśmy. Mój post mówił o tym, że osobiście zastanowiłbym się dwa razy czy chcę pracować w firmie, która zmusza/nakazuje/whatever mnie do akceptowania każdej zachcianki klienta (choćby była kompletnie absurdalna, jak wspomniany przez Ciebie "różowy program z zielonymi tekstami" - jeśli to nie są cuda, to czym w takim razie dla Ciebie one są?). Jeśli nie masz nic przeciwko takim zachciankom, to przecież Twoja sprawa i nic mi do tego. Ja tylko wyraziłem swoją opinię :slight_smile:


(somekind) #18

Graj mniej w szachy, to Ci się refleks poprawi. :wink:

Nie wnikam w skłonności do zabaw klienta. :slight_smile: A poza tym jest też opcja szukania podstawowego.

Były ładne posegregowane według pewnych grup związanych ze sobą danych w GroupBoxach.

To nie są cuda - to są wymagania klienta.

Z takim podejściem można nigdy nie znaleźć pracy, bo firmy są od spełniania zachcianek klientów. Zwłaszcza że to, co wygodne dla programisty, nie musi być wygodne dla klienta.

Nie mam prawa mieć cokolwiek przeciwko takim zachciankom. To tak, jakbym był malarzem i ktoś mnie zatrudnił do pomalowania domu na granatowo, a ja bym odmówił, bo nie lubię tego koloru. To dopiero absurd.


(Tomek Matz) #19

A to dobre :slight_smile:

Ok, to może być. Jeśli dana osoba często korzysta z takiego okna, to umieszczenie wszystkich kontrolek w jej polu widzenia jest uzasadnione.