Dědění formuláře   zodpovězená otázka

VB.NET

Pracuji ve VB2005 EE.

V tématu

http://www.vbnet.cz/forum-tema--988-dedi...

se řeší dědičnost formulářů s doporučením přepsat v definici potomka název jeho předka z Form na název formuláře, který chci dědit. Zkoušel jsem upravovat kód formuláře vytvořený designerem, tam je totiž původní definice Inherits System.Windows.Forms.Form, ale se zvláštními důsledky.

Vytvořil jsem si jakousi šablonu pro formuláře, na které mám pět komponent Datagridview (u všech je nastavena hodnota AutoGenerateColumns na True a všechny sloupce se vytvářejí na základě podkladového DataSource při běhu programu)a pár Buttonů. Tato výbava má zajišťovat základní funkcionalitu a bude pro všechny další formuláře shodná. Pak jsem založil prázdný nový formulář a provedl přepsání definice třidy dle návodu Tomáše Jechy ve výše uvedením tématu. Zpočátku se vše jevilo pěkně, zděděný formulář obsahoval "zamčené" komponenty svého předka, šel spustit, daly se do něj přidávat další komponenty při zachování funkcionality bázové třídy. Ale v jednom okamžiku se "sám" změnil kód vytvářený designerem v tom smyslu, že tam přibyla hromada komponent typu DataGridViewTextBoxColumn, které evidentně podle názvů pocházely z datového zdroje, jenž se do jednotlivých DataGridVieW načetl při spuštění programu. Je to pro mě velká záhada. Díky za případnou odpověď.

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

Pravidlo číslo 1:

NIKDY NEZASAHUJTE DO KÓDU VYTVOŘENÉHO DESIGNÉREM, vámi provedené změny v něm mohou kdykoliv zmizet.

Pokud potřebujete přidat kód do třídy vytvořené designérem, použijte Partial Class v samostatném souboru...

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

Ano, obecně platí, že kód v designer souboru by se neměl upravovat, pokud neznáte přesné chování designéru. Ale tato úprava (změna bázové třídy v partial souboru - například Form1.vb) by neměla zapříčinit to, co říkáte. Není možné, že jste provedl nějakou neobvyklou úpravu? Ta chyba se vyskytla v pobodě "rozskočení" jen jednou nebo nyní již pokaždé? Dědění formuláře používám často a hojně a nidky jsem takový problém nezaznamenal.

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

Pravidlo číslo 1 znám, chápu a doposud jsem je beze zbztku respektoval. Mám-li však na doporučení Tomáše Jechy provést změnu předka z Form na svoji šablonu, kde jinde to mohu udělat než v kódu pro designer? Zkoušel jsem to vícekrát tak říkajíc od nuly, tedy přidal jsem si do projektu nový formulář a změnil v kódu pro designer pouze text System.Wndows.Forms.Form na frmVzor (název mého formuláře-šablony). Vše fungovalo dobře, akorát po prvním spuštění, když se do všech DataGridView načetla reálná data z podkladové databáze, zůstala tato data i po ukončení programu v návrhovém zobrazení vidět ve všech Datagridview tam, kde normálně bývá jen prázdný obdélník. V kódu designeru bylo vše OK. Až po několikerém spuštění se najedou objevily v kódu designeru popsané definice všech sloupců.

Zajímavé je, že pokud jako předka zadám jiný svůj formulář-šablonu, který má pouze jednu komponentu DataGridView, žádné popsané podivnosti se nedějí a vše chodí dlouhodobě jak má...

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

Ale v designéru nic neměňte (například Form1.designer.vb). Toto se mění v souboru s kódem (například Form1.vb).

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

V souboru s kódem to nemohu ZMĚNIT, protože po přidání prázdného formuláře je kód prázdný, resp. je tam

Public Class Form1
End Class

Ono inkriminované Inherits System.Windows.Forms.Form je implicitně právě v kódu pro designer.

Pokud to DOPÍŠU do kódu 'Form1.vb', tak mi překladač vynadá:'Error 16 Base class 'frmVzor' specified for class 'Form1' cannot be different from the base class 'System.Windows.Forms.Form' of one of its other partial types.'

Pakliže nepřidám novou formulářovou třídu metodou 'Add-Windows Form', ale vytvořením 'Add Class', pak mohu dopsat Inherits frmVzor ale neudělá se automaticky kód pro designer. Teď koukám, že si mohu návrhové zobrazení i u takovéto třídy přepnout pravým tlačítkem myši v Solution exploreru, ale přidám-li zde na formulář nějaký prvek, pak jej po spuštění nevidím a zase mi po spuštění zděděného formuláře za chvíli do kódu "někdo" napere tu hromadu nesmyslů resp. TextBoxColumnů. Přidám-li nějaký prvek v události load:

Dim btn As New Button
  Me.Controls.add(btn)

tak je viditelný a funkční.

Uff.

Nějak se už dva dny nemohu hnout z místa. Nejdřív ty ComboBoxColumny ( http://www.vbnet.cz/forum-tema--2203-dat... )a teď tohle..

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

Neznáte rozdělené třídy (Partial Classes). Kód třídy může být rozdělen do několika souborů pomocí klíčového slova Partial, a to právě z důvodu, aby šlo lehce oddělit kód designéru a vlastní kód. Bohužel zde bude nutné odstranit řádek Inherits System.Windows.Forms.Form z kódu designéru, tomu se v tomto případě nevyhnete, protože jinak by bylo v konfliktu Inherits frmVzor vs. Inherits System.Windows.Forms.Form.

'Form1.Designer.vb
Public Partial Class Form1
  'Odstranit Inherits System.Windows.Forms.Form
End Class


'Form1.vb
Public Partial Class Form1
  Inherits frmVzor
  '...
End Class

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

Díky. Princip rozdělené třídy jsem chápal, nedošlo mi, že je možno dělit opakovaně. Nicméně popsaná konstrukce nepomůže odstranit tu popsanou záhadu se "samočinným" generováním těch sloupců mřížek do kódu designeru dle skutečných dat po spuštění formuláře, resp. po první změně formuláře v návrhovém zobrazení. Dokud v návrhovém zobrazení s ničím nehnu, tak je kód designeru nedotčen, ale stačí přidat jednu další komponentu a VB aktualizuje kód designeru nejen o ni, ale i o tu hromadu sloupců.

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

Pravděpodobně jste datové ovládací prvky navrhoval vizuálně v designéru a ty se vám tedy automaticky napojily na živou databázi, což by v kombinaci s AutoGenerateColumns = True mohlo způsobovat uvedené problémy. Vypnul bych AutoGenerateColumns a použil ruční binding dat. Rovněž se mi nezdá použití pěti DataGridViewů na jednom formuláři, k čemu takový nesmysl? Z uživatelského hlediska to musí být naprosto nepřehledné a neovladatelné.

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

Máte pravdu, že jsem datové ovládací prvky navrhoval vizuálně v designeru, ale použil jsem úplně stejný postup, jako při dědění jiného formuláře, který obsahuje jedno DataGridView, také jsem jej navrhoval v designeru, také se s ním napojuji na databázi a ten mi žádné automatické generování kódu do souboru pro designer neprovádí. Tento formulář, který funguje OK používám pro editaci jednoduchých databázových tabulek, tudíž ruční binding nepřichází do úvahy, protože sloupce jsou pokaždé jiné.

Teď jsem zkoušel nastavit u toho "zlobivého" formuláře AutoGenerateColumn=False a chová se to pořád stejně divně.

Chápu, že se Vám zdá pět mřížek na jednom formuláři dost, ale věřte, že to má své opodstatnění.

Naproti tomu nechápu, jak se může datový prvek automaticky napojit na živou databázi, když veškerý databinding dělám v kódu za běhu programu a návrhové zobrazení používám pouze ke vkládání a rozmístění komponent na formulář.

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

Jestliže návrh provádíte vizuálně pomocí Drag-and-Drop ze Server Exploreru, v jednom kroku se to dokonce ptá, zda-li chcete uložit nezabezpečené heslo Connection Stringu do konfiguračního souboru. Pokud zvolíte ano, potom máte k dispozici živá data dokonce i v návrhovém režimu. Vytvářet datové ovládací prvky tímto způsobem je vůbec ten nejhorší způsob jak dělat uživatelské rozhraní pro databázovou aplikaci, protože si to dělá co chce a lze to jen málo ovlivnit...

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

Sice mám zvláštní talent volit častěji než by mi bylo milé ty nejhorší způsoby návrhu, ale Server Explorer vůbec nepoužívám.

Používám návrhové zobrazení formuláře POUZE pro vložení a rozmístění ovládacích prvků a nastavení těch základních designových vlastností (Anchor, Dock, Font, BackColor...).

Veškerý kód týkající se databáze potažmo DataSetu a dalších komponent (zejména BindingSource, ten se mi moc líbí...) a napojení na komponenty formuláře píšu sám ručně.

Přiznám se bez mučení, že ConnectionString mám v app.config a Váš předchozí příspěvek mě navedl na další experimenty. Zjistil jsem, že pokud zobrazím formulář v návrhovém zobrazení, data v mřížkách pocházejí z aktuálních hodnot skutečné podkladové databáze a to i tehdy, když změním v app.config ConnectionString na nesmyslnou hodnotu. Nechápu. Ale mohlo by to vysvětlovat skutečnost, že druhý formulář s jedním datagridview funguje OK, protože v něm v ručně psaném kódu (odkud nepochybně návrhové zobrazení aniž ho o to prosím vyčmuchá na co je vlastně daná komponenta navázána) nemám název tabulky, ale posílám ho tam variabilně pomocí parametru.

Jinak budu velice rád když mi poradíte (nebo odkážete na nějaký informační zdroj) JAKÝ je nejlepší způsob vytváření uživatelského rozhraní pro db aplikaci. Učím se to pár měsíců metodou pokus omyl...

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

Způsob pro vytváření GUI pro DB aplikaci se mi osvědčil tento:

1) Bindingsource vždy a všude.

2) "Klikátka" jsou typicky k ničemu.

3) Dobře si pohlídat, kdy se co natahuje.

4) Zbytek nechávám na PropertyBindingu

5) Snažím se používat LINQ to SQL

Třeba Vám něco z toho přijde k dobru...

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

Díky.

Bod 1 se mi taky osvědčil a používám jej všude.

"Klikátko" používám k vizuálnímu rozmístění komponent. Vytvářet všechny uživatelské prvky na formuláři v kódu mi přišlo zbytečně pracné a zdlouhavé.

Kdy se co natahuje se snažím mít pod kontrolou, ale že si ten zatracený designer sám natáhne tabulku z DB pro návrhové zobrazení to mi nejde do hlavy.

Dělám ve VB 2005 a tam ještě LINQ to SQL není.

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

Souhlasím s tím co napsal P. Zajíc až na LINQ to SQL, se kterým se sice jednoduše pracuje, ale za cenu snížení výkonu...

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

Na jednoducjé SQL dotazy není výkonnostní rozdíl moc velký a jakýkoliv složitější dotaz, který joinuje dvě nebo více tabulek, se už vyplatí dělat přes uložené procedury. Takže když se LINQ používá rozumně, zpomalení je minimální a přinese to ulehčení práce, protože si nemusíte pamatovat názvy sloupců a máte IntelliSense. Jinak samozřejmě musí to zákonitě být o něco pomalejší, když dotaz napíšete špatně, tak se to může zpomalit opravdu znatelně. Viděl jsem jeden dotaz (a nebyl ani moc složitý, ale končilo to něco jako select i.Clanek.Autor.Jmeno a ještě něco kolem, přesně si to nepqamatuji). SQL, které LINQ To SQL vygeneroval, bylo po vytištění asi na 2 stránky A4.

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