Úvodní formulář při startu programu (splashscreen)   otázka

VB.NET, WinForms

Dobrý den,

prosím poraďte jestli to má vůbec smysl... Mám aplikaci, kde bych při jejím startu rád zobrazil nějaký úvodní formulář, tedy spíš grafiku, něco jako má třeba Photoshop, Corel, nebo nakonec i Office a tam do textboxu psal hlášky, co se děje při startu programu (např. načítám soubor xml, inicializuji rozharaní...atd.).

Když jsem zobrazil něco jako splashscreen, tak sice několik vteřin byl vidět, ale stejně se tam nic pořádně nezobrazilo, pak zmizel a naskočil normální formulář.

Dá se toto ve vb.net vůbec seriózně udělat a jak? případně nějak jinak? Poradíte prosím...?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

SplashScreen se v .NETu samozřejmě udělat dá, stačí vytvořit formulář, který se zobrazí jako první při spuštění projektu (to se dá nastavit ve vlastnostech projektu: Application > Startup Form). SplashScreen se postará o vytvoření instance hlavního formuláře aplikace, bude sledovat, jak se načítají její zdroje a informovat o tom ve svém uživatelském rozhraní dokud nedojde k načtení hlavního formuláře, který pak zobrazí. Je potřeba, aby SplshScreen rezidoval ve vlastním vlákně, hlavní formulář a SplashScreen pak musí cross-thread komunikací předávat informace o tom, jak probíhá načítání.

Také je možné použít single-instance scénář, kdy bude SplashScreen sám zdroje načítat a inicializovat (nebo bude volat nějakou jinou vrstvu aplikace, která si to vezme na starost), a v momentě, kdy jsou data připravená je předat hlavnímu formuláři, ten zobrazit a odchytit událost Show toho formuláře, aby se pak sám skryl.

Visual Studio obsahuje také jednoduchou SplashScreen šablonu. V kontextové nabídce projektu dejte Add > New Item... a v nabídce SplashScreen naleznete. Je to ale úplně k ničemu, v podstatě je to jen okno bez okraje s grafikou na pozadí, kterou byste stejně měnil.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

To jsem tak nějak intuitivně tušil...ale bylo by možné to trochu konkretizovat, nejlépe na kódu nebo je nějaký článek, která by to srozumitelně popisoval, jaké jsou možnosti...

Moc děkuji za trpělivost :-)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Upřímně, jen málo projektů úvodní okno opravdu potřebuje, protože načtení a zpracování zdrojů netrvá většinou tak dlouho, aby měl uživatel čas číst si logovací údaje a obdivovat práci Vašeho grafika nebo Vaší. SplashScreen navržený pouze z estetických důvodů vypadá takto:

' v nastavení projektu určeno jako spouštěcí formulář
Public Class SplashForm
  Public Sub SplashForm_Load() Handles Me.Load
    ' vytvoříme instanci hlavního formuláře
    With New MainForm()
      AddHandler .Shown, Sub() Me.Hide() ' schovat při zobrazení MainForm
      .Show()
    End With
  End Sub
End Class

Public Class MainForm

End Class

SplashForm a MainForm jsou samozřejmě dva různé soubory pro přehlednost. Zde načrtám pouze zobrazení MainFormu SplashFormem. UI SplashFormu je mnohem benevolentnější než u klasického formuláře, který opravdu něco dělá. Jinými slovy je pouze na Vás, jaký dojem chcete na zákazníka udělat při spouštění aplikace. Dojem z tohoto SplashFormu by byl pravděpodobně velmi zmatený, protože pouze velmi rychle problikne. Možná by stálo za to zobrazit hlavní formulář až např. za 5 sekund a i SplashScreen zobrazovat s Opacity=0 a postupně se dostat na hodnotu 1 a tím vytvořit plynulou animaci objevení se a vice-versa při zavírání SplashForm.

Nezapomeňte na to, že SplashScreen je z pohledu assembly hlavním formulářem aplikace! Ve výchozím nastavení se aplikace zavírá s ukončením hlavního formulář, ne posledního formuláře, takže je třeba v hlavním formuláři (z hlediska aplikace) zavřít schovaný SplashForm, jinak aplikace nebude vidět v liště spuštěných programů, ale pořád poběží. Druhou možností je nastavit projekt tak, aby se vypínal s posledním oknem(opět záložka s nastavením projektu), ale to má svá úskalí v některých scénářích.

Public Class SplashForm
  Public Sub New()
    ' This call is required by the designer.
    InitializeComponent()
    ' Add any initialization after the InitializeComponent() call.
    Me.Opacity = 0 ' nastavit už v konstruktoru, aby nedošlo k probliknutí
  End Sub()
  Public Sub SplashForm_Load() Handles Me.Load
    Dim ticks = 0
    Dim interval = 50 'ms
    Dim second = 1000 \ interval
    Dim amount = interval / 1000
    Dim mainForm As New MainForm()
    Dim timer As New Timer() With {.Interval = interval, .Enabled = True}
    AddHandler mainForm.Shown, AddressOf timer.Stop
    AddHandler mainForm.FormClosed, AddressOf Me.Close
    AddHandler timer.Tick, Sub()
                             ticks += 1
                             Select Case ticks
                               Case 0 To second
                                 Me.Opacity += amount
                               Case 4 * second To 5 * second
                                 Me.Opacity -= amount
                               Case Is > 5 * second
                                 mainForm.Show()
                                 Me.Hide()
                             End Select
                           End Sub
  End Sub
End Class

Tento kód se postará o trochu jemnější zobrazení SplashFormu.

Pokud přijde ke slovu zpracování dat, můžete ho nechat v konstruktoru MainForm a použít něco jako tohle: (do SplashForm_Load)

    Dim ticks = 0
    Dim interval = 25 'ms
    Dim second = 1000 \ interval ' ticks/sec.
    Dim opacityCoefficient = interval / 1000 ' opacity in-/decrement

    Dim mainForm As New MainForm() With {.Opacity = 0} ' opacity proti probklinutí
    Dim timer As New Timer() With {.Interval = interval, .Enabled = True}
    Dim loaded = False

    AddHandler timer.Tick, Sub()
                             ticks += 1
                             Me.Opacity += If(loaded, -opacityCoefficient, opacityCoefficient)
                             If ticks = second Then
                               If Not loaded Then mainForm.Show()
                               timer.Enabled = False
                             End If
                           End Sub

    AddHandler mainForm.Shown, Sub()
                                 mainForm.Opacity = 1
                                 mainForm.Focus()
                                 ticks = 0
                                 loaded = True
                                 timer.Enabled = True
                               End Sub
    AddHandler mainForm.FormClosed, AddressOf Me.Close

Toto jemně zobrazí SplashForm, počká na zobrazení MainForm (tzn. i provedení konstruktoru a Load metody - zpracování dat) a pak jemně schová SplashForm.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

SplashScreen se postará o vytvoření instance hlavního formuláře aplikace, bude sledovat, jak se načítají její zdroje

No to je doufám nějaký špatný vtip. S touto filozofií můžete rovnou celou funkčnost programu předat oknu O aplikaci...

Neraďte prosím nesmysly, protože by to tak někdo v dobré víře mohl skutečně udělat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Za případnou desinformaci se omlouvám, budu rád, pokud mne náležitě opravíte.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Celý problém se dá řešit poměrně jednoduše ze spouštěcího modulu (Sub Main) za cenu ztráty Application Frameworku, nebo lépe z Load události hlavního formuláře. Záleží na architektuře aplikace.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Jen doplním, že pokud bychom mluvili o WPF, tam se SplashScreen vytváří tak, že se do zdrojů aplikace přidá obrázek, kterému se nastaví BuildAction na SplashScreen. Tento obrázek se zobrazuje nativním kódem během vytváření instance aplikace.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Takže podobně jako nastavení SplashScreen formuláře ve Windows Forms. To je k ničemu, protože nad tím není žádná kontrola. Hodí se pouze pro velmi jednoduché věci.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nešlo by to ukázkou kódu...?

Děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Na něco takového je zbytečné psát ukázku kódu. Zobrazení úvodního okna nemodálně dejte do události Load hlavního formuláře, pokud bude potřeba ho automaticky zavřít po určité době, to se udělá pomocí Timeru. Stavové zprávy do něj můžete předávat pomocí nějaké Public String vlastnosti.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback