Monday, July 16, 2007
Saturday, July 7, 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, July 7, 2007 5:15:35 PM (Central Europe Standard Time, UTC+01:00)
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, July 7, 2007 2:52:56 PM (Central Europe Standard Time, UTC+01:00)
Mobilitky
Monday, July 2, 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, July 2, 2007 8:07:26 PM (Central Europe Standard Time, UTC+01:00)
Mobilitky | Net Monitor
Wednesday, June 27, 2007
Monday, February 12, 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, February 12, 2007 6:50:49 PM (Central Europe Standard Time, UTC+01:00)
Kurzy UML a OOP | Ostatní
Sunday, October 29, 2006
Analytická hádanka - žhnoucí vztahy mezi třídami
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 , 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.
A 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, October 29, 2006 10:41:37 PM (Central Europe Standard Time, UTC+01:00)
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, October 29, 2006 8:52:11 PM (Central Europe Standard Time, UTC+01:00)
Compact .Net Framework
Monday, October 9, 2006
ASP.NET - jednoduchý přístup z kódu na webovém formuláři k prvkům deklarovaným v šabloně
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(" ");
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(" ");
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, October 9, 2006 3:42:53 PM (Central Europe Standard Time, UTC+01:00)
.NET Framework | ASP.NET
Wednesday, September 13, 2006
Windows Forms DataGridView - nevykreslování záhlaví sloupce
V .Net konferenci na serveru builder se objevil dotaz, jak skrýt záhlaví (header) sloupce v DataGridView. Kolegové, zvyklí pravděpodobně stále na poněkud nehrabaný DataGrid z verze 1.x .Net Frameworku, radili vytvořit nový sloupec a nové záhlaví.
Nejjednodušší řešení ale představuje odchycení události CellPainting DatagridView a a v ní zamezíte vykreslení sloupce nastavením vlastnosti Handled na true. DataGridView má ale mnohem lepší objektový model než DataGrid a jednoduchých změn ve vykreslování DataGridView dosáhneme rychle v obsluze událostí CellPainting, RowPrePaint, RowPostPaint a dalších.
const int hiddenRowIndex = -1; //záhlaví má index -1
const int hiddenColumnIndex = 0; //skryjeme první sloupec
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == hiddenRowIndex && e.ColumnIndex == hiddenColumnIndex)
{
e.Handled = true;
}
}
Update : Samozřejmě nemusíte zcela rezignovat na vykreslení buňky a chcete vybarvit alespoň její pozadí.
Opět je to jednoduché - vyplníme pozadí a nastavíme e.Handled na true
e.Graphics.FillRectangle(myColor, e.CellBounds);
e.Handled = true;
Wednesday, September 13, 2006 5:17:52 PM (Central Europe Standard Time, UTC+01:00)
.NET Framework | Windows Forms