Otvorenie formulara, nazov formulara z premennej   zodpovězená otázka

VB.NET

Zdravim

Potrebujem otvorit formular, pricom nazov formulara aby bol nacitavany z databazy.

Nieco taketo:

1. Zistim nazov formulara:

Dim sql_text As String
        Dim x As string

        sql_text = "SELECT * from tab where a = " & xx.value

        Dim cmd As New SqlCommand(sql_text, connection)
        connection.Open()

        Dim reader As SqlDataReader
        reader = cmd.ExecuteReader()

        If reader.Read Then
            x = reader("formular")
        End If
        reader.Close()
        connection.Close()

2. Ziskany nazov formulara v premennej x pouzit na otvorenie formulara z takym menom

Dim f As New x
        w.Show()

Ako donutim vb aby x bralo ako formular a nie ako string?

Dik.

Karol

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

jestliže to x má být "ten" formulář nemělo by místo

Dim x as string

být

Dim x as Form

?

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

Jeden z několika způsobů jak vytvořit instanci třídy z textového řetězce je použít metodu Activator.CreateInstance.

http://msdn.microsoft.com/en-us/library/...

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

Dakujem.

Toto funguje:

        Dim objForm As Form
        Dim FullTypeName As String
        Dim FormInstanceType As Type

        ' plny nazov formulara
        FullTypeName = Application.ProductName & "." & x
        ' zistim typ
        FormInstanceType = Type.GetType(FullTypeName, True, True)
        ' vytvorim instanciu
        objForm = CType(Activator.CreateInstance(FormInstanceType), Form)
        ' zobrazim formular
        objForm.Show()

Co ale v pripade, ze potrebujem predat do formulara premenu? Robil som to takto:

        Dim objForm As Form
        Dim FullTypeName As String
        Dim FormInstanceType As Type

        ' plny nazov formulara
        FullTypeName = Application.ProductName & "." & x
        ' zistim typ
        FormInstanceType = Type.GetType(FullTypeName, True, True)
        ' vytvorim instanciu
        objForm = CType(Activator.CreateInstance(FormInstanceType), Form)
        ' vlozim premennu a zobrazim formular
        objForm.idp = "1"
        objForm.Show()

Toto konci pri kompilacii chybou, pochopitelne, formular objForm sa urci az pri behu programu. Pri kompilacii este nie je. Da sa tato chyba potlacit pripadne ako inak?

K.

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

Přetypujte to na konkrétní formulář a ne na obecný formulář System.Windows.Forms.Form. Potom budou dostupné jeho členy už v době kompilace, což uvidíte i pomocí IntelliSense.

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

Ako?

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

FormX je ta požadovaná třída formuláře.

objForm = DirectCast(Activator.CreateInstance(FormInstanceType), FormX)
nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Nechápu jak by tohle mělo tazateli pomoct. Pokud ten typ konkrétního formuláře není znám v době kompilace a je proto nutné vytvářet přes Activator (a ne přes kontruktor) tak není znám ani pro provedení toho přetypování.

Také se dá z uvedeného scénáře předpokládat, že těch konkrétních formulářů bude více, a danou vlastnost mají všichni. Pak je řešení s těmto formulářům společnou base třídou nebo interface jediné čisté (na rozdíl například od nějakého switche). Toto je zároveň přímo úplně základní ukázkový scénář na použití polymorfismu v OOP.

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

Znáte-li typ, pak znáte i konkrétní formulář. Z toho co je zde uvedené se bude jednat pouze o jediný formulář, proto není třeba implementovat žádná zbytečná řešení, jako je toto zřejmě vaším bratrem uvedené.

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

Z čeho usuzujete, že ten formulář bude jenom jeden? Kdyby byl pouze jeden, tak by asi nemělo vůbec smysl implementovat mechanizmus na to, aby mohl byl název formuláře uložen přímo v databázi a na základě těchto dat vytvořen dynamicky.

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

Z čeho usuzujete, že ten formulář bude jenom jeden?

Potrebujem otvorit formular, pricom nazov formulara

tak by asi nemělo vůbec smysl implementovat mechanizmus na to, aby mohl byl název formuláře uložen přímo v databázi a na základě těchto dat vytvořen dynamicky.

Není zde uvedeno k čemu to má být, za svoje působení zde jsem se setkal s mnohem většími hovadinami.

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

nemusi pretypovavat priamo na ten typ, staci ked pretypuje na jeho abstrakciu (rodic, intrface)

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

Pokud přetypuje na fotra toho formuláře, nebude tam mít ty vlastní členy. Pokud použije rozhraní, bude vždy muset měnit věci na dvou místech zároveň. Nedejbože aby bylo potřeba u každého formuláře něco jiného - to potom bude buď tisíce rozhraní, nebo jeden hnůj ve kterém bude nahňácané všechno.

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

Vytvořte interface pro vaše formuláře, které budou mít vlastnost idp. Přetypování proveďte na tento interface pro nastavení hodnoty idp.

Public Interface IMyForm
    Property idp() As String
End Interface

Public Class TestForm
    Implements IMyForm

    Private _idp As String

    Property idp() As String Implements IMyForm.idp
        Get
            Return _idp
        End Get
        Set(value As String)
            _idp = value
        End Set
    End Property
End Class

Dim fullTypeName As String = Application.ProductName + "." + x
Dim formInstanceType As Type = Type.GetType(fullTypeName, True, True)
Dim objForm As Form = CType(Activator.CreateInstance(formInstanceType), Form)

CType(objForm, IMyForm).idp = "1"
objForm.Show()
nahlásit spamnahlásit spam 0 / 2 odpovědětodpovědět

Zastávám podobný názor. Nemá cenu používat atomové zbraně tam, kde stačí domlouvací klacík....

Nicméně umím si představit i mnohem komplikovanější a zbytečnější řešení, toto mi příjde ještě celkem OK.

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

Máte samozřejmě pravdu. I toto "rozhraňové" řešení by se v mnoha případech osvědčilo, ovšem ne v tomto.

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

Dakujem vsetkym za rady. Nechodia mi upozornenia, takze som sa do tohto nepozrel dlhsie.

A keby som to urobil cez globalnu premennu?

Dim objForm As Form
Dim FullTypeName As String
Dim FormInstanceType As Type
 
' plny nazov formulara
FullTypeName = Application.ProductName & "." & x
' zistim typ
FormInstanceType = Type.GetType(FullTypeName, True, True)
' vytvorim instanciu
objForm = CType(Activator.CreateInstance(FormInstanceType), Form)
' vlozim premennu a zobrazim formular
idp = "1" 'globalna premenna
objForm.Show()

Funguje mi to. Pouzitie globalne premennej je az take zverstvo? A ak ano preco?

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

Ano, použití globální proměnné není (minimálně) v tomto případě vůbec čisté, a to hlavně ze dvou důvodů:

1) Globální proměnná má (jak název napovídá) globální životnost, kdežto zde je potřeba "něco", co má stejnou životnost jako ten formulář, kterému je potřeba toto nastavení při jeho vytváření předat. Takto není nijak zajištěno ani vynuceno, že proměnná bude nastavena vždy při konstrukci formuláře a i kdyby byla, tak tento požadavek není v kódu nijak vidět.

2) Tato proměnná je pouze jediná, kdežto formulářů se obecně může najednou otevírat více. Nyní je funkčnost závislá na splnění požadavku, že od doby nastavení proměnné (před objForm.Show()) až do doby, kdy si formulář proměnnou "vyzvedne", se tato globální proměnná nesmí nikde změnit (tedy například se formulář mezitím nesmí otevřít podruhé). A opět to není jinak zajištěno, vynuceno, a ani to není v kódu vidět. Opět je potřeba "něco", co je svázáno s instancí formuláře.

Obě tyto záležitosti vedou na neudržovatelný, nerozšiřitelný a nepřehledný kód se skrytými předpoklady a závislostmi.

Jediné správné řešení takovýchto případů je již výše uvedené řešení se základní třídou nebo interface. Přitom si myslím, že je to téměř úplný základ OOP, a že je to není nijak obtížné.

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

S globální proměnnou souhlasím, s tím, že je to Jediné správné řešení takovýchto případů rozhodně ne...

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

Dakujem, vsetkym.

Implementoval som interface postup.

Funguje.

Na globalne premenne uz ani nepomyslim.

Karol

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