Xabatcha blog - SCSF: MDI zarovnání child objektů
Vcelku jednoduchá zaležitost, ale hotové řešení pro někoho jiného se vždycky hodí. :-)Prvně, nastavení umístění child objektů pro MDI parent form se mění pomocí metody LayoutMdi an objektu Form. Např.CODELayoutMdi(MdiLayout.TileHorizontal);
Vcelku jednoduchá zaležitost, ale hotové řešení pro někoho jiného se vždycky hodí. :-)Prvně, nastavení umístění child objektů pro MDI parent form se mění pomocí metody LayoutMdi an objektu Form. Např.CODELayoutMdi(MdiLayout.TileHorizontal);
Související články
Tak se postupně snažím pochopit smysl všech těch pro mě nových výrazů v programování, např. MVP, MVC, Dependency injection, Smart parts a mnoho dalších. Musím říci, že to není vůbec jednoduché a pokud to člověk nepotřebuje během své normální pracovní doby, tak se do toho člověk dostává dost těžko, alespoň takhle po večerech.Tento příspěvek píší ze záměrem pomocí případným zájemcům o SCSF implementaci usnadnit pátrání po případné dokumentaci, příkladům či průvodcům.Ačkoli by člověk předpokládal, že největším informačním zdrojem budou stránky SCSF, tak podle mě nejvíce začátečníkovi pomůže seriál jež na svém blogu zveřejňuje Rich Newman. Pokud se rozhodnete použít SCSF pro svůj budoucí projekt, určitě se budete muset seznámit s Composite Application Block, což je vlastně podstata věci.Dle svých zkušeností bych doporučil tyto dostupné zdroje: (Seznam seřazen dle priorit)1 . seriál od Riche Newmana2. Cabpedia - wiki dokumentace shrnující dostupné informace k SCSF, plus pár tipů k vývoji3. SCSF - officiální stránky Smart klienta (za pozornost určitě stojí nově otevřená znalostní databáze)Za zmínku stojí určitě i pár blogů, například #2782, David Hayden, Tom Hollander a již zmiňovaný Rich NewmanCo se týče příkladů s použitím SCSF, tak bych doporučil mimo příkladů dostupných přímo od SCSF týmu těchto pár implementací:1. kombinace CSLA a SCSF - použití SCSF u příkladu distribuovaného s CSLA2. Example ke knize o SCSF od Davida Platta3. třetím implementací je Petshop od Szymona KobalczykaOsobně shledávám problém v pochopení, a to hlavně v roztřístřeností možných řešení implementace. Zatím pro mne není zřejmé, kdy a kde co použít pro docílení nejoptimálnějšího řešení. Když na to musí člověk přicházet sám, tak to vždy trvá, zase na druhou stranu tomu bude plně rozumět. Hlavně vytrvat...P.S. pokud budete mít nějaké další tipy, nerozpakujte se a přidejte je do diskuze.
Pro ty kdo ještě neví co je to SCSF alias Smart Client Software Factory nechť následují bílého králíka.Začal jsem se seznamovat s tímto programovacím modelem a narazil jsem na pár záludných chyb.První byl problém po instalaci při vytváření nového SCSF projektu ve VS2005, kdy celý proces spadl a zahlásil chybu, že nemůže vytvořit nové solution a v error message byl odkaz na nějaké chybějící VB soubory. Dle informaci na stránkách projektu jde o dnes již vyřešený bug a to buď nutnou doinstalací Visual Basicu nebo s modifikací instalačního balíčku případně nainstalované verze.Druhý bug je docela legrační, protože si myslím, že mohl dost lidem přivodit pár neradostných okamžiků. Při použití recipe Add Event Publication nad View docházelo k padání generování kódu s nějakou nesmyslnou chybou. Ale co mě fakt dostalo je řešení. Stačí zapnout odřádkování složených závorek na nový řádek pro formátování metod. Tedy něco jako toto:public void CloseView(....){}Fakt jsem obdivoval toho borce co na to přišel.]
Při použití toolbaru v MDI aplikaci je častým cílem, v tomto případě i mým, měnit sestavu jednotlivých položek toolbaru dle zobrazeného (aktivního) okna. Klasická konstrukce použitá v SCSF předpokládá využití v podstatě statického toolbaru, který je nahrán při načtení business modulu. Tj. v třídě ModuleController v metodě. Tento přístup nelze tedy použít v případě MDI. Jak tedy na to?
Přiložené soubory
Při použití MDI workspace v SCSF narazíte na pár problémů, které vám udělají pár vrásek na čele. Prvním z nich je, jak správně reagovat na zavření formuláře alias MDI okna pomocí klasického křížku.Pokud se uzavírá View programově, tak se volá metoda OnCloseView definovaná v Presentru, která zavře View a případně ho i odstraní z WorkItem kolekce. Viz příklad:
Pokud se někdo snažil použít řešení z předchozího příspěvku, tak jistě zjistil, že dané řešení není zdaleka ideální.Po nějaké době jsem se vrátil k tomuto řešení a trochu na tom zapracovat.První důležitou věcí je, že jsem změnil způsob jakým se získává odkaz na RootWorkItem. Z service IToolbarProviderService jsem odstranil metodu SetWorkItem a použil jsem klasického DI způsobu jak vložit objekt:CODE[InjectionConstructor]
Tak se tak prokousávám tím chytrákem SmartClientem a dneska se mi podařilo vyřešit jedna z mnoha věcí a to přidání submenu při načítání modulu.Problém spočíval v tom, ža objekt UIExtensionSites nepodporuje Get metodu, takže se nemůžete dostat k již existující položce kolekce. Podporované metody jsou jen Add a Remove. V případě menu pak nelze přidat dynamicky menu dle potřeb na příslušné místo.Jedno řešení je použít další třídu, která pomocí svých public metod bude vracet případné existující objekty. Pomoc jsem našel na SCSF fóru v tomto komentáři. Komentář obsahuje kompletní zdroják takovéto třídy, kterým jsem vložil do nového projektu, zkompiloval a vložil do referencí jako nový projekt. Záměrně jsem tuto třídu nedával nikam do složky Infrastructure, kde sou rootové projekty, které se automaticky linkují do modulů. Nebyl jsem si jist kam bych mohl tuto třídu dát, jako jediná možná volba by mohl být projekt Infrastructure.Interface, ale ten obsahuje záměrně jen Interface objekty, čímž bych zjevně porušil pravidla nezávislosti.Při vytváření submenu v modulu pak jen již vytvořím tuto třídu, podhodím ji rootový WorkItem a název hledaného menu a v případě, kdy není menu není vytvořeno, tak ho vytvořím. A pak již přidám jen lokální submenu dle potřeb jednotlivých modulů. Vypadá to asi takto.Příklad metody z třídy ModuleControllerCODE private void ExtendMenu() { //check if root menu exist, if not then create new ExtensionSiteUtility<ToolStripMenuItem> mainMenu = new ExtensionSiteUtility<ToolStripMenuItem>( WorkItem.RootWorkItem, UIExtensionSiteNames.MainMenu); ToolStripMenuItem diary = mainMenu.GetSite(HelloWord.Infrastructure.Interface.Constants.MenuItemNames.Diary); if (diary == null) { //adding menuitem to RootWorkItem to UIExtensionSites collection diary = new ToolStripMenuItem(); diary.Text = HelloWord.Infrastructure.Interface.Constants.MenuItemNames.Diary; WorkItem.RootWorkItem.UIExtensionSites[UIExtensionSiteNames.MainMenu].Add<ToolStripMenuItem>(diary); } //add module menu to module WorkItem ToolStripMenuItem sport = AddMainMenuItem(null, "Sport"); ToolStripMenuItem info = AddMainMenuItem(CommandNames.ShowSportInfoList, "Sport InfoList"); ToolStripMenuItem detail = AddMainMenuItem(CommandNames.ShowSportDetail, "Sport Detail"); sport.DropDownItems.AddRange(new ToolStripMenuItem[] { info, detail }); diary.DropDownItems.AddRange(new ToolStripMenuItem[] { sport }); }Detail metody AddMainMenuItem pro jistotuCODE private ToolStripMenuItem AddMainMenuItem(string commandName, string text) { ToolStripMenuItem item = new ToolStripMenuItem(); item.Text = text; if (!String.IsNullOrEmpty(commandName)) { WorkItem.UIExtensionSites[UIExtensionSiteNames.MainMenu].Add<ToolStripMenuItem>(item); WorkItem.Commands[commandName].AddInvoker(item, "Click"); } return item; }
Tak jsem řešil, jak nastavit základní parametry MDI view, respektive vlastností, které jsou dostupné na objektu WindowSmartPartInfo. V mém případě jsem potřeboval nastavit atributy Icon, Title, Width, Height. Ideálním řešením je samozřejmě jen jedno místo, které by bylo dosažitelné v rámci modulu.Zkoušel jsem například toto:První ideou bylo získání objektu ISmartPartInfo dle ID z kolekce WorkItem.SmartParts, nastavit vybrané vlastnosti a tím by bylo vystaráno. Avšak tohle řešení nefungovalo ve všech případech. Zkoušel jsem dát metodu, která provede nastavení, jak do presenteru, metoda OnViewReady a i do View, metoda OnLoad, ale v obou případech při otevření nebyl nalezen ISmartPartInfo objekt, který se vázal k danému View. Zdrojáky vypadali asi takto:Kód z View:CODEprotected override void OnLoad(EventArgs e)

22. červenece 08, 12:07
megaBLOG.cz Seznam blogů
Podle zpravodajství BBC byla u jednoho z největších výrobců notebooků, taiwanské společnosti Quanta Computer, zahájena sériová výroba školního notebooku pro rozvojové země One Laptop per Child. Cena 176 USD je zatím hodně vzdálena původně plánované...

24. červenece 07, 12:07
Blog.lupa.cz
Agentura Reuters přinesla čtvrteční zprávu News Agency of Nigeria (NAN), podle které její reportér zjistil, že na počítačích One-Laptop-per-Child, dodaných v rámci pilotního projektu, školáci v Abuja volně prohlížejí pornografické stránky. Zástupce...

23. červenece 07, 06:07
Blog.lupa.cz
Firma jež zaměstnává guru of CSLA, Rockforda Lhotku, hledá nové zaměstnance. Hádám, že nic pro našince, jelikož všechny její pobočky jsou v USA, ale určitě je zajímavý jejich vstupní test, který je online dostupný na internetu. Kriterium pro možnost přijetí je dosažení 70 bodů ze 100. Obsahem testu jsou v podstatě elementární otázky týkajicí se Net frameworku. Nic o CSLA, jen základy. Teoreticky, ten kdo pilně studoval celý Henselmanuv seznam otázek by neměl mít větší problémy dosáhnout velmi vysokého hodnocení. Určitě je zajímavé zjistit, jak na tom jsme....osobně jsem dosáhl 50 bodů a test jsem vyplnil behěm 10 minut bez toho abych se vracel zpět. Tak co, jak dobří jste?]

28. listopadu 07, 03:11
megaBLOG.cz Seznam blogů
Některé věci jsou opravdu mimo mé chápání.Můj tchán je tak trochu samorost a beran a některé věci prostě řeší tak nějak po svém....ale co je moc to je moc....jeden příklad za všechny.V baráku máme v obývacím pokoji krb. Krb bohužel nemá záklopku a tak jsem ustí komína vrazil takovou ucpávku, kterou lze v případě potřeby šlo vyndat. Můj tchán je vášnivý pyromen a snílek, rád pálí ohníčky. A tak zatím co jsem uspával ratolesti, tak se jal pálit ohýnek. Když jsem se ho později zeptal, kam že to dal tu ucpávku, odpověděl mi z dětským výrazem ve tváři, že ji spálil. A tohle prostě nechápu. Ta vycpávka byla specificky vyrobena za účelem nahrazení záklopky. Primitivní, ale funkční. A on to spálí jako by se nechumelilo. Opravdu tohle přichází z věkem na každého? Budu taky takový?????]
Sasha Barber, jeden z mnoha MVP používá usměvnou poznámku pod čarou:Originál:Your best friend is you.I"m my best friend too. We share the same views, and hardly ever argueNeoriginální překlad:Ty jsi svůj nejlepší přítel.Já jsem můj nejlepší přátel také. Máme stejný názor na věc a nikdy se nepřeme.
Již nějakou dobu používám CSLA.Net pro business objekty. Za tu dobu jsem si vytvořil pár templates, které by se mohli případně hodit i někomu jinému. Originály jsou z šablon, které se dodávají volně s frameworkem. Templates kombinují CSLA objekty s Enterprise Library data block, Pro získání dat z database se volají stored procedure. Pro C# kód jsem dříve používal jen princip Copy, Past, Replace. Teď používám ReSharper, tak to jde jednodušeji přes templates, které tam jsou zabudované. Pro začátek začneme jedním z nejvíce používaných objektů a to je RootEditable object.
Přiložené soubory
Při použití vnitrofiremní knihovny pro logování v Net aplikacích jsem se dostal do problému, kdy se zpráva logovala do databáse. V tomto případě SQL Server 2000. Při hledání řešení jsem narazil na několik chyb. Zde musím říci, že je mimo mou moc něco změnit v této knihovně. Což mě nečiní moc šťastným, spíše naopak.Chybou bylo, že pokud byla nějaká vstupní hodnota rovna null, v mém případě StackTrace z Exception objektu, tak to padalo jemně na pusu. Důvodem je, že SQL Server neakceptuje null hodnotu tak jak ji interpretuje Dot.Net. Musí se provést test hodnoty na null hodnotu a pokud je object roven null, musí se přiřadit jiná null hodnota, které SQL Server rozumí. V tomto případě System.DBNull.Value.Tento problém se dal ještě řešit na úrovni SQL serveru a to přiřazením default NULL hodnoty pro vstupní parametr v insertovací stored proceduře. Pak to projde i bez změn v logovací knihovně. Tedy něco jakoCREATE PROCEDURE dbo.insert_errorlog @errormessage nvarchar(500) = NULL, @errorsource nvarchar(100) = NULL, @stacktrace nvarchar(300) = NULL, as ...Zajímavostí, které mě ale nejvíce zaujala jest zjištění, že na to aby se naplnil StackTrace v Exception musí být sama Exception vyhozena (vyhozena ... legrační, že). Tedy nestačí ji jen vytvořit pomocí new konstrukce ale musí se použít navíc i throw konstrukce. Viz příklad.CODEstatic void Main(string[] args){ UserFriendlyException exc = new UserFriendlyException("test"); Console.WriteLine("1. Exception created"); Console.WriteLine(string.Format("Reading Stacktrace: {0}",exc.StackTrace)); try { Console.WriteLine("2. Exception thrown"); throw exc; } catch (UserFriendlyException ex) { Console.WriteLine("3. Exception caught as UserFriendlyException"); Console.WriteLine(string.Format("Reading Stacktrace: {0}",ex.StackTrace)); } catch(Exception ex) { Console.WriteLine("4. Exception caught as Exception"); Console.WriteLine(string.Format("Reading Stacktrace: {0}",ex.StackTrace)); } Console.WriteLine("**************************"); Console.WriteLine("Press any key to close it."); Console.ReadLine();}Věc se má vlastně tak, že jsem se snažil přijít na to, jak bych mohl nastavit nějakou hodnotu do StackTrace vlastnosti. Bohužel StackTrace má pouze Getter a nelze ho vložit jako input parametr do konstruktoru, takže zde není šance jak ho nastavit z venku.Btw. podobná situace je s další Exception vlastností a to je Source, ale ten jde naštěstí nastavit, jelikož má i Setter.Source:
ExceptionTest.zip ( 17.07k )
Počet stažení: 0]
Na Codesqueeze jsem narazil na skvělý článek, akorát nevím jestli je k smíchu nebo pláči.Osobně jsem nemohl udržet smích v rozumných mezích. :-)]
Ten kdo má, měl možnost potýkat se s klonováním objektů v Net aplikacích jistě řešil jak správně a jak hluboko :-) se má klonovat. Mým problémem je, že chci do svých Base objektů implementovat metodu, která vrátí Deep copy objektu v nové instanci. Tedy, že v paměti vzniknou dva různé avšak identické objekty.Pod tlakem událostí jsem to řešil né příliš efektivní cestou o to tím, že jsem metodu implementoval až na úrovni zděděných objektů, přičemž jsem ovšem porušil pravidlo viditelnosti Base objektů a zpřístupnil jsem některé privátní proměnné jako protected tak aby šli nastavit. Spokojený s tím moc nejsem, takže se mi snad podaří prosadit změnu ve smyslu implementace na úrovni Base objektů a navrácení viditelnosti změněných vlastností.Na toto téma jsem trochu googloval a našel jsem velmi vydařený článek, který obsahuje i praktické příklady.]
Ten kdo má, měl možnost potýkat se s klonováním objektů v Net aplikacích jistě řešil jak správně a jak hluboko :-) se má klonovat. Mým problémem je, že chci do svých Base objektů implementovat metodu, která vrátí Deep copy objektu v nové instanci. Tedy, že v paměti vzniknou dva různé avšak identické objekty.Pod tlakem událostí jsem to řešil né příliš efektivní cestou o to tím, že jsem metodu implementoval až na úrovni zděděných objektů, přičemž jsem ovšem porušil pravidlo viditelnosti Base objektů a zpřístupnil jsem některé privátní proměnné jako protected tak aby šli nastavit. Spokojený s tím moc nejsem, takže se mi snad podaří prosadit změnu ve smyslu implementace na úrovni Base objektů a navrácení viditelnosti změněných vlastností.Na toto téma jsem trochu googloval a našel jsem velmi vydařený článek, který obsahuje i praktické příklady.[Update]Tak jsem si vyzkoušel jak to funguje a nakonec jsem použil verzi s metodou MemberwiseClone(). Tady se můžete podívat na zdrojáky:
CLone.zip ( 76.29k )
Počet stažení: 12
Velmi rád čtu blog Johna Vanhara. Jméno zní dost agnlicky, ale jde o našince, který žije dlouhodobě v US. Pan Vanhara zde píše o svých zkušenostech s podnikáním v US a jde o velmi poutavé a inspirující čtení. Velmi mě zaujal jeden z jeho posledních článků. Řeč je o placení daní.Nejvíce mě zaujal tento odstavec, dovolím si citovat: "Kdyby každý vložil stejné usilí do rozvoje svých podnikání, tak garantuji, že vydělá více než přemýšlením jak ušetřit na daních.". Parafrází je další vyřčená myšlenka z blogu Miroslava Macka, bohužel jsem nenašel originální text, ale dovolím si vyjádřit podstatu myšlenky: "Je lepší přemýšlet nad tím jak vydělat než kde ušetrit."
Na světě jsou lidi, kteří mají dar. Rudolf Havlík je jedním z nich. Každý nový článek na jeho blogu je jak záblesk z čistého nebe. Prostě Vás dostane. Mě alespoň jo.