\


 Wednesday, 19 December 2007
Vánoční dárek - nový software - WiFi profily pro Windows Mobile

Stáhnout cab:

Diskuze k programu:

Vytvořil jsem aplikaci pro přepínání WiFi profilů - jedná se o první build (alfa verze). Alfa je varováním, že v aplikaci je určitě mnoho chyb, které, dá-li Bůh,  postupně odstraním. ;-)

K čemu aplikaci potřebujete? Přecházíte mezi více Wifi sítěmi a některé vyžadují zadání IP adresy, masky podsítě, DNS a u jiných stačí povolit DHCP? Nebaví vás neustálé ruční nastavování hodnot na síťové kartě a poté otravný povinný soft reset zařízení, aby se zadané údaje použily? Pak je tento SW přímo pro vás.

Aplikace je otestována na Windows Mobile 5 a 6. Testováno na HTC Wizard (MDA Vario) a HTC Kaiser {MDA Vario III).

Verze 0.0.5.

Diskuze k programu:

Stáhnout cab:

1) Záloha všech profilů do souboru

2) Obnovení zálohy všech profilů - i na jiném zařízení včetně možnosti změny názvu net adaptéru při obnově profilů.

3) Přímo z menu lze vytvořit zástupce na profil.

4) Odstraněny nalezené bugy.

Tip: Pokud máte zařízení od HTC  (např. HTC wizard - MDA Vario) a musíte nejprve spustit  wifi z Comm Manageru,protože není po startu zařízení ihned nahrán driver, zkuste do registru pridat HtcPreloadWifi s hodnotou 1.

HKLM\Comm\<nazev net adapteru - zobrazovan ve wifi profilech>\Parms\HTCPreloadWifi

 

Verze 0.0.4.

1) Sjednocení EN a CZ verze - podpora pro libovolné množství dalších jazyků.
Aplikace se spustí v angličtině, do češtiny se přepnete vybráním položky Language menu a zvolením CZ v dalším dialogu.

2) Možnost nastavení internetové http proxy. Podpora vrácení se k poslednímu stavu připojení před aplikací proxy.  [b]Abyste požívali proxy v Pocket IE a dalších programech, musíte nastavit u wifi sítě, že se připojuje k profilu work. [/b] Nové nastavení vás připojí přes proxy na internet   - nechci zabíhat do detailů, "global wide proxy" jsou poměrně komplikovaná záležitost a pro jejich programové nastavení neexistuje pořádná dokumentace. :(
Pokud bude zájem, mohu přidat socks proxy.

3) Možnost samostatně z menu nebo i u každého profilu nastavit, zda se má wifi odpojit při vypnutí zařízení. Upozorňuji, že u některých zařízení musíte pro uplatnění hodnot (podobně jako je tomu při zapínání wifi) sami zapnout wifi po soft resetu z manažera připojení před nastavením způsobu odpojování wifi.

4) Možnost spustit po aplikaci profilu (resp. po připojení k wifi síti - platné SSID) libovolný program. Jestliže není wifi síť připojena, nebo nelze detekovat připojení k wifi síti, je program spuštěn po uplynuti 20 s.

Pro program je možné zadat příkazový řádek. V příští verzi nebudete muset zadávat cestu k programu sami do textového pole, ale v dialogu si program sami vyberete.

7) Možnost vytvořit si zástupce přímo pro profil (např. v Total Commanderu CE) -  profil se dá vytvořením zástupce s příkazem v následujícím tvaru.
"<Cesta k exe>" <Nazev profilu>

Tedy např. tento zástupce aktivuje profil s názvem MujProfil.
"\Storage Card\Program Files\RStein\WifiProfiles\RStein.WifiProfiles3.exe"  MujProfil


6) Možnost nainstalovat aplikaci na SD kartu.

[B]Za nesprávné používání aplikace ani za možné vzniklé škody a následné hard resety nenesu žádnou odpovědnost! To pro jistotu připomínám . :) [/B]

Verze 0.0.3. - pouze anglická mutace

Verze 0.0.2. - pouze anglická mutace


Verze 0.0.1. - Hlavní rysy:
1) Vytváření nových síťových  profilů.
2) Aplikace profilu bez resetu zařízení.
3) Automatické nalezení WIFI adaptéru.
4) Položka v menu pro rychlé přepnutí do DHCP režimu.
5) Vytvoření nového profilu zkopírováním a úpravou stávajícího profilu.
6) Automatické vypnutí a zapnutí WIFI po aplikaci profilu.
Jestliže je v profilu DHCP nastaveno na hodnotu "ANO", všechny další volby jsou ignorovány.

Plánované funkce:
1) Podpora pro další jazyky - hlavně resource dll pro EN.
2) Plugin na Today obrazovku s rychlým výběrem  profilu.
3) Vylepšené UI pro zadávání IP  adresy, validace dat, informace o průběhu aplikace profilu.
4) Automatické vytvoření nové ad hoc wifi sítě z programu (např. pro sdílení GPRS/EDGE/UMTS připojení přes wifi do notebooku)


Instalace:
Stáhněte CAB, zkopírujte jej do zařízení a spusťte. V programech budete mít novou ikonu - WifiProfiles.

!!!Důležité: Není povoleno cab soubor dále redistribuovat nebo vystavovat na svých stránkách -program  musí být stažen z výše uvedeného odkazu !!!

Enjoy :)





Wednesday, 19 December 2007 22:25:30 (Central Europe Standard Time, UTC+01:00)       
Comments [3]  Mobilitky | Wifi Profiles Windows Mobile


 Monday, 16 July 2007
Net Monitor verze 0.5.0.0

Hlavní změny:

  1. Plugin lze ovládat bez stylusu (podpora Today Selection API).
  2. Odstraněno problikávání při překreslování obrazovky - double buffering.

Více informací o Net Monitoru.



Monday, 16 July 2007 20:30:30 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Mobilitky | Net Monitor


 Saturday, 07 July 2007
Net Monitor verze 0.4.0.0

Hlavní změny ve verzi 0.4.0.0
1) Reinicializace RILu po opakovaném spuštění logování.
2) Přidán dialog o aplikaci.
3) Při stahování databází  program využije buď stávající připojení k internetu, nebo při neexistenci připojení se pokusí PDA připojit (přes GPRS, CSD  - dle nakonfigurovaných připojení)
4) Kolem "akčních" ikon vykreslováno ohraničení.

Více informací o Net Monitoru.



Saturday, 07 July 2007 17:15:35 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Mobilitky | Net Monitor


Funkce "AutoConnect" mezi MDA (Pocket PC Phone Editon s MS BT stackem) a autorádiem Pioneer (DEH-P 55 BT) s bluetooth handsfree

Někdy na konci minulého roku jsem si koupil autorádio Pioneer DEH-P 55 BT a i když jsem byl velmi spokojen s kvalitou hovorů, nelíbilo se mi, že s MDA Variem nebo s HTC Artemis (obecně tedy s jakýmkoliv Pocket PC Phone Edition s BT stackem od Microsoftu) není funkční automatické připojení zařízení k rádiu. Jinými slovy - chtěl jsem přijít do auta, otočit klíčkem v zapalování a být si jistý, že všechny hovory budu přijímat přes autorádio. To ale nešlo - musel jsem vždy nastartovat a teprve poté na rádiu ručně zvolit "Connect". Docela opruz.  Naštěstí jsem ale čirou náhodou zjistil, že když v MDA po BT spárování zaškrtnete u autorádia volbu "Set As Handsfree", tak MDA , když je v dosahu rádia a přijmete hovor nebo někomu zavoláte sami, se k rádiu připojí a všechny zvukové vstupy a výstupy telefonní části na něj přesměruje. "Čiré náhodě" dá člověk šanci tak, že když ho přestane bavit otravné hledání položky Connect v menu po každé zastávce v autě a často na tento svého druhu pozoruhodný opičí úkon pozapomene, tak při příchozím hovoru najednou s údivem zjistí, že i bez jeho asistence BT HF stejně funguje. Takže nakonec spokojenost, sice z nečekané strany, ale přesto spokojenost se spoluprací rádia a MDA.

Vrtala mi ale hlavou i další nepříjemnost - rádio MDA při párování nikdy nenašlo. Obezlička (česky Workaround ;-) ): Otevřete BT připojení z rádia (Connect Open - modrá dioda na rádiu začne blikat) a z MDA iniciujete párování.

Přesto mně nedalo spát, proč nelze párovat Vario/Artemis s rádiem stejně jako další telefony a z jakého - čertovským marketingem říznutého - důvodu má rádio nepoužitelnou funkci AutoConnect, který je přitom barvitě a neodolatelně popsána v manuálu - a zde je řešení celé záhady.

MDA se identifikují při BT připojení jako zařízení třídy PDA. Při připojení MDA přes BT k počítači si můžete všimnout přiřazené ikony se symbolem PDA. Rádio ale spolupracuje jen zařízeními třídy 'Phone' nebo 'Smartphone'.

V registrech, v klíči HKLM\SOFTWARE\Microsoft\Bluetooth\sys\COD,  změňte stávající hodnotu na hodnotu 5374476 (decimálně). Tím docílíte toho, že MDA skryje svou pravou identitu a nabídne janusovskou tvář  - místo plnokrevného PDA charakteru poskytne BT rádiem vstřícně očekávané a jemu milé mimikry zdegenerovaných a zkriplovaných SmartPhonů. ;)

Restartujte zařízení a nyní můžete MDA spárovat s rádiem, využít funkce AutoConnect apod.



Saturday, 07 July 2007 14:52:56 (Central Europe Standard Time, UTC+01:00)       
Comments [1]  Mobilitky


 Monday, 02 July 2007
Alfa verze Net monitoru pro Pocket PC ke stažení

Download: http://blog.renestein.net/__DOWNLOAD/NetMonitorTodayInstall.CAB

Sice mám teď nařízen nucený odpočinek, ale ještě předtím se mi podařilo vytvořit Net Monitor pro Pocket PC Phone Edition. Pokud jste nikdy nelovili BTS, ani si nedovedete představit, o jakou zábavu jste přišli. Na starších Nokiích nebo Siemensu S55 bylo jednoduché aktivovat tzv. Net Monitor - režim, ve kterém jsou zobrazovány základní parametry GSM připojení (Cell Id, LAC, Network ID). Net Monitor jsem vytvořil i pro Pocket PC a navic je nyní integrován se skvělými databázemi BTS na GSM webu:

Charakteristika aplikace:

1) Jedna se o Today plugin (udaje se zobrazuji na obrazovce dnes).
2) Aplikace se prozatim snazi zjistit udaje Cell Id, LAC, Network Id  a BCCH. Na HTC Artemis a MDA Variu mam overeno, ze se zobrazi spravne udaje Cell Id a LAC, BCCH se pokusim zjistit jeste jinak. Overeno, ze udaje Cell Id a LAC se zobrazi i na Ipaqu 6340 s WM 2003, HTC TYTN, HTC Trinity, MIU A701 ...

3) Udaje o GSM siti jsou po zapnuti zjistovany dle hodnoty zadane v konfiguracnim dialogu.

3) Aplikace volitelne loguje zjistene udaje do zadaneho souboru) - soubor ma format (Datum); (cas);(LAC);(Cell Id);(BCCH); .
Instalace:
Protoze se jedna o AlFA preview, doporucuji pred instalaci Net Monitoru mit v zarizeni napr. SPB Pocket Plus a v nem aktivovany safe boot - jestlize by vam vytuhlo zarizeni, nebudete nucet delat HR (Hard reset), protoze muzete pri startu zarizeni docasne deaktivovat Today pluginy.

1) Z adresy http://blog.renestein.net/__DOWNLOAD/NetMonitorTodayInstall.CAB si stahnete instalacni CAB.
2) CAB zkopirujte do PDA, spustte jej  a potvrdte pripadne hlasky zabezpeceni.
3) Resetujte (Soft reset) zarizeni - na Today obrazovce se Vam zobrazi novy plugin s hlasenim "Prozatim nebyly zadany zadne udaje". Plugin obsahuje kontextove menu - v nem zvolte polozku Sledovat informace o GSm siti (nebo kliknete na ikonu po leve strane panelu).
Chcete-li udaje logovat, takze zvolte po opakovanem otevreni menu polozku Zapisovat informace do souboru.

V planu je krome veci zminenych vyse:
1) Zapis GPS souradnic ke kazdemu zaznamu v logovacim souboru.
2) Integrace s databazi BTS na GSMWEB.cz.  Online integrace s databázemi BTS na GSMWebu.
3) Graficka indikace primo v pluginu, zda je zapnuto sledovani udaju, zda dochazi k logovani do souboru atd.


Hlavni zmeny ve verzi 0.3.0.0: (Verze 0.2.0.0. nebyla veřejná).

1) Uzivatelske rozhrani Net pluginu zobrazuje udaje v zalozkach.
2) "Offline integrace s databazi GSMWEBU - program dokaze stahnout csv soubory z GSMWebu a na zalozce Podrobnosti zobrazuje podrobne informace o prave nalezene bunce. Konfiguraci csv databazi naleznete v nastaveni (kontextove menu -> nastaveni) - prednastaveny jsou url pro GSM sit TMO, Vodafone a O2. Zmente adresar, do ktereho budou csv soubory ulozeny, pripojte se k internetu (v PRISTI verzi vas program pripoji sam) a kliknete na tlacitko Stahnout vse. Na zalozce podrobnosti se obcas muzete setkat s tim, ze pod udajem LAT se objevi jmeno cloveka, ktery BTS zaevidoval - jde o chybu/nedokonalost stavajicich souboru a ve spolupraci s autory GSM webu se ji pokusim vyresit.
3) Zobrazovani petimistneho Network Id.
4) Zobrazovani sily signalu.
5) Po leve strane je "toolbar" s ikonami pro nejcastejsi akce. Dole je stavovy pruh s ikonami - v soucasne dobe je indikovano zapnuti/vypnuti radiove casti. Zatim se moc nedivejte na ikonky, ty jsou priserne.
6) Opravy chyb a mnoho drobnych vylepseni.

Hlavni zmeny ve verzi 0.1.0.0:

1) Udaje jsou na Today obrazovce zobrazeny v decimalnim formatu (predtim byly v hexa formatu).
2) V logovacim souboru je na kazdem radku i datum.
3) Pokud se misto platneho udaje na today obraozvce zobrazi -1, znamena to, ze pro tento udaj jsem nedostal validni odpoved.
4) Pridan konfiguracni dialog - dostupny z kontextoveho menu pluginu pres polozku Nastaveni nebo primo v nastaveni Today pluginu pres standardni volbu Options.

 

Monday, 02 July 2007 20:07:26 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Mobilitky | Net Monitor


 Wednesday, 27 June 2007
Pozvánka na podzimní běh kurzu Objektovými principy a návrhovými vzory řízený design a vývoj kvalitních aplikací

Chci vás pozvat na podzimní termíny kurzu Objektovými principy a návrhovými vzory řízený design a vývoj kvalitních aplikací.

Termíny:

24. - 26. 9. 2007
5. - 7. 11. 2007

Organizační informace ke kurzu

Program kurzu

Zaregistrované ohlasy na školení :

http://blog.renestein.net/ct.ashx?id=10d7acf8-1026-43fe-b1f1-54fccb69105b&url=http%3a%2f%2fwww.jirifabian.net%2fwordpress%2f%3fp%3d157

http://blog.renestein.net/ct.ashx?id=10d7acf8-1026-43fe-b1f1-54fccb69105b&url=http%3a%2f%2fwww.rarous.net%2fclanek%2f143-skoleni-oop-uml-a-navrhovych-vzoru.aspx

 

Omlouvám se za tento přízračně mrtvolný klid na blogu, ale kvůli neočekávaným osobním problémům nemám na blog vůbec čas. Do konce září (alespoň doufám) ale konečně změním kompletně blogovací systém a nasadím slibované wiki + fórum o  OOP a návrhových vzorech.



Wednesday, 27 June 2007 09:38:11 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Kurzy UML a OOP | Návrhové vzory | UML


 Monday, 12 February 2007
Pozvánka na další běh kurzu "Objektovými principy a návrhovými vzory řízený design a vývoj kvalitních aplikací" a pár informací navíc

Chci vás pozvat na další termíny kurzu Objektovými principy a návrhovými vzory řízený design a vývoj kvalitních aplikací.

Termíny:

18.04. - 20.04. 2007
02.05. - 04.05. 2007

Organizační informace ke kurzu

Program kurzu

Zaregistrované ohlasy na školení :

http://www.jirifabian.net/wordpress/?p=157

http://www.rarous.net/clanek/143-skoleni-oop-uml-a-navrhovych-vzoru.aspx

 

A malá poznámka pro ty, co si mysleli, že tento blog je již trpí zhoubným zombie syndromem viru dgx  (metlou lidstva dnešních dnů je pro mě nesvatá trojice TBC, HIV, DGX s faktorem RH v komentářích) :-) a čeká se jen na poslední R.I.P. spot  - blog mrtvý není a nebude, jen poslední 3 měsíce na žádné "hobby" libůstky jako je blog nebyl a není stále čas (většinou tato věta představuje trapně křiklavé mimikry lenosti autora blogu, ale u mě jde nyní o empirický a subjektivně drasticky verifikovaný fakt) :-), takže toto období považujte za zimní spánek. V březnu opět začnu publikovat, blog přejde na můj redakční systém (konec DasBlogu a konec jeho rozmarům) a také se objeví slibované fórum od OOP, UML, DSL a návrhových vzorech. Současně s fórem bude spuštěna WIKI na stejná témata - ta již obsahuje několik desítek textů, které jsem stihl napsat ještě minulý rok na podzim.



Monday, 12 February 2007 18:50:49 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Kurzy UML a OOP | Ostatní


 Sunday, 29 October 2006
Analytická hádanka - žhnoucí vztahy mezi třídami
Hádanka

Slovo "žhnoucí" v nadpisu spotu není zavedením dlouho očekávané extenze do UML pro označení libidinózního vztahu mezi třídami :-D, ale jen a pouze hodnotí vztahy, které jsou kvalitními kandidáty na epicentra pořádného požáru, v němž veškeré výhody OOP návrhu jsou devótně obětovány božstvu "najděte v aplikaci podstatná jména, nasekejte z nich třídy a pak si dejte panáka na další úspěch". ;-)

Diagram je záměrně neúplný, takže bych chtěl slyšet, jak by se dal upravit/rozvinout a jaké předpoklady jsou v něm obsaženy.

 

diagram tříd - hádanka na vztahy

 

 

zatím jde jen o triviální problém, ale na subtilnější kličky narazíme brzy v dalších hádankách :)

 



Sunday, 29 October 2006 22:41:37 (Central Europe Standard Time, UTC+01:00)       
Comments [23]  


Kontrola duplicitního spuštění aplikace v Compact .Net Frameworku - Windows CE

I když samotný Compact .Net Framework v souladu s doporučeními Microsoftu pro vývoj Windows Mobile aplikací zajišťuje, že je vždy spuštěna nanejvýš jedna instance aplikace, v Compact .Net Frameworku spuštěném na "čistých" Windows CE již zmíněné pravidlo neplatí a kontrolu na opakované spuštění aplikace musíme doplnit sami.

Tento kód funguje pro Compact .Net Framework od verze 1.x a byl otestován na Windows CE 4.2 a vyšších.

private const int ERROR_ALREADY_EXISTS = 183;

[DllImport("CoreDll.dll")]
private static extern int GetLastError(); 

[DllImport("CoreDll.dll", EntryPoint="CreateMutexW")]

private static extern int CreateMutex( IntPtr
lpMutexAttributes, bool InitialOwner, string MutexName );

public static bool AppAlreadyStarted() 
{ 
string myID =
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

if( CreateMutex(IntPtr.Zero, true, myID) != 0 )
{
    return (GetLastError() == ERROR_ALREADY_EXISTS);
} 

return false; 
}

Můžeme také najít formulář již spuštěné aplikace podle titulku, přenést jej do popředí a duplicitní instanci aplikace ukončit.

namespace DeviceApplication1
{
static class Program
{
[DllImport("coredll", EntryPoint="FindWindow")] 
private static extern IntPtr FindWindow( 
string lpClassName, 
string lpWindowName); 


[DllImport("coredll", EntryPoint="SetForegroundWindow")] 
private static extern bool SetForegroundWindow(IntPtr hWnd); 

[MTAThread]
static void Main()
{


IntPtr mainWindowHwnd = FindWindow(null, "DeviceMain");


if (mainWindowHwnd.Equals(IntPtr.Zero)) 
{ 
   Application.Run(new Form1()); 
} 
else 
{
   SetForegroundWindow(mainWindowHwnd); 
   Application.Exit(); 
} 

}

}


Sunday, 29 October 2006 20:52:11 (Central Europe Standard Time, UTC+01:00)       
Comments [0]  Compact .Net Framework


 Monday, 09 October 2006
ASP.NET - jednoduchý přístup z kódu na webovém formuláři k prvkům deklarovaným v šabloně
.Net Framework V ASP.NET 1.x jsme při přístupu k prvkům v šabloně (šablonou rozumíme vlastnost serverového ovládacího prvku typu ITemplate) museli zavolat metodu FindControl a předat ji Id hledaného prvku. A protože návratovou hodnotou metody FindControl je pouze rozhraní třídy Control, byli jsme nuceni přetypovávat na odvozený ovládací prvek.
  Label lblMess = LoginControl1.FindControl("lblMessage") as Label;

U prvků DataList, Repeater a dalších, kteří používají šablony pro opakování stejného obsahu pro každý řádek v datovém zdroji (ItemTemplate, AlternateItemTemplate) je použití metody FindControl odůvodněné. Ovládací prvky v šabloně jsou vytvořeny opakovaně pro všechny řádky v datovém zdroji a rodičovský prvek šablony implementací rozhraní INamingContainer zajišťuje, že každá instance šablony je v html formuláři složena z html elementů s unikátními hierarchickými názvy. Metoda FindControl na řádku  Datalistu, Repeateru si můžeme zjednodušeně představit jako "překladač" dlouhého, hierarchického a automaticky generovaného Id na jednoduché Id zadané v šabloně. Vidíme-li na stránce Id LoginControl1_ctl00_lblMessage, můžeme se k prvku s Id 'lblMessage' dostat tak, jak jsme si ukázali v kódu výše.

Proč si ale komplikovat život, když máme na stránce vždy maximálně jednu instanci šablony? Šablona prvku WizardStep bude na stránce právě jednou, protože šablonu jednoho kroku v průvodci (asp:wizard) nepoužíváme pro opakovanou instanciaci stejného obsahu, ale jen pro vytvoření vlastního vzhledu jednoho kroku průvodce. Šablonu nám prvek wizard nabízí jen proto, abychom si mohli vytvořit pěkné vlastní uživatelské rozhraní a nebyli sešněrováni ve svém tvůrčím rozletu představami ASP.NET týmu. Pak ale není žádný důvod, abychom k prvkům šablony přistupovali přes metodu FindControl. Prvky jsou na stránce pouze jednou a je bezpečné na ně odkazovat přímo na úrovni stránky jako na každý jiný ovládací prvek v ASP.NET formuláři, protože nehrozí kolize jejich Id.

ASP.NET 2.0 dovoluje u každé vlastnosti typu ITemplate určit, jestli bude šablona instanciována na jedné stránce opakovaně, anebo zda se na šablona stránce vyskytne nanejvýš jednou. Informaci o tom, jak budete šablonu používat, nese nový atribut TemplateInstance, kterým dekorujete vlastnost ITemplate.

 [TemplateInstance(TemplateInstance.Single)]

Hodnotu Single z enumerace TemplateInstance ASP.NET interpretuje jako příkaz k vygenerování typových proměnných na úrovni stránky pro všechny ovládací prvky v šabloně.

Když atribut TemplateInstance nepoužijeme nebo zvolíme režim TemplateInstance.Multiple, k vygenerování proměnných nedojde a ASP.NET 2.0 se k prvkům k šabloně chová stejně jako ASP.NET 1.x.

Zde je jednoduchý serverový ovládací prvek LoginControl, který obsahuje dvě šablony - jednu pro anonymní uživatele a druhou, asi nepřekvapivě,  pro přihlášené uživatele. Obě šablony jsou dekorovány atributem TemplateInstance s hodnotou TemplateInstance.Single - jako autoři ovládacího prvku víme, že určitě nebudeme používat více instancí jedné šablony.

namespace RStein.Web.UI.WebControls
{
    /// <summary>
    /// Serverový ovládací prvek, který dovoluje definovat odlišné šablony pro anonymního a přihlášeného uživatele
    /// </summary>
    [DefaultProperty("AnonymousUserMessage")]
    [DefaultEvent("LoginRequest")]
    [ToolboxData("<{0}:LoginControl runat=server></{0}:LoginControl>")]
    public class LoginControl : CompositeControl
    {
        

        #region Delegates
        public delegate void LoginItemCommandEventHandler (object sender, CommandEventArgs e);
        #endregion Delegates
        #region Public Constants
        /// <summary>
        /// popisek na tlačítko pro událost <see cref="LoginRequest"/>
        /// </summary>
        public const string LOGIN_BUTTON_NAME = "Login";
        
        /// <summary>
        /// Konstanta reprezentuje popisek na tlačítko pro událost <see cref="LogoutRequest"/>
        /// </summary>
        public const string LOGOUT_BUTTON_NAME = "Logout";
        
        #endregion Public Constants

        #region Events Keys

        /// <summary>
        /// Klíč události <see cref="LoginRequest"/>
        /// </summary>
        public static readonly Object LoginRequestKey = new Object();
        
        /// <summary>
        /// Klíč události <see cref="LoginRequest"/>
        /// </summary>
        public static readonly Object LogoutRequestKey = new Object();
        
        /// <summary>
        /// Klíč události <see cref="ItemCommand"/>
        /// </summary>
        public static readonly Object ItemCommandKey = new Object();
        
        #endregion Events Keys
        

        #region Public Events
        /// <summary>
        /// Událost 'Přihlásit uživatele' je vyvolána po kliknutuí na tlačítko s popiskem <see cref="LoginButtonName"/>
        /// </summary>
        public event EventHandler LoginRequest
        {
            add
            {
                Events.AddHandler(LoginRequestKey, value);
            }
            
            remove
            {
                Events.RemoveHandler(LoginRequestKey, value);
            }
        }
        
        /// <summary>
        /// Událost 'Odhlásit  uživatele' je vyvolána po kliknutuí na tlačítko s popiskem <see cref="LogoutButtonName"/>
        /// </summary>
        public event EventHandler LogoutRequest
        {
            add
            {
                Events.AddHandler(LogoutRequestKey, value);
            }
            
            remove
            {
                Events.RemoveHandler(LogoutRequestKey, value);
            }
        }
        
        /// <summary>
        /// Událost zprostředkovává události vnořených ovládacích prvků
        /// </summary>
        public event LoginItemCommandEventHandler ItemCommand
        {
            add
            {
                Events.AddHandler(ItemCommandKey, value);
            }
            
            remove
            {
                Events.RemoveHandler(ItemCommandKey, value);
            }
        }
        
        #endregion Public Events
        
        
        #region Private variables
        private LoginControlContent m_content;
        private ITemplate m_anonymousTemplate;
        private ITemplate m_loggedInTemplate;
        #endregion Private variables
        
        #region Contructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        public LoginControl()
        {

        }
        #endregion Contructors
        
        
        #region Public properties
    
        /// <summary>
        /// Vlastnost dovoluje přistupovat k prvkům šablony přes FindControl
        /// </summary>
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public LoginControlContent Content
        {
            get
            {
                EnsureChildControls();
                return m_content;
            }
        }

        /// <summary>
        /// Šablona pro přihlášeného uživatele
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(LoginControlContent))]
        [TemplateInstance(TemplateInstance.Single)]
        public ITemplate LoggedInTemplate
        {
            get
            {
                return m_loggedInTemplate;
            }

            set
            {
                m_loggedInTemplate = value;
            }
        }

        /// <summary>
        /// Šablona pro nepřihlášeného uživatele
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(LoginControlContent))]
        [TemplateInstance(TemplateInstance.Single)]
        public ITemplate AnonymousTemplate
        {
            get
            {
                return m_anonymousTemplate;
            }

            set
            {
                m_anonymousTemplate = value;
            }
        }
        
        /// <summary>
        /// Informace zobrazená nepřihlášenému uživateli
        /// </summary>
        [Category("Behavior")]
        [Bindable(true)]
        [DefaultValue("")]
        [Description("Informace zobrazená nepřihlášenému uživateli")]
        public string AnonymousUserMessage
        {
            get
            {
                string message = (string) ViewState["AnonymousUserMessage"];
                return (message == null ? String.Empty : message);
            }
            
            set
            {
                ViewState["AnonymousUserMessage"] = value;
            }
        }

        /// <summary>
        /// Informace zobrazená přihlášenému uživateli
        /// </summary>
        [Category("Behavior")]
        [Bindable(true)]
        [DefaultValue("")]
        [Description("Informace zobrazená přihlášenému uživateli")]
        public string LoggedInMessage
        {
            get
            {
                string message = (string) ViewState["LoggedInMessage"];
                return (message == null ? String.Empty : message);
            }
            set
            {
                ViewState["LoggedInMessage"] = value;
            }
        }
        #endregion Public properties        
        
        #region Protected properties        
        
        /// <summary>
        /// Prvek bude uzavřen v HTML značce DIV
        /// </summary>
        protected override HtmlTextWriterTag TagKey
        {
            get
            {
                return HtmlTextWriterTag.Div;
            }
        }

        #endregion Protected properties        

        #region Protected methods
        
    
        /// <summary>
        /// Vytvoření vnořených ovládacích prvků
        /// </summary>
        protected override void CreateChildControls()
        {
            
            Controls.Clear();
            
            if (Page.User.Identity.IsAuthenticated)
            {
                m_content = new LoginControlContent(Page.User.Identity.Name, AnonymousUserMessage, LoggedInMessage);
                ITemplate template = null;

                if (m_loggedInTemplate != null)
                {
                    template = m_loggedInTemplate;
                }
                else
                {
                    template = new DefaultLoggedInTemplate();
                }
                
                template.InstantiateIn(m_content);
                
            }
            else
            {
                m_content = new LoginControlContent(String.Empty, AnonymousUserMessage, LoggedInMessage);
                
                ITemplate template = null;
                
                if (m_anonymousTemplate != null)
                {
                    template = m_anonymousTemplate;
                }
                else
                {
                    template = new DefaultAnonymousTemplate();
                }
                
                template.InstantiateIn(m_content);
                    
                
            }
            
            this.Controls.Add(m_content);
            
        }

        /// <summary>
        /// Přpsání metody, která zachycuje bublané události
        /// </summary>
        /// <param name="source">Zdroj bublané události</param>
        /// <param name="args">Argumenty bublané události</param>
        /// <returns><see cref="true"/> - Událost byla zpracována, <see cref="false"/> - Událost nebyla zpracována</returns>
        protected override bool OnBubbleEvent(object source, EventArgs e)
        {
            CommandEventArgs ex = e as CommandEventArgs;
            if (ex != null)
            {
                if (ex.CommandName.ToLower() == LOGIN_BUTTON_NAME.ToLower())
                {
                    OnLoginRequest(new EventArgs());
                }

                else if (ex.CommandName.ToLower() == LOGOUT_BUTTON_NAME.ToLower())
                {
                    OnLogoutRequest(new EventArgs());
                }

                else
                {
                    OnItemCommand(ex);
                }
                
                return true;
            }
            
            return false;
        }

        /// <summary>
        /// Metoda odpovědná za vyvolání události loginRequest
        /// </summary>
        /// <param name="e">Parametry události</param>
        protected virtual void OnLoginRequest(EventArgs e)
        {
            EventHandler eh = (EventHandler) Events[LoginRequestKey];
            if (eh != null)
            {
                eh(this, e);
            }
        }

        /// <summary>
        /// Metoda odpovědná za vyvolání události LogoutRequest
        /// </summary>
        /// <param name="e">Parametry události</param>
        protected virtual void OnLogoutRequest(EventArgs e)
        {
            EventHandler eh = (EventHandler) Events[LogoutRequestKey];

            if (eh != null)
            {
                eh(this, e);
            }
        }

        /// <summary>
        /// Metoda odpovědná za vyvolání události ItemCommand
        /// </summary>
        /// <param name="e">Parametry události</param>
        protected virtual void OnItemCommand(CommandEventArgs e)
        {
            LoginItemCommandEventHandler eh = (LoginItemCommandEventHandler) Events[ItemCommandKey];
           
            if (eh != null)
            {
                eh(this, e);
            }
        }

        #endregion Protected methods
    }
}

LoginControl použijeme na testovací stránce a zadáme anonymní šablonu.

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="WebControlLibrary1" Namespace="RStein.Web.UI.WebControls"
    TagPrefix="cc2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Testovací stránka</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <cc2:LoginControl ID="LoginControl1" runat="server" AnonymousUserMessage="Přihlašte se prosím" OnLoginRequest="LoginControl1_LoginRequest">
            <AnonymousTemplate>
                <asp:label runat="server" ID="lblMessage"><%#Container.AnonymousMessage%> </asp:label> <br />
                <asp:LinkButton Id="Login" runat="server" Text="Přihlásit se" />                          
            </AnonymousTemplate>
        </cc2:LoginControl>
        <
    </div>
    </form>
</body>
</html>

Tlačítko Login i popisek lblMessage deklarované v šabloně jsou přímo dostupné ze stránky, jak si můžeme ověřit, když v události PreRender stránky změníme barvu pozadí popisku lblMessage. Nemusíme používat metodu FindControl, ani přetypovávat, což jsou docela příjemná vylepšení kódu ;)

 private void Page_PreRender(object sender, EventArgs e)
    {
        LoginControl1.DataBind();

        if (lblMessage != null)
        {
            lblMessage.BackColor = Color.Cyan;
        }
    }

 

Abyste mohli ovládací prvek LoginControl zkompilovat, následuje kód používaných pomocných tříd.

using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;

namespace RStein.Web.UI.WebControls
{
    /// <summary>
    /// Kontejner pro šablony
    /// </summary>
    [ToolboxItem(false)]
    public class LoginControlContent : Control, INamingContainer
    {
        #region Private variables
        private string m_userName;
        private string m_anonymousMessage;
        private string m_loggedInMessage;
        #endregion Private variables
        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="userName">Jméno uživatele</param>
        /// <param name="anonymousMessage">Zpráva pro nepřihlášeného uživatele</param>
        /// <param name="loggedInMessage">Zpráva pro přihlášeného uživatele</param>
        internal LoginControlContent(string userName, string anonymousMessage, string loggedInMessage)
        {
            m_userName = userName;
            m_anonymousMessage = anonymousMessage;
            m_loggedInMessage = loggedInMessage;
        }
        
        /// <summary>
        /// Jméno uživatele
        /// </summary>
        public string UserName
        {
            get
            {
                return m_userName;
            }
        }

        /// <summary>
        ///Zpráva pro nepřihlášeného uživatele
        /// </summary>
        public string AnonymousMessage
        {
            get
            {
                return m_anonymousMessage;
            }
        }

        /// <summary>
        ///Zpráva pro přihlášeného uživatele
        /// </summary>
        public string LoggedInMessage
        {
            get
            {
                return m_loggedInMessage;
            }
        }
    }
}

using System;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace RStein.Web.UI.WebControls
{
    /// <summary>
    /// Standardní šablona pro nepřihlášeného uživatele
    /// </summary>
    public class DefaultAnonymousTemplate : ITemplate
    {
        #region Constructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        internal DefaultAnonymousTemplate()
        {
        }
        #endregion Constructors

        #region public methods
        #region ITemplate Members
        /// <summary>
        /// Implementace InstantiateIn - vytvoření ovládacích prvků anonymní šablony
        /// </summary>
        /// <param name="container">Ovládací prvek, do jehož kolekce Controls bzdou prvky šablony přidány</param>
        public void InstantiateIn(Control container)
        {
            Label lblMessage = new Label();
            lblMessage.ID = "lblMessage";
            lblMessage.DataBinding += new EventHandler(lblMesssage_DataBind);
            
            LiteralControl separator = new LiteralControl("&nbsp;");
            
            LinkButton btnLogin = new LinkButton();
            btnLogin.ID = "btnLogin";
            btnLogin.Text = "Přihlásit";
            btnLogin.CommandName = LoginControl.LOGIN_BUTTON_NAME;

            container.Controls.Add(lblMessage);
            container.Controls.Add(separator);
            container.Controls.Add(btnLogin);


        }

        #endregion ITemplate Members
        #endregion public methods
        
        #region private methods
        //Handler události DataBind prvku lblMessage
        private void lblMesssage_DataBind(object sender, EventArgs e)
        {
            Label lblMessage = (Label) sender;
            LoginControlContent currContent = lblMessage.NamingContainer as LoginControlContent;
            lblMessage.Text = currContent.AnonymousMessage;
        }
        #endregion private methods
    }
}

using System;
using System.Web.UI.WebControls;
using System.Web.UI;

namespace RStein.Web.UI.WebControls
{
    /// <summary>
    /// Standardní šablona pro přihlášeného uživatele
    /// </summary>
    public class DefaultLoggedInTemplate : ITemplate
    {
        #region constructors
        /// <summary>
        /// Konstruktor
        /// </summary>
        internal DefaultLoggedInTemplate()
        {
        }
        #endregion constructors

        #region public methods
        #region ITemplate Members
        /// <summary>
        /// Implementace InstantiateIn - vytvoření ovládacích prvků anonymní šablony
        /// </summary>
        /// <param name="container">Ovládací prvek, do jehož kolekce Controls bzdou prvky šablony přidány</param>
        public void InstantiateIn(Control container)
        {
            Label lblMessage = new Label();
            lblMessage.ID = "lblMessage";
            lblMessage.DataBinding += new EventHandler(lblMesssage_DataBind);
            
            LiteralControl separator = new LiteralControl("&nbsp;");
            
            LinkButton btnLogout = new LinkButton();
            btnLogout.ID = "btnLogout";
            btnLogout.Text = "Odhlásit";
            btnLogout.CommandName = LoginControl.LOGOUT_BUTTON_NAME;

            container.Controls.Add(lblMessage);
            container.Controls.Add(separator);
            container.Controls.Add(btnLogout);


        }

        #endregion ITemplate Members
        #endregion public methods
        
        #region private methods
        //Handler události DataBind prvku lblMessage
        private void lblMesssage_DataBind(object sender, EventArgs e)
        {
            Label lblMessage = (Label) sender;
            LoginControlContent currContent = lblMessage.NamingContainer as LoginControlContent;
            lblMessage.Text = currContent.LoggedInMessage + " " + currContent.UserName;
        }
        #endregion private methods
    }
}

 



Monday, 09 October 2006 15:42:53 (Central Europe Standard Time, UTC+01:00)       
Comments [2]  .NET Framework | ASP.NET