<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>René Stein - WP7</title>
    <link>http://blog.renestein.net/</link>
    <description>Názory vzešlé z mesaliance humanitní skepse a technologického optimismu</description>
    <image>
      <url>http://blog.renestein.net/themes/discreetBlogBlue/SpotImages/sfinga_rss.jpg</url>
      <title>René Stein - WP7</title>
      <link>http://blog.renestein.net/</link>
    </image>
    <language>cs-CZ</language>
    <copyright>René Stein</copyright>
    <lastBuildDate>Tue, 06 Dec 2011 14:17:03 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.7174.0</generator>
    <managingEditor>rene@renestein.net</managingEditor>
    <webMaster>rene@renestein.net</webMaster>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=5773e213-e568-429b-85da-179c954f22c3</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,5773e213-e568-429b-85da-179c954f22c3.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,5773e213-e568-429b-85da-179c954f22c3.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=5773e213-e568-429b-85da-179c954f22c3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Několik lidí mi psalo na email, že by chtěli demo z <a href="http://jdem.cz/suru9">první
přednášky</a> na <a href="http://ms-fest.cz/">MS Festu</a>.
</p>
        <p>
Zde je:
</p>
        <p>
          <a href="http://jdem.cz/sxs63">
            <big>http://jdem.cz/sxs63</big>
          </a>
        </p>
        <p>
Podrobné informace, na které nebyl na přednášce čas, naleznete v sérii článků <strong>Tipy
pro Windows Phone 7 aplikace</strong> v <a href="http://jdem.cz/sxs92">sekci o WP7
aplikacích</a>. 
</p>
        <p>
          <em>Asi nemusím zdůrazňovat, že jde o demo, tedy kód nemusí mít produkční kvalitu,
za nic neručím a určitě ke kódu není poskytována žádná podpora.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Demo-z-MS-Festu_D343/wlEmoticon-smile_2.png" /></em>
        </p>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=5773e213-e568-429b-85da-179c954f22c3" />
      </body>
      <title>Demo z MS Festu</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,5773e213-e568-429b-85da-179c954f22c3.aspx</guid>
      <link>http://blog.renestein.net/Demo+Z+MS+Festu.aspx</link>
      <pubDate>Tue, 06 Dec 2011 14:17:03 GMT</pubDate>
      <description>&lt;p&gt;
Několik lidí mi psalo na email, že by chtěli demo z &lt;a href="http://jdem.cz/suru9"&gt;první
přednášky&lt;/a&gt; na &lt;a href="http://ms-fest.cz/"&gt;MS Festu&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Zde je:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://jdem.cz/sxs63"&gt;&lt;big&gt;http://jdem.cz/sxs63&lt;/big&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Podrobné informace, na které nebyl na přednášce čas, naleznete v sérii článků &lt;strong&gt;Tipy
pro Windows Phone 7 aplikace&lt;/strong&gt; v &lt;a href="http://jdem.cz/sxs92"&gt;sekci o WP7
aplikacích&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Asi nemusím zdůrazňovat, že jde o demo, tedy kód nemusí mít produkční kvalitu,
za nic neručím a určitě ke kódu není poskytována žádná podpora.&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Demo-z-MS-Festu_D343/wlEmoticon-smile_2.png"&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=5773e213-e568-429b-85da-179c954f22c3" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,5773e213-e568-429b-85da-179c954f22c3.aspx</comments>
      <category>C#</category>
      <category>Návrhové vzory</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=dedfc31d-f3cb-4579-ab0b-cf27616119b7</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,dedfc31d-f3cb-4579-ab0b-cf27616119b7.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,dedfc31d-f3cb-4579-ab0b-cf27616119b7.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=dedfc31d-f3cb-4579-ab0b-cf27616119b7</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p align="left">
Dnes jsem měl dvě přednášky na <a href="http://ms-fest.cz/Program/Sobota">MS Festu</a>. 
</p>
        <h5>Vývoj WP 7 aplikací pro pokročilé
</h5>
        <p>
          <strong>Strasti a slasti vývoje wp7 aplikací. I Mango chutná hořko sladce.</strong>
        </p>
        <p align="left">
Prezentace z přednášek naleznete níže.
</p>
        <p align="left">
Chci poděkovat lidem, kteří MS Fest připravují (klobouk dolů, v jakém počtu to zvládnou)
a kteří mě oslovili a dovolili mi dnes přednášet. MS Fest se koná ještě zítra, pokud
můžete, vyražte. Třeba přednášky o WCF RIA Services, PRISMu nebo přednáška o psaní
testovatelného kódu budou určitě stát za výlet do Prahy.
</p>
        <p align="left">
Mně se jen potvrdilo, že na odbornou přednášku (ta první) je jedna hodina málo a na
bulvární přednášku (ta druhá) až moc.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png" /></p>
        <p align="left">
Jsem moc rád, že jsem viděl známé tváře a že jsem se seznámil s mnoha zajímavými lidmi.
Omlouvám se těm, kteří se ke mně ani o poslední přestávce nedostali, nebylo v mých
silách jít ke každému a zodpovědět všechny dotazy. A děkuji i za hromadné odpolední
follow na twitteru, sice nevím, co to přesně znamená, ale to neznačí, že si toho nevážím. <img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png" /></p>
        <p align="left">
Také chci poděkovat pánovi z Nokie (omlouvám se, neslyšel jsem v tomu hluku vaše jméno),
díky kterému jsem si na přednášce procvičil asertivní chování.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png" /></p>
        <p align="left">
Pár dalších postřehů, abych nemusel odpovídat jednotlivě na Twitteru a na G+:
</p>
        <ol>
          <li>
            <div align="left">Názory na druhou přednášku se liší, což se dalo čekat. Třeba <a href="https://twitter.com/#!/WindMobiDown/status/140475583082663936">https://twitter.com/#!/WindMobiDown/status/140475583082663936</a> X <a href="https://plus.google.com/104228058858941704434/posts/RxgW6HUtsib">https://plus.google.com/104228058858941704434/posts/RxgW6HUtsib</a><br />
Takže malý komentář: Když jsem nabízel témata pro MS Fest, bylo zřejmé, že nebudu
chválit. Na webu se dá dohledat dost mých vyjádření k WP7, ze kterých plyne, že ze
současné podoby WP7 nejsem nadšený. Také jsem si uvědomoval, že na MS Fest se přednáška
nemusí hodit – jedná se o akci zaštiťovanou Mícrosoftem a ani předpokládaní účastníci
MS Festu nemusí být nadšeni. Ještě během podzimu jsem tyto své pochyby konzultoval
s jedním z pořadatelů, s Tomášem Hercegem, ale shodli jsme se, že Microsoft určitě
pár nekorektních slov na svou adresu přežije. Orel much nelapá a Microsoft podle mě
nikdy moc přecitlivělý na kritiku nebyl.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png" /><br /><br /></div>
          </li>
          <li>
            <div align="left">Přednášku jsem 3x přepracoval, většinu věcí vyházel a nakonec jsem
ji nechal v nevážné podobě. I jsem avizoval, jak jsou přednášky postaveny, abych lidi
odradil.<br /><br /><a href="https://twitter.com/#!/renestein/status/140185759683575808">https://twitter.com/#!/renestein/status/140185759683575808</a><br /><br /><a href="https://twitter.com/#!/renestein/status/139983752788049920">https://twitter.com/#!/renestein/status/139983752788049920</a><br /><br /><br /></div>
          </li>
          <li>
            <div align="left">Kdybych měl mít jen tu druhou přednášku na MS Festu a nebyla mi
schválena první přednáška, ani ta druhá by nezazněla. Neměla by smysl. Počítal jsem
s tím, že na obou přednáškách budou stejní lidé a že po přednášce, která o WP7 pojednává
s plnou vážností, přijmou i tu, u které je i doprovodná prezentace zcela jiná. Na
začátku jsem také zmínil, že kromě faktů k API WP7 pronesu subjektivní postřehy, nekorektní
poznámky a domněnky, které mohou účastníci ignorovat. A uváděná fakta, jestliže mají
lepší informace, opravit. Skoro na konci prezentace jsou v kontrapozici můj sarkastický
pesimistický výrok a nadšený (nadsazený?) výrok Radka Hulána – i to jsem považoval
za jasný signál, že prezentace je názorově jednostranná (kdo zná Radka, pochopil)
a korektivem k ní byla první přednáška.<br /><br /></div>
          </li>
          <li>
            <div align="left">Pokud to zaniklo, tak leitomotivem druhé přednášky bylo:”Otravujme
jako vývojáři Microsoft, ať nám ve WP7 nehází drobky ze stolu, ale poskytne nám servis,
na který jsme zvyklí.”<br /></div>
          </li>
        </ol>
        <p align="left">
A ještě. Záznam z mých přednášek nebude. Bohužel informace o natáčení byla rozesílána
až tento týden, navíc jsem před přechodem na nový notebook a nechtěl jsem riskovat,
že na můj již tak zkoušený stávající notebook nainstaluju nějaký SW, o kterém moc
nevím. Mám špatnou zkušenost z instalace nějakého prezentačního SW, který mi na inhouse
kurzu poté nedovolil přepnout výstup na projektor. Na veřejné a jen hodinové přednášce
by to mohl být ještě větší průšvih. Ani mi to ale moc nevadilo, protože během tohoto
podzimu se neustále potýkám se ztrátou hlasu a dalšími radostmi, takže jsem se bál,
že můj výkon dotčený soustředěním na namáhané hlasivky bude navíc ještě zvěčněn na
nějakém videu.<img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png" /></p>
        <p align="left">
Díky, že jste přišli!:)
</p>
        <div style="width: 425px" id="__ss_10342811">
          <strong style="margin: 12px 0px 4px; display: block">
            <a title="Vývoj wp 7 aplikací pro pokročilé" href="http://www.slideshare.net/renestein1/vvoj-wp-7-aplikac-pro-pokroil" target="_blank">Vývoj
wp 7 aplikací pro pokročilé</a>
          </strong>
          <iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/10342811" frameborder="0" width="425" marginwidth="0" scrolling="no">
          </iframe>
          <div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px">View
more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/renestein1" target="_blank">René
Stein</a></div>
        </div>
        <div style="width: 425px" id="__ss_10342810">
          <strong style="margin: 12px 0px 4px; display: block">
            <a title="Strasti a slasti vývoje wp7 aplikací" href="http://www.slideshare.net/renestein1/strasti-a-slasti-vvoje-wp7-aplikac" target="_blank">Strasti
a slasti vývoje wp7 aplikací</a>
          </strong>
          <iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/10342810" frameborder="0" width="425" marginwidth="0" scrolling="no">
          </iframe>
          <div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px">View
more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/renestein1" target="_blank">René
Stein</a></div>
        </div>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=dedfc31d-f3cb-4579-ab0b-cf27616119b7" />
      </body>
      <title>Prezentace z MS Festu 2011 a stručn&amp;yacute; koment&amp;aacute;ř</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,dedfc31d-f3cb-4579-ab0b-cf27616119b7.aspx</guid>
      <link>http://blog.renestein.net/Prezentace+Z+MS+Festu+2011+A+Stru%c4%8dnyacute+Komentaacute%c5%99.aspx</link>
      <pubDate>Sat, 26 Nov 2011 19:15:12 GMT</pubDate>
      <description>&lt;p align="left"&gt;
Dnes jsem měl dvě přednášky na &lt;a href="http://ms-fest.cz/Program/Sobota"&gt;MS Festu&lt;/a&gt;. 
&lt;/p&gt;
&lt;h5&gt;Vývoj WP 7 aplikací pro pokročilé
&lt;/h5&gt;
&lt;p&gt;
&lt;strong&gt;Strasti a slasti vývoje wp7 aplikací. I Mango chutná hořko sladce.&lt;/strong&gt;
&lt;/p&gt;
&lt;p align="left"&gt;
Prezentace z přednášek naleznete níže.
&lt;/p&gt;
&lt;p align="left"&gt;
Chci poděkovat lidem, kteří MS Fest připravují (klobouk dolů, v jakém počtu to zvládnou)
a kteří mě oslovili a dovolili mi dnes přednášet. MS Fest se koná ještě zítra, pokud
můžete, vyražte. Třeba přednášky o WCF RIA Services, PRISMu nebo přednáška o psaní
testovatelného kódu budou určitě stát za výlet do Prahy.
&lt;/p&gt;
&lt;p align="left"&gt;
Mně se jen potvrdilo, že na odbornou přednášku (ta první) je jedna hodina málo a na
bulvární přednášku (ta druhá) až moc.&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p align="left"&gt;
Jsem moc rád, že jsem viděl známé tváře a že jsem se seznámil s mnoha zajímavými lidmi.
Omlouvám se těm, kteří se ke mně ani o poslední přestávce nedostali, nebylo v mých
silách jít ke každému a zodpovědět všechny dotazy. A děkuji i za hromadné odpolední
follow na twitteru, sice nevím, co to přesně znamená, ale to neznačí, že si toho nevážím. &lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p align="left"&gt;
Také chci poděkovat pánovi z Nokie (omlouvám se, neslyšel jsem v tomu hluku vaše jméno),
díky kterému jsem si na přednášce procvičil asertivní chování.&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p align="left"&gt;
Pár dalších postřehů, abych nemusel odpovídat jednotlivě na Twitteru a na G+:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div align="left"&gt;Názory na druhou přednášku se liší, což se dalo čekat. Třeba &lt;a href="https://twitter.com/#!/WindMobiDown/status/140475583082663936"&gt;https://twitter.com/#!/WindMobiDown/status/140475583082663936&lt;/a&gt; X &lt;a href="https://plus.google.com/104228058858941704434/posts/RxgW6HUtsib"&gt;https://plus.google.com/104228058858941704434/posts/RxgW6HUtsib&lt;/a&gt;
&lt;br&gt;
Takže malý komentář: Když jsem nabízel témata pro MS Fest, bylo zřejmé, že nebudu
chválit. Na webu se dá dohledat dost mých vyjádření k WP7, ze kterých plyne, že ze
současné podoby WP7 nejsem nadšený. Také jsem si uvědomoval, že na MS Fest se přednáška
nemusí hodit – jedná se o akci zaštiťovanou Mícrosoftem a ani předpokládaní účastníci
MS Festu nemusí být nadšeni. Ještě během podzimu jsem tyto své pochyby konzultoval
s jedním z pořadatelů, s Tomášem Hercegem, ale shodli jsme se, že Microsoft určitě
pár nekorektních slov na svou adresu přežije. Orel much nelapá a Microsoft podle mě
nikdy moc přecitlivělý na kritiku nebyl.&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png"&gt; 
&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Přednášku jsem 3x přepracoval, většinu věcí vyházel a nakonec jsem
ji nechal v nevážné podobě. I jsem avizoval, jak jsou přednášky postaveny, abych lidi
odradil.&lt;br&gt;
&lt;br&gt;
&lt;a href="https://twitter.com/#!/renestein/status/140185759683575808"&gt;https://twitter.com/#!/renestein/status/140185759683575808&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a href="https://twitter.com/#!/renestein/status/139983752788049920"&gt;https://twitter.com/#!/renestein/status/139983752788049920&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Kdybych měl mít jen tu druhou přednášku na MS Festu a nebyla mi
schválena první přednáška, ani ta druhá by nezazněla. Neměla by smysl. Počítal jsem
s tím, že na obou přednáškách budou stejní lidé a že po přednášce, která o WP7 pojednává
s plnou vážností, přijmou i tu, u které je i doprovodná prezentace zcela jiná. Na
začátku jsem také zmínil, že kromě faktů k API WP7 pronesu subjektivní postřehy, nekorektní
poznámky a domněnky, které mohou účastníci ignorovat. A uváděná fakta, jestliže mají
lepší informace, opravit. Skoro na konci prezentace jsou v kontrapozici můj sarkastický
pesimistický výrok a nadšený (nadsazený?) výrok Radka Hulána – i to jsem považoval
za jasný signál, že prezentace je názorově jednostranná (kdo zná Radka, pochopil)
a korektivem k ní byla první přednáška.&lt;br&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div align="left"&gt;Pokud to zaniklo, tak leitomotivem druhé přednášky bylo:”Otravujme
jako vývojáři Microsoft, ať nám ve WP7 nehází drobky ze stolu, ale poskytne nám servis,
na který jsme zvyklí.”&lt;br&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p align="left"&gt;
A ještě. Záznam z mých přednášek nebude. Bohužel informace o natáčení byla rozesílána
až tento týden, navíc jsem před přechodem na nový notebook a nechtěl jsem riskovat,
že na můj již tak zkoušený stávající notebook nainstaluju nějaký SW, o kterém moc
nevím. Mám špatnou zkušenost z instalace nějakého prezentačního SW, který mi na inhouse
kurzu poté nedovolil přepnout výstup na projektor. Na veřejné a jen hodinové přednášce
by to mohl být ještě větší průšvih. Ani mi to ale moc nevadilo, protože během tohoto
podzimu se neustále potýkám se ztrátou hlasu a dalšími radostmi, takže jsem se bál,
že můj výkon dotčený soustředěním na namáhané hlasivky bude navíc ještě zvěčněn na
nějakém videu.&lt;img style="border-bottom-style: none; border-left-style: none; border-top-style: none; border-right-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Prezentace-z-MS-Festu-2011-a-strun-komen_10F24/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p align="left"&gt;
Díky, že jste přišli!:)
&lt;/p&gt;
&lt;div style="width: 425px" id="__ss_10342811"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Vývoj wp 7 aplikací pro pokročilé" href="http://www.slideshare.net/renestein1/vvoj-wp-7-aplikac-pro-pokroil" target="_blank"&gt;Vývoj
wp 7 aplikací pro pokročilé&lt;/a&gt;&lt;/strong&gt; 
&lt;iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/10342811" frameborder="0" width="425" marginwidth="0" scrolling="no"&gt;
&lt;/iframe&gt;
&lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View
more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/renestein1" target="_blank"&gt;René
Stein&lt;/a&gt; 
&lt;/div&gt;
&lt;/div&gt;
&lt;div style="width: 425px" id="__ss_10342810"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Strasti a slasti vývoje wp7 aplikací" href="http://www.slideshare.net/renestein1/strasti-a-slasti-vvoje-wp7-aplikac" target="_blank"&gt;Strasti
a slasti vývoje wp7 aplikací&lt;/a&gt;&lt;/strong&gt; 
&lt;iframe height="355" marginheight="0" src="http://www.slideshare.net/slideshow/embed_code/10342810" frameborder="0" width="425" marginwidth="0" scrolling="no"&gt;
&lt;/iframe&gt;
&lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View
more &lt;a href="http://www.slideshare.net/" target="_blank"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/renestein1" target="_blank"&gt;René
Stein&lt;/a&gt; 
&lt;/div&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=dedfc31d-f3cb-4579-ab0b-cf27616119b7" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,dedfc31d-f3cb-4579-ab0b-cf27616119b7.aspx</comments>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=7aff293a-4afa-4efa-8bfa-78500f267cfa</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,7aff293a-4afa-4efa-8bfa-78500f267cfa.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,7aff293a-4afa-4efa-8bfa-78500f267cfa.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=7aff293a-4afa-4efa-8bfa-78500f267cfa</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Přibližně před rokem jsem u dvou firem začínal sérii technologických kurzů subjektivním
shrnutím změn (nejen) v aplikacích psaných v .Net Frameworku. Nedávno jsme ji s kolegou
náhodou otevřeli a pobavili jsme se nad tím, jak je rok v IT stále dlouhá doba a že
zde dvojnásobně platí “tempus fugit”. Napadlo mě, že se nad prezentací možná se pobaví
i někdo další, hlavně v pasážích, kde jemně naznačuju zálibu Microsoftu v zařezávání
technologií.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/de5bdc4acd85_ADFB/wlEmoticon-smile_2.png" /></p>
        <p>
U prezentace je třeba mít na paměti:
</p>
        <ol>
          <li>
Jedná se jen o osnovu “přehledové“ a cca dvouhodinové přednášky.<br /><br /></li>
          <li>
Témata, typy projektů a technologie jsou v přednášce voleny podle zájmu zákazníka.<br /><br /></li>
          <li>
Snažil jsem se nebýt hned  v této úvodní přednášce příliš ostrý a konfliktní.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/de5bdc4acd85_ADFB/wlEmoticon-smile_2.png" /><br /><br /></li>
          <li>
Zvolená témata se týkala oblastí, které jsme v dalších dnech probíraly detailněji
na konkrétních projektech vytvořených na návazných kurzech. Po pár zkušenostech si
myslím, že jediný smyslupný kurz zabývající se technologií či programovacím jazykem
je ten, na kterém píšete před účastníky kód. Tato přednáška byla koncipována jako
motivační úvod k dalším tématům.</li>
        </ol>
        <div style="width: 425px" id="__ss_7332936">
          <strong style="margin: 12px 0px 4px; display: block">
            <a title="Moderni trendy ve_vyvoji_aplikaci" href="http://www.slideshare.net/RENESTEIN/moderni-trendy-vevyvojiaplikaci">Moderni
trendy ve_vyvoji_aplikaci</a>
          </strong>
          <object id="__sse7332936" width="425" height="355">
            <param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=modernitrendyvevyvojiaplikaci-110321070156-phpapp01&amp;stripped_title=moderni-trendy-vevyvojiaplikaci&amp;userName=RENESTEIN" />
            <param name="allowFullScreen" value="true" />
            <param name="allowScriptAccess" value="always" />
            <embed name="__sse7332936" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=modernitrendyvevyvojiaplikaci-110321070156-phpapp01&amp;stripped_title=moderni-trendy-vevyvojiaplikaci&amp;userName=RENESTEIN" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355">
            </embed>
          </object>
          <div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px">View
more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/RENESTEIN">RENESTEIN</a>.
</div>
        </div>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=7aff293a-4afa-4efa-8bfa-78500f267cfa" />
      </body>
      <title>Prezentace Modern&amp;iacute; trendy ve v&amp;yacute;voji aplikac&amp;iacute;</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,7aff293a-4afa-4efa-8bfa-78500f267cfa.aspx</guid>
      <link>http://blog.renestein.net/Prezentace+Moderniacute+Trendy+Ve+Vyacutevoji+Aplikaciacute.aspx</link>
      <pubDate>Mon, 21 Mar 2011 12:11:41 GMT</pubDate>
      <description>&lt;p&gt;
Přibližně před rokem jsem u dvou firem začínal sérii technologických kurzů subjektivním
shrnutím změn (nejen) v aplikacích psaných v .Net Frameworku. Nedávno jsme ji s kolegou
náhodou otevřeli a pobavili jsme se nad tím, jak je rok v IT stále dlouhá doba a že
zde dvojnásobně platí “tempus fugit”. Napadlo mě, že se nad prezentací možná se pobaví
i někdo další, hlavně v pasážích, kde jemně naznačuju zálibu Microsoftu v zařezávání
technologií.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/de5bdc4acd85_ADFB/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
U prezentace je třeba mít na paměti:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Jedná se jen o osnovu “přehledové“ a cca dvouhodinové přednášky.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Témata, typy projektů a technologie jsou v přednášce voleny podle zájmu zákazníka.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Snažil jsem se nebýt hned&amp;nbsp; v této úvodní přednášce příliš ostrý a konfliktní.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/de5bdc4acd85_ADFB/wlEmoticon-smile_2.png"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Zvolená témata se týkala oblastí, které jsme v dalších dnech probíraly detailněji
na konkrétních projektech vytvořených na návazných kurzech. Po pár zkušenostech si
myslím, že jediný smyslupný kurz zabývající se technologií či programovacím jazykem
je ten, na kterém píšete před účastníky kód. Tato přednáška byla koncipována jako
motivační úvod k dalším tématům.&lt;/li&gt;
&lt;/ol&gt;
&lt;div style="width: 425px" id="__ss_7332936"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Moderni trendy ve_vyvoji_aplikaci" href="http://www.slideshare.net/RENESTEIN/moderni-trendy-vevyvojiaplikaci"&gt;Moderni
trendy ve_vyvoji_aplikaci&lt;/a&gt;&lt;/strong&gt;
&lt;object id="__sse7332936" width="425" height="355"&gt;
&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=modernitrendyvevyvojiaplikaci-110321070156-phpapp01&amp;amp;stripped_title=moderni-trendy-vevyvojiaplikaci&amp;amp;userName=RENESTEIN" /&gt;
&lt;param name="allowFullScreen" value="true" /&gt;
&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed name="__sse7332936" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=modernitrendyvevyvojiaplikaci-110321070156-phpapp01&amp;amp;stripped_title=moderni-trendy-vevyvojiaplikaci&amp;amp;userName=RENESTEIN" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View
more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/RENESTEIN"&gt;RENESTEIN&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=7aff293a-4afa-4efa-8bfa-78500f267cfa" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,7aff293a-4afa-4efa-8bfa-78500f267cfa.aspx</comments>
      <category>.NET Framework</category>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>Compact .Net Framework</category>
      <category>LINQ</category>
      <category>RX Extensions</category>
      <category>Silverlight</category>
      <category>Web Services</category>
      <category>Windows Forms</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=be4f9165-3d77-40c8-aea2-e7f8087f9b70</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,be4f9165-3d77-40c8-aea2-e7f8087f9b70.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,be4f9165-3d77-40c8-aea2-e7f8087f9b70.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=be4f9165-3d77-40c8-aea2-e7f8087f9b70</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Na twitteru i v emailu se opakuje stále několik dotazů od lidí, kteří koketují s myšlenkou
pořídit si WP7 telefon nebo chtějí pro WP7 vyvíjet. Účelem tohoto článku není suplovat
uživatelský informační servis o WP7, který u nás skvěle dělá <a href="http://www.smartmania.cz">Smartmania</a> a
kterému se i  v zahraničí  věnuje mnoho webů, ale nabídnout snad trochu
jiné informace než ty, které různí nájemní pisálci stále kopírují z tiskových zpráv
a oficiálních prezentací a které další sociálně-altruističtí trotlové bezmyšlenkovitě
linkují, sdílejí a lajkují.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /></p>
        <p>
          <em>
            <font style="background-color: #00ff00">Je Windows Phone 7 zcela nový operační
systém, který Microsoft skutečně vyvinul  “na zelené louce” a který nemá <strong>NIC</strong> společného
s Windows Mobile?</font>
          </em>
        </p>
        <p>
Je i není.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-winkingsmile_2.png" /> Neuspokojivá
odpověď ve stylu hárající chytré horákyně, já vím. Windows Phone 7 jsou postaveny
na operačním systému Windows CE, na kterém běžely i Windows Mobile. Dnešní oficiální
název zní <a href="http://msdn.microsoft.com/en-us/library/ee483001.aspx">Windows
Embedded CE</a> a aktuální verze má pořadové číslo 6. I Windows Mobile v poslední
verzi 6.5 byly stále založeny na Windows CE 5. Jak vidíte, Microsoft nám to moc neulehčuje
a  číslo verze Windows Mobile není nijak závislé na verzi použitých Windows CE.
WP7 dle všech indicií běží na buildu Windows CE 6.
</p>
        <p>
Windows CE 6 mají oprotí Windows CE 5 několik výhod. A z toho plyne, že i WP7 využívají
nových rysů v systému a netrpí hlavními problémy Windows Mobile aplikací.
</p>
        <ul>
          <li>
Ve Windows CE 5 mohlo běžet najednou maximálně 32 procesů. Ano, celých 32 procesů
musí stačit každému, ale s tím, jak se smartphony/PDA/MDA vyvíjely a výrobci ihned
po startu zařízení obsazovali stále více procesních slotů pro své a se zařízením dodávané
aplikace, se tento limit kupodivu ukázal nedostačující. Podpora cca 32 000 procesů
ve Windows CE 6 je pořádné zlepšení. 
<br /><br /></li>
          <li>
Ve Windows CE 5 měl každý proces 32 MB virtuální paměti a všechny procesy sdílely
4 GB adresní prostor. Nechci zabíhat do detailů, ale způsob nahrávání dynamických
knihoven a jejich sdílení mezi procesy mohl vést velmi rychle k fragmentaci paměti
a k chybě “nedostatek paměti”, i když fyzické paměti bylo dostatek. V CE 6.0 jsou
2 GB virtuálního paměťového prostoru vyhrazeny pro kernel a 2 GB pro každý proces.
Správa paměti v CE 6 má některé nepříjemné dopady na vývojáře kernel/user driverů,
ale pro uživatele i vývojáře aplikací je tento paměťový model mnohem lepší.</li>
        </ul>
        <p>
 
</p>
        <p>
Mobilní Silverlight ve WP7 interně využívá Compact .Net Framework, který můžete znát
z Windows Mobile. Jestliže pro WP7 vyvíjíte, poznáte to i podle toho, že při ladění
aplikace a pokusu editovat zdrový kód vám Visual Studio hlásí, že Compact .Net Framework
aplikace nemohou být při ladění upravovány.
</p>
        <p>
Shrnuto – Windows Phone 7 mají nový kabátek (UI Metro), nová běhová prostředí pro
uživatelské aplikace (Silverlight, XNA Framework) a vylepšený podvozek (CE 6). Psát
a hlavně v článcích zdůrazňovat, že WP7 nemají se staršími Windows Mobile <strong>NIC</strong> společného,
mi přijde v lepším případě naivní, v tom horším okázale neprofesionální. Už minulý
rok jsem psal několikrát , že Microsoft <a href="http://twitter.com/#!/renestein/status/22298585861193730">by
těžko za pár měsíců vyvinul zcela nový mobilní operační systém</a>.
</p>
        <p>
          <em>
            <font style="background-color: #00ff00">Mohu v ČR nakupovat aplikace v  marketplace?</font>
          </em>
        </p>
        <p>
          <font style="background-color: #00ff00">
          </font>Stručná odpověď: Ne. 
</p>
        <p>
Složitější odpověď. Microsoft podle neoficiálních informací uvažuje, že marketplace
v ČR bude dostupný “v létě <strike>2010 </strike>2011”. 
<br />
Neoficiálně to jde – stačí mít zahraniční platební kartu, založit nějaký Live účet,
kde nastavíte, že pocházíte třeba z USA/UK. Ale musíte být asi velcí blázni nebo nadšenci,
abyste si přes tyto obstrukce kupovali dnes (psáno 15.2. 2011) v ČR WP7 telefon. Počítejte
také s tím, že když Microsoft zpřístupní marketplace pro ČR, a vy budete chtít používat
svůj běžný Live účet, zakoupené aplikace mezi různými Live účty nepřevedete.
</p>
        <p>
          <em>
            <font style="background-color: #00ff00">Mohu dnes dát svou WP7 aplikaci do marketplace?</font>
          </em>
        </p>
        <p>
Stručná odpověď: Ne. 
<br />
Složitější odpověď. Pokud chcete dát aplikaci do marketplace, vyvíjejte se zahraničním
partnerem. Je možné také se s trochou kreativity při tvorbě vývojářského účtu (v komentářích
tohle sousloví vysvětlovat raději nebudu<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" />)
registrovat jako vývojář z jiné země, pokud máte zahraniční platební kartu, ale riskujete,
že Microsoft na tento “trik” přijde a zablokuje vám prodej aplikací, protože porušujete
jeho podmínky.
</p>
        <p>
          <font style="background-color: #00ff00">
            <em>Dobře, jsem smířen s tím, že se do market
place prozatím nedostanu, ale přesto chci svou aplikaci otestovat na reálném zařízení,
a ne jen v emulátoru. Jak to udělám, když mi WP7 telefon nedovolí nahrát vlastní aplikace?</em>
          </font>
        </p>
        <p>
          <font style="background-color: #00ff00">
          </font>Nejjednodušší je dnes použít Chevron
WP7 k neoficiálnímu odemknutí telefonu. Poté co telefon odemknete, můžete nahrávat
své vlastní aplikace. <a href="http://forum.xda-developers.com/showthread.php?t=857127">Podrobný
návod, jak odemknout telefon, je na XDA-Developers</a>, takže jej zde nebudu opakovat.
Autoři Chevronu používají na odemčení WP7 telefonu jednoduchý trik. Požadavek na odemčení
telefonu cílený na servery Microsoftu přesměrují na lokální počítač a odemčení telefonu
povolí.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /> Výhodou
je, že nejde o vážný zásah do zařízení, nevýhodou, že pro Microsoft bude snadné tuhle
“díru” (dá se pro tohle amatérské zabezpečení najít nějaký jiný eufemismus?) 
uzavřít další plánovanou aktualizací. Microsoft ale po setkání s autory Chevronu přislíbil,
že sám umožní “co nejdříve” vývojářům nahrání a ladění vlastních aplikací v telefonu,
aniž by bylo nutné otevírat a platit za vývojářský účet. Neznámou proměnnou je, které
jednotky pro měření času používá Microsoft, kde, soudě podle stále odkládaného data
první aktualizace pro WP7, korporátní čas evidentně plyne pomaleji, a jestli optimistická
fráze “co nejdříve” zahrnuje alespoň předpokládanou dobu životnosti WP7 na trhu smartphonů.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /></p>
        <p>
          <font style="background-color: #00ff00">Mohu pro WP7 vyvíjet v Compact .Net Frameworku?</font>
        </p>
        <p>
          <font style="background-color: #00ff00" color="#000000">
          </font>
          <font color="#000000">Ne.
I když Microsoft Compact .Net Framework používá a při nahrání Silverlight aplikace
je patrné z debug logů, že se nahrávají CNF assembly, vlastní CNF aplikaci nenapíšete.
Ale – v poslední části tohoto FAQ o prozatím hypotetické možnosti spouštět CNF aplikace
na WP7 zařízení znovu píšu.</font>
        </p>
        <p>
          <em>
            <font style="background-color: #00ff00" color="#000000">Mohu pro WP7 vyvíjet nativni 
(C/C++) aplikace? Slyšel jsem o nějakém Microsoftem vyvinutém nativním frameworku
Iris.</font>
          </em>
        </p>
        <p>
Stručná odpověď: Nativní aplikace nejsou podporovány, můžete vyvíjet jen Silverlight
aplikace nebo aplikace využívající XNA Framework. Na Iris v klidu zapomeňte.
</p>
        <p>
Složitější odpověď: Nejprve vyřídíme IRIS, což je framework, ke kterém jsem se t<a href="http://twitter.com/#!/renestein/status/28408385225">aké
vyjadřoval na twitteru.</a></p>
        <table border="2" cellspacing="0" cellpadding="2" width="400">
          <tbody>
            <tr>
              <td valign="top" width="396">
Twitter:<br /><em>Objevily se bajky o tajném nativním frameworku IRIS pro </em><a href="http://twitter.com/#!/search?q=%23WP7"><em>#WP7</em></a><em>.
IRIS ale připomíná spíš mix CNF/WPF + P/Invoke. Nativní kód =stále WIN CE API</em></td>
            </tr>
          </tbody>
        </table>
        <p>
          <em>Z</em>de jen dodám, že IRIS si můžete představit jako framework, který v MS vyvinuli
vývojáři, kteří asi nesnášejí technologie WPF/XAML/Silverlight  vytvořené jejich
kolegy, <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /> a
proto si navrhli vlastní značkovací jazyk mixovaný s řízeným kódem a množstvím API
(P/Invoke) volání. IRIS Microsoft pravděpodobně používá v shellu a ve svých WP7 aplikacích.
Jestliže jste se ptali, jak to, že u MS aplikací třeba prvky Pivot a Panorama podporují
plynulejší skrolování než stejné prvky v Silverlightu, v použití IRIS frameworku leží
pravděpodobně odpověď. V Microsoftu buď občas neví levice, ce dělá pravíce, anebo
mobilní Silverlight není zas tak odladěn a vyšperkován, jak by se mohlo z prezentací
demo aplikací u MS evangelistů zdát, a teprve IRIS je tím zázrakem, který rozanimuje
výchozí uživatelské rozhraní a dovede recenzenty WP7 systému k stále opakované větě
o “ďábelské rychlosti WP7 aplikací”. Věta “o ďábelské rychlosti WP7 aplikací” platí
paradoxně do té doby, než začnete další aplikace skutečně instalovat, k čemuž se nadšení
recenzenti už asi nedokopou. Trochu sarkasticky dodejme, že v bajtech zhmotněná IRIS
snad není ve WP7 proto, aby poslala brzy bezduché WP7 do křemíkového pekla, stejně
jako kdysi mytologická Iris pomohla Dídó uvolnit duši z těla.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-winkingsmile_2.png" /></p>
        <p>
          <strong>Nativní kód ale některé aplikace napsané v Silverlightu používají. </strong>Jestliže
si prohlédnete XAP soubory (XAP soubor – distribuční soubor Silverlight aplikace) 
aplikací od výrobcu zařízení, zjistíte, že používají knihovnu GAC_Microsoft.Phone.InteropServices_v7_0_0_0_cneutral_1.dll.
Jak název assembly napovídá, měla by sloužit jako most k nativnímu kódu.
</p>
        <p>
Aplikace od výrobce tuto assembly používají pro dynamické volání metod COM objektů.
Zkusil jsem si napsat jednoduchou COM assembly ve VS 2008 pro Windows CE, protože
VS 2010 z rozhodnutí nějaké moudré hlavy ve vývojářské centrále Microsoftu podporu
pro vývoj CE aplikací již neobsahuje. COM knihovnu jsem nazval SL_COM2.dll.
</p>
        <p>
Poté jsem založil projekt v Silverlightu, přidal do něj soubor nazvaný WPInteropManifest.xml,
který obsahují i aplikace od výrobců. Soubor WPInteropManifest.xml má jednoduchý obsah.
</p>
        <script src="http://gist.github.com/827481.js">
        </script>
        <p>
Do projektu jsem přidal knihovnu GAC_Microsoft.Phone.InteropServices_v7_0_0_0_cneutral_1.dll.
i svou COM knihovnu SL_COM2.dll a u obou knihoven jsem nastavil build akci na content,
aby obě knihovny byly přidány do výsledného XAP souboru. Žádné COM Interop knihovny
nevygenerujete, COM typy musíte naimportovat z COM  knihovny “ručně”.
</p>
        <p>
          <script src="http://gist.github.com/827501.js">
          </script>
        </p>
        <p>
Pomocí reflexe zaregistrujeme COM knihovnu na cílovém zařízení s využitím metod v
assembly GAC_Microsoft.Phone.InteropServices_v7_0_0_0_cneutral_1.dll.
</p>
        <p>
          <script src="http://gist.github.com/827506.js">
          </script>
        </p>
        <p>
Tento kód projde, ale na posledním řádku dostanete výjimku, která znamená, že vaše
COM knihovna je nekompatibilní s aktuální verzí operačního systému. Musíte si na internetu
“najít” a nainstalovat správný Platform builder, <a href="http://blog.walshie.me/2010/11/15/windows-phone-7-full-file-system-access-anyone/#comment-244">což
udělal asi Ch. Welsh, nebo si pohrát s PE hlavičkami knihoven, což jsem udělal já</a>.
COM knihovna by mohla být po odstranění všech překážek i branou ke všem API funkcím,
které si vystavíte v COM objektech. Nepředpokládejte ale, že vaše aplikace bude při
využívání COM knihovny přijata do marketplace.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /></p>
        <p>
          <font style="background-color: #00ff00">Když jsou problémy s umístěním aplikací do
marketplace, je naděje, že brzy bude pro WP7 existovat “jailbreak” a my budeme mít
obchod s neoficiálními aplikacemi? Dají se WP7 “hacknout”?<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /></font>
        </p>
        <p>
Všechno jde, jen to stojí čas a peníze. A musíte mít přitom víru, že WP7 z trhu rychle
nezmizí.
</p>
        <p>
Hlavní problém je podle mě v tom, že Silverlight aplikace běží ve <a href="http://msdn.microsoft.com/en-us/library/dd470128(v=vs.95).aspx">striktním
bezpečnostním modelu</a>, který není snadné překonat. Takže možnosti, které mě napadají:
</p>
        <p>
Metoda pokus-omyl – začneme hledat slabiny v zabezpečení celé CE platformy a doufat,
že Microsoft někde udělal další školáckou chybu podobnou té, kterou využil Chevron,
jen teď někde v mnohem nižších vrstvách systému. Třeba kdyby Microsoft ponechal i
byť jen trochu pootevřen přístup k <a href="http://msdn.microsoft.com/en-us/library/aa920177.aspx">RAPI</a>,
to by byla paráda. Sice se dá “získat” a použít knihovna SmartDevice.Connectivity,
která RAPI interně využívá, ale neodemčený telefon nespolupracuje.
</p>
        <p>
Ukázka volání:
</p>
        <p>
          <script src="http://gist.github.com/827526.js">
          </script>
        </p>
        <p>
Daleko nadějnější mi přijde pokračovat tak, že se do CE registrů přidá vlastní driver,
který po startu zařízení shodí výchozí WP7 shell a dovolí vám nainstalovat a spouštět 
nativní aplikace i aplikace psané v Compact .Net Frameworku. V dalším kroku by to
chtělo nového hostitele Silverlight aplikací, který bude vstřícnější k neoficiálním
aplikacím. <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /> Na
některých HTC zařízeních se průnik do registru již podařil… Takže nezbývá než zopakovat:
Všechno jde, jen to stojí čas a peníze.
</p>
        <p>
Snad jste v tomhle článků nalezli alespoň něco zajímavějšího než v konfekčních článcích
o WP7.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png" /></p>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=be4f9165-3d77-40c8-aea2-e7f8087f9b70" />
      </body>
      <title>FAQ k WP7 a p&amp;aacute;r specialitek nav&amp;iacute;c &amp;ndash; aneb co jste vždy chtěli vědět o WP7, ale v Microsoftu se v&amp;aacute;m b&amp;aacute;li odpovědět</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,be4f9165-3d77-40c8-aea2-e7f8087f9b70.aspx</guid>
      <link>http://blog.renestein.net/FAQ+K+WP7+A+Paacuter+Specialitek+Naviacutec+Ndash+Aneb+Co+Jste+V%c5%bedy+Cht%c4%9bli+V%c4%9bd%c4%9bt+O+WP7+Ale+V+Microsoftu+Se+Vaacutem+Baacuteli+Odpov%c4%9bd%c4%9bt.aspx</link>
      <pubDate>Tue, 15 Feb 2011 14:23:05 GMT</pubDate>
      <description>&lt;p&gt;
Na twitteru i v emailu se opakuje stále několik dotazů od lidí, kteří koketují s myšlenkou
pořídit si WP7 telefon nebo chtějí pro WP7 vyvíjet. Účelem tohoto článku není suplovat
uživatelský informační servis o WP7, který u nás skvěle dělá &lt;a href="http://www.smartmania.cz"&gt;Smartmania&lt;/a&gt; a
kterému se i&amp;nbsp; v zahraničí&amp;nbsp; věnuje mnoho webů, ale nabídnout snad trochu
jiné informace než ty, které různí nájemní pisálci stále kopírují z tiskových zpráv
a oficiálních prezentací a které další sociálně-altruističtí trotlové bezmyšlenkovitě
linkují, sdílejí a lajkují.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;font style="background-color: #00ff00"&gt;Je Windows Phone 7 zcela nový operační
systém, který Microsoft skutečně vyvinul&amp;nbsp; “na zelené louce” a který nemá &lt;strong&gt;NIC&lt;/strong&gt; společného
s Windows Mobile?&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Je i není.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-winkingsmile_2.png"&gt; Neuspokojivá
odpověď ve stylu hárající chytré horákyně, já vím. Windows Phone 7 jsou postaveny
na operačním systému Windows CE, na kterém běžely i Windows Mobile. Dnešní oficiální
název zní &lt;a href="http://msdn.microsoft.com/en-us/library/ee483001.aspx"&gt;Windows
Embedded CE&lt;/a&gt; a aktuální verze má pořadové číslo 6. I Windows Mobile v poslední
verzi 6.5 byly stále založeny na Windows CE 5. Jak vidíte, Microsoft nám to moc neulehčuje
a&amp;nbsp; číslo verze Windows Mobile není nijak závislé na verzi použitých Windows CE.
WP7 dle všech indicií běží na buildu Windows CE 6.
&lt;/p&gt;
&lt;p&gt;
Windows CE 6 mají oprotí Windows CE 5 několik výhod. A z toho plyne, že i WP7 využívají
nových rysů v systému a netrpí hlavními problémy Windows Mobile aplikací.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Ve Windows CE 5 mohlo běžet najednou maximálně 32 procesů. Ano, celých 32 procesů
musí stačit každému, ale s tím, jak se smartphony/PDA/MDA vyvíjely a výrobci ihned
po startu zařízení obsazovali stále více procesních slotů pro své a se zařízením dodávané
aplikace, se tento limit kupodivu ukázal nedostačující. Podpora cca 32 000 procesů
ve Windows CE 6 je pořádné zlepšení. 
&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Ve Windows CE 5 měl každý proces 32 MB virtuální paměti a všechny procesy sdílely
4 GB adresní prostor. Nechci zabíhat do detailů, ale způsob nahrávání dynamických
knihoven a jejich sdílení mezi procesy mohl vést velmi rychle k fragmentaci paměti
a k chybě “nedostatek paměti”, i když fyzické paměti bylo dostatek. V CE 6.0 jsou
2 GB virtuálního paměťového prostoru vyhrazeny pro kernel a 2 GB pro každý proces.
Správa paměti v CE 6 má některé nepříjemné dopady na vývojáře kernel/user driverů,
ale pro uživatele i vývojáře aplikací je tento paměťový model mnohem lepší.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Mobilní Silverlight ve WP7 interně využívá Compact .Net Framework, který můžete znát
z Windows Mobile. Jestliže pro WP7 vyvíjíte, poznáte to i podle toho, že při ladění
aplikace a pokusu editovat zdrový kód vám Visual Studio hlásí, že Compact .Net Framework
aplikace nemohou být při ladění upravovány.
&lt;/p&gt;
&lt;p&gt;
Shrnuto – Windows Phone 7 mají nový kabátek (UI Metro), nová běhová prostředí pro
uživatelské aplikace (Silverlight, XNA Framework) a vylepšený podvozek (CE 6). Psát
a hlavně v článcích zdůrazňovat, že WP7 nemají se staršími Windows Mobile &lt;strong&gt;NIC&lt;/strong&gt; společného,
mi přijde v lepším případě naivní, v tom horším okázale neprofesionální. Už minulý
rok jsem psal několikrát , že Microsoft &lt;a href="http://twitter.com/#!/renestein/status/22298585861193730"&gt;by
těžko za pár měsíců vyvinul zcela nový mobilní operační systém&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;font style="background-color: #00ff00"&gt;Mohu v ČR nakupovat aplikace v&amp;nbsp; marketplace?&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="background-color: #00ff00"&gt;&lt;/font&gt;Stručná odpověď: Ne. 
&lt;/p&gt;
&lt;p&gt;
Složitější odpověď. Microsoft podle neoficiálních informací uvažuje, že marketplace
v ČR bude dostupný “v létě &lt;strike&gt;2010 &lt;/strike&gt;2011”. 
&lt;br&gt;
Neoficiálně to jde – stačí mít zahraniční platební kartu, založit nějaký Live účet,
kde nastavíte, že pocházíte třeba z USA/UK. Ale musíte být asi velcí blázni nebo nadšenci,
abyste si přes tyto obstrukce kupovali dnes (psáno 15.2. 2011) v ČR WP7 telefon. Počítejte
také s tím, že když Microsoft zpřístupní marketplace pro ČR, a vy budete chtít používat
svůj běžný Live účet, zakoupené aplikace mezi různými Live účty nepřevedete.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;font style="background-color: #00ff00"&gt;Mohu dnes dát svou WP7 aplikaci do marketplace?&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Stručná odpověď: Ne. 
&lt;br&gt;
Složitější odpověď. Pokud chcete dát aplikaci do marketplace, vyvíjejte se zahraničním
partnerem. Je možné také se s trochou kreativity při tvorbě vývojářského účtu (v komentářích
tohle sousloví vysvětlovat raději nebudu&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt;)
registrovat jako vývojář z jiné země, pokud máte zahraniční platební kartu, ale riskujete,
že Microsoft na tento “trik” přijde a zablokuje vám prodej aplikací, protože porušujete
jeho podmínky.
&lt;/p&gt;
&lt;p&gt;
&lt;font style="background-color: #00ff00"&gt;&lt;em&gt;Dobře, jsem smířen s tím, že se do market
place prozatím nedostanu, ale přesto chci svou aplikaci otestovat na reálném zařízení,
a ne jen v emulátoru. Jak to udělám, když mi WP7 telefon nedovolí nahrát vlastní aplikace?&lt;/em&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="background-color: #00ff00"&gt;&lt;/font&gt;Nejjednodušší je dnes použít Chevron
WP7 k neoficiálnímu odemknutí telefonu. Poté co telefon odemknete, můžete nahrávat
své vlastní aplikace. &lt;a href="http://forum.xda-developers.com/showthread.php?t=857127"&gt;Podrobný
návod, jak odemknout telefon, je na XDA-Developers&lt;/a&gt;, takže jej zde nebudu opakovat.
Autoři Chevronu používají na odemčení WP7 telefonu jednoduchý trik. Požadavek na odemčení
telefonu cílený na servery Microsoftu přesměrují na lokální počítač a odemčení telefonu
povolí.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt; Výhodou
je, že nejde o vážný zásah do zařízení, nevýhodou, že pro Microsoft bude snadné tuhle
“díru” (dá se pro tohle amatérské zabezpečení najít nějaký jiný eufemismus?)&amp;nbsp;
uzavřít další plánovanou aktualizací. Microsoft ale po setkání s autory Chevronu přislíbil,
že sám umožní “co nejdříve” vývojářům nahrání a ladění vlastních aplikací v telefonu,
aniž by bylo nutné otevírat a platit za vývojářský účet. Neznámou proměnnou je, které
jednotky pro měření času používá Microsoft, kde, soudě podle stále odkládaného data
první aktualizace pro WP7, korporátní čas evidentně plyne pomaleji, a jestli optimistická
fráze “co nejdříve” zahrnuje alespoň předpokládanou dobu životnosti WP7 na trhu smartphonů.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="background-color: #00ff00"&gt;Mohu pro WP7 vyvíjet v Compact .Net Frameworku?&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="background-color: #00ff00" color="#000000"&gt;&lt;/font&gt;&lt;font color="#000000"&gt;Ne.
I když Microsoft Compact .Net Framework používá a při nahrání Silverlight aplikace
je patrné z debug logů, že se nahrávají CNF assembly, vlastní CNF aplikaci nenapíšete.
Ale – v poslední části tohoto FAQ o prozatím hypotetické možnosti spouštět CNF aplikace
na WP7 zařízení znovu píšu.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;font style="background-color: #00ff00" color="#000000"&gt;Mohu pro WP7 vyvíjet nativni&amp;nbsp;
(C/C++) aplikace? Slyšel jsem o nějakém Microsoftem vyvinutém nativním frameworku
Iris.&lt;/font&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Stručná odpověď: Nativní aplikace nejsou podporovány, můžete vyvíjet jen Silverlight
aplikace nebo aplikace využívající XNA Framework. Na Iris v klidu zapomeňte.
&lt;/p&gt;
&lt;p&gt;
Složitější odpověď: Nejprve vyřídíme IRIS, což je framework, ke kterém jsem se t&lt;a href="http://twitter.com/#!/renestein/status/28408385225"&gt;aké
vyjadřoval na twitteru.&lt;/a&gt;
&lt;/p&gt;
&lt;table border="2" cellspacing="0" cellpadding="2" width="400"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="396"&gt;
Twitter:&lt;br&gt;
&lt;em&gt;Objevily se bajky o tajném nativním frameworku IRIS pro &lt;/em&gt;&lt;a href="http://twitter.com/#!/search?q=%23WP7"&gt;&lt;em&gt;#WP7&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.
IRIS ale připomíná spíš mix CNF/WPF + P/Invoke. Nativní kód =stále WIN CE API&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&lt;em&gt;Z&lt;/em&gt;de jen dodám, že IRIS si můžete představit jako framework, který v MS vyvinuli
vývojáři, kteří asi nesnášejí technologie WPF/XAML/Silverlight&amp;nbsp; vytvořené jejich
kolegy, &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt; a
proto si navrhli vlastní značkovací jazyk mixovaný s řízeným kódem a množstvím API
(P/Invoke) volání. IRIS Microsoft pravděpodobně používá v shellu a ve svých WP7 aplikacích.
Jestliže jste se ptali, jak to, že u MS aplikací třeba prvky Pivot a Panorama podporují
plynulejší skrolování než stejné prvky v Silverlightu, v použití IRIS frameworku leží
pravděpodobně odpověď. V Microsoftu buď občas neví levice, ce dělá pravíce, anebo
mobilní Silverlight není zas tak odladěn a vyšperkován, jak by se mohlo z prezentací
demo aplikací u MS evangelistů zdát, a teprve IRIS je tím zázrakem, který rozanimuje
výchozí uživatelské rozhraní a dovede recenzenty WP7 systému k stále opakované větě
o “ďábelské rychlosti WP7 aplikací”. Věta “o ďábelské rychlosti WP7 aplikací” platí
paradoxně do té doby, než začnete další aplikace skutečně instalovat, k čemuž se nadšení
recenzenti už asi nedokopou. Trochu sarkasticky dodejme, že v bajtech zhmotněná IRIS
snad není ve WP7 proto, aby poslala brzy bezduché WP7 do křemíkového pekla, stejně
jako kdysi mytologická Iris pomohla Dídó uvolnit duši z těla.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-winkingsmile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Nativní kód ale některé aplikace napsané v Silverlightu používají. &lt;/strong&gt;Jestliže
si prohlédnete XAP soubory (XAP soubor – distribuční soubor Silverlight aplikace)&amp;nbsp;
aplikací od výrobcu zařízení, zjistíte, že používají knihovnu GAC_Microsoft.Phone.InteropServices_v7_0_0_0_cneutral_1.dll.
Jak název assembly napovídá, měla by sloužit jako most k nativnímu kódu.
&lt;/p&gt;
&lt;p&gt;
Aplikace od výrobce tuto assembly používají pro dynamické volání metod COM objektů.
Zkusil jsem si napsat jednoduchou COM assembly ve VS 2008 pro Windows CE, protože
VS 2010 z rozhodnutí nějaké moudré hlavy ve vývojářské centrále Microsoftu podporu
pro vývoj CE aplikací již neobsahuje. COM knihovnu jsem nazval SL_COM2.dll.
&lt;/p&gt;
&lt;p&gt;
Poté jsem založil projekt v Silverlightu, přidal do něj soubor nazvaný WPInteropManifest.xml,
který obsahují i aplikace od výrobců. Soubor WPInteropManifest.xml má jednoduchý obsah.
&lt;/p&gt;
&lt;script src="http://gist.github.com/827481.js"&gt;&lt;/script&gt;
&lt;p&gt;
Do projektu jsem přidal knihovnu GAC_Microsoft.Phone.InteropServices_v7_0_0_0_cneutral_1.dll.
i svou COM knihovnu SL_COM2.dll a u obou knihoven jsem nastavil build akci na content,
aby obě knihovny byly přidány do výsledného XAP souboru. Žádné COM Interop knihovny
nevygenerujete, COM typy musíte naimportovat z COM&amp;nbsp; knihovny “ručně”.
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/827501.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Pomocí reflexe zaregistrujeme COM knihovnu na cílovém zařízení s využitím metod v
assembly GAC_Microsoft.Phone.InteropServices_v7_0_0_0_cneutral_1.dll.
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/827506.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Tento kód projde, ale na posledním řádku dostanete výjimku, která znamená, že vaše
COM knihovna je nekompatibilní s aktuální verzí operačního systému. Musíte si na internetu
“najít” a nainstalovat správný Platform builder, &lt;a href="http://blog.walshie.me/2010/11/15/windows-phone-7-full-file-system-access-anyone/#comment-244"&gt;což
udělal asi Ch. Welsh, nebo si pohrát s PE hlavičkami knihoven, což jsem udělal já&lt;/a&gt;.
COM knihovna by mohla být po odstranění všech překážek i branou ke všem API funkcím,
které si vystavíte v COM objektech. Nepředpokládejte ale, že vaše aplikace bude při
využívání COM knihovny přijata do marketplace.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font style="background-color: #00ff00"&gt;Když jsou problémy s umístěním aplikací do
marketplace, je naděje, že brzy bude pro WP7 existovat “jailbreak” a my budeme mít
obchod s neoficiálními aplikacemi? Dají se WP7 “hacknout”?&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Všechno jde, jen to stojí čas a peníze. A musíte mít přitom víru, že WP7 z trhu rychle
nezmizí.
&lt;/p&gt;
&lt;p&gt;
Hlavní problém je podle mě v tom, že Silverlight aplikace běží ve &lt;a href="http://msdn.microsoft.com/en-us/library/dd470128(v=vs.95).aspx"&gt;striktním
bezpečnostním modelu&lt;/a&gt;, který není snadné překonat. Takže možnosti, které mě napadají:
&lt;/p&gt;
&lt;p&gt;
Metoda pokus-omyl – začneme hledat slabiny v zabezpečení celé CE platformy a doufat,
že Microsoft někde udělal další školáckou chybu podobnou té, kterou využil Chevron,
jen teď někde v mnohem nižších vrstvách systému. Třeba kdyby Microsoft ponechal i
byť jen trochu pootevřen přístup k &lt;a href="http://msdn.microsoft.com/en-us/library/aa920177.aspx"&gt;RAPI&lt;/a&gt;,
to by byla paráda. Sice se dá “získat” a použít knihovna SmartDevice.Connectivity,
která RAPI interně využívá, ale neodemčený telefon nespolupracuje.
&lt;/p&gt;
&lt;p&gt;
Ukázka volání:
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/827526.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Daleko nadějnější mi přijde pokračovat tak, že se do CE registrů přidá vlastní driver,
který po startu zařízení shodí výchozí WP7 shell a dovolí vám nainstalovat a spouštět&amp;nbsp;
nativní aplikace i aplikace psané v Compact .Net Frameworku. V dalším kroku by to
chtělo nového hostitele Silverlight aplikací, který bude vstřícnější k neoficiálním
aplikacím. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt; Na
některých HTC zařízeních se průnik do registru již podařil… Takže nezbývá než zopakovat:
Všechno jde, jen to stojí čas a peníze.
&lt;/p&gt;
&lt;p&gt;
Snad jste v tomhle článků nalezli alespoň něco zajímavějšího než v konfekčních článcích
o WP7.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/FAQ-k-WP7_A14B/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=be4f9165-3d77-40c8-aea2-e7f8087f9b70" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,be4f9165-3d77-40c8-aea2-e7f8087f9b70.aspx</comments>
      <category>Compact .Net Framework</category>
      <category>Mobilitky</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=1ab0ecc7-7a79-4e17-b2f8-358bd7713695</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,1ab0ecc7-7a79-4e17-b2f8-358bd7713695.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,1ab0ecc7-7a79-4e17-b2f8-358bd7713695.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=1ab0ecc7-7a79-4e17-b2f8-358bd7713695</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
V <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">předchozích
článcích</a> jsme si vytvořili miniframework pro <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">view
modely</a>   a ukázali si hostitele <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">našich
view modelů</a>. Přišel čas naše znalosti, idiomy a návrhové vzory zakódované ve formě
aplikační infrastruktury v našem miniframeworku využít při tvorbě konkrétní aplikace.
Pro účely tohoto článku i následujících článků jsem se rozhodl, že vytvoříme aplikaci,
která nám dovolí spravovat vlastní blog na doméně <a href="https://posterous.com/">Posterous</a> s
využitím <a href="http://posterousapi.codeplex.com/releases/view/55736#DownloadId=167194">Posterous
API</a>.
</p>
        <p>
Hlavní případy užití, které budeme v aplikaci podporovat.
</p>
        <ol>
          <li>
Přihlášení uživatele ke svému účtu  - téma dnešního článku.<br /><br /></li>
          <li>
Zobrazení seznamu blogů, které patří přihlášenému uživateli.<br /><br /></li>
          <li>
Zobrazení seznamu příspěvků na vybraném blogu.<br /><br /></li>
          <li>
Zobrazení detailu příspěvku na blogu.<br /><br /></li>
          <li>
Úprava stávajícího příspěvku na blogu.<br /><br /></li>
          <li>
Zadání nového příspěvku na blog.<br /></li>
        </ol>
        <p>
Jako vždy nás tato prozatím letmo načrtnutá témata dovedou k dalším podivným zákoutím
vývoje WP7 aplikací  a my se z nich s úsměvem záludnostmi WP7 <strike>poučeného
idiota  </strike>zoceleného harcovníka pokusíme dostat.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png" />.
</p>
        <p>
Skutečně vás nechci urážet popisem klikání ve Visual Studiu ani popisem základů XAMLu,
“data bindingu”, “behaviors”, takže jen napíšu, že byste před vytvářením aplikace
měli:
</p>
        <ol>
          <li>
Stáhnout si a nainstalovat <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce&amp;displaylang=en">Windows
Phone Developer Tools.</a><br /><br /></li>
          <li>
Ve Visual Studiu založte nový projekt Windows Phone Application – nejlepší bude, když
ho pojmenujete jako já <em>RStein.PosterousReader.WP</em>, abyste nebyli zmateni názvy
jmenných prostorů dále v článku.<br /><br /><a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_1.png" width="244" height="170" /></a><br />
  
</li>
          <li>
Vývojářský život je na tomto projektu jednodušší o to, že k práci s Posterous API
použijeme můj <a href="http://posterousapi.codeplex.com/releases/view/55736#DownloadId=167194">C#
Posterous API Wrapper pro WP7</a>.  Po stažení přidejte referenci na knihovnu <em>RStein.Posterous.API.SLM </em>do
svého projektu.<br />
A i když to dnes ještě není tak nutné, <a href="https://posterous.com/">zřiďte si
na Posterous vlastní účet</a>, abyste mohli aplikaci později testovat na reálných
datech. C# Posterous API pro nás v triádě Model-View-ViewModel bude představovat model,
což má pro nás výhodu, že se můžeme stále soustředit na view a view modely, o které
šlo i v předchozích článcích, a model můžeme považovat za černou skříňku.<br /><br /></li>
          <li>
V novém projektu vytvořte hlavně dvě nové složky View a ViewModels. Na obrázku jsou
červeně podtrženy další složky, které si již dnes doporučuju přidat do projektu 
- Behaviors, Extensions, HostServices, Icons, SpecialTypes, UI, UIServices a hlavně
ViewModels a Views.<br /><br /><br /><a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_7.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_2.png" width="94" height="244" /></a><br /><br /></li>
          <li>
Předpokládám, že jste schopni do svého projektu vložit kód tříd, které jsem popisoval
v předchozích článcích. Seznam předchozích článků s výpisy kódu naleznete na konci
tohoto článku.</li>
        </ol>
        <p>
Dnes vytvoříme přihlašovací obrazovku do naší aplikace. Pro lepší představu je zde
obrazovka, kterou byste měli mít hotovou na konci dnešního článku.
</p>
        <p>
          <img src="http://blog.renestein.net/content/binary/Windows-Live-Writer/C-Posterous-API-.3--s-podporou-i-pro-WP7_D37E/image_2.png" width="379" height="633" />
        </p>
        <p>
  
</p>
        <p>
Nejprve určíme, které funkce musí obrazovka a její podkladový kód zvládat: 
</p>
        <ol>
          <li>
Přihlašovací obrazovka se zobrazí ihned po startu aplikace.<br /><br /></li>
          <li>
Uživateli dovolíme zadat přihlašovací jméno a heslo.<br /><br /></li>
          <li>
Jestliže není uživatelské jméno vyplněno (prázdný řetězec) a/nebo není vyplněno heslo,
tlačítko Přihlásit se je neaktivní.<br /><br /></li>
          <li>
Jestliže dojde k <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">“tombstoningu</a>”
stránky, bude jméno i heslo po návratu z “tombstonovaného” stavu zachováno – ověříme
si tak poprvé in vivo, že <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">naše
třída ViewModelBase podporuje “tombstoning” přesně dle našich požadavků</a>.<br /><br /></li>
          <li>
Po návratu na přihlašovací obrazovku z jiné části aplikace bude zachován jen obsah
textového pole “uživatelské jméno”, textové pole “heslo” bude prázdné.<br /><br /></li>
          <li>
Po kliknutí na tlačítko Přihlásit nebudeme zadané jméno a heslo ihned ověřovat, ale
uložíme oba údaje  pro použití na dalších stránkách aplikace. Poté přesměrujeme
uživatele na další stránku se seznamem blogů, kde bude jméno a heslo využito k získání
seznamu blogů uživatele. Důvodem je to, že v Posterous API se jméno a heslo zasílá
při každém webovém požadavku, žádné jednorázové přihlášení neexistuje a nemá smysl
generovat nějaký “dummy” požadavek jen pro ověření hesla. Jestliže se na stránce se
seznamem blogů, na kterou z přihlašovací obrazovky přesměrováváme, data kvůli neplatným
přihlašovacím údajům získat nepodaří, aplikace nás vrátí na přihlašovací obrazovku.
Vytvoření stránky se seznamem blogů bude téma dalšího článku.<br /></li>
        </ol>
        <p>
A začínáme: 
</p>
        <p>
Do složky Views vložte nové View pro přihlášení uživatele. V dialogu Add new item
vyberte Windows Phone Portrait Page a pojmenujte ji MainLoginView.xaml.
</p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_9.png">
            <img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_3.png" width="244" height="170" />
          </a>
        </p>
        <p>
Jedná se o úvodní  stránku aplikace, a proto v deskriptoru WP7 aplikace nazvaném
WAMppManifest.xml, který naleznete v projektové složce Properties, změníme startovací
stránku na View/mainLoginView.xaml. <script src="https://gist.github.com/793066.js"></script></p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_13.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_5.png" width="244" height="154" />
          </a>
        </p>
        <p>
I když to není u přihlašovacího dialogu nutné, v dnešním článku si ukážeme, jak můžeme
jednoduše složit jedno view z dalších nezávislých view a také to, že view nemusí být
jen stránka (Page), ale i “User Control”. Naše MainLoginView bude zobrazovat titulek
aplikace (Posterous klient), titulek stránky (Přihlášení) , ale textová pole “heslo”,
“uživatelské jméno” a tlačítko “Přihlásit" se” bude obsahovat “user control” LoginView,
který můžeme použít jako součást i zcela jiného view (stránky) v aplikaci.  Do
složky Views přidejte Windows Phone User Control a nazvěte jej LoginView.xaml. 
</p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_15.png">
            <img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_6.png" width="244" height="170" />
          </a>
        </p>
        <p>
Zkompilujte (Build) “solution”. 
</p>
        <p>
Do view MainLoginView vložte tento kód: 
</p>
        <p>
          <script src="http://gist.github.com/793080.js">
          </script>
        </p>
        <p>
Jak jsem zmiňoval v <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">jednom
z předešlých článků</a>, všechny stránky v aplikaci by měly být potomkem naší třídy <a href="https://gist.github.com/763320">PageBase</a>,
která je hostitelem pro view modely. Proto je naše stránka uzavřena v elementu <em>&lt;controlex:PageBase&gt;</em>. 
XML jmenný prostor controleex je u mě namapován na xmlns:controlex="clr-namespace:RStein.PosterousReader.WP.UI".
V projektovém adresáři UI musíte mít tedy třídu PageBase.
</p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_19.png">
            <img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_8.png" width="244" height="154" />
          </a>
        </p>
        <p>
Také v “code behind souboru” musíte třídu MainLoginView učinit potomkem PageBase.
</p>
        <script src="https://gist.github.com/793085.js">
        </script>
        <p>
Hlavní xaml pro přihlášení uživatele obsahuje “User Control” LoginView, na který se
v MainLoginView odkazujeme. <em>(&lt;views:LoginView Grid.Row="1"&gt;&lt;/views:LoginView&gt;</em>). 
XML jmenný prostor <em>views</em> je mapován na jmenný prostor <em>RStein.PosterousReader.WP.Views </em>v
C# (<em>xmlns:views="clr-namespace:RStein.PosterousReader.WP.Views</em>) – v našem
případě tedy na projektový adresář Views.
</p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_17.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_7.png" width="244" height="154" />
          </a>
        </p>
        <p>
Do view s názvem LoginView vložte následující XAML:
</p>
        <script src="https://gist.github.com/793102.js">
        </script>
        <p>
Jak bylo vidět na snímku obrazovky na počátku článku, LoginView obsahuje hlavně textové
pole pro zadání jména uživatele (txtName) a prvek pro zadání hesla uživatele (txtPassword)
a tlačítko “Přihlásit se”. U prvků pro zadání uživatelského jména a hesla vás mohou
zarazit jen tagy &lt;i:Interaction.Behaviors&gt; a atributy <em>jako behaviors:TextboxPasswordAttachedProperties.TextBoxChangedAction</em>,
jejichž význam vysvětlím za chvíli. Také vás hned  upozorním, že tlačítko “Přihlásit
se” je speciální tlačítko ((<em>&lt;controlex:ButtonEx</em>) dovolující reagovat na
stisknutí tlačítka uživatelem tak, že spustí metodu Execute objektu ICommand, což
standardní WP7 tlačítko nezvládá. Znovu  připomínám, že Silverlight ve WP7 je
bohužel založen na poměrně staré verzi 3 desktopového Silverlightu. Kód třídy ButtonEx
uvidíte také za chvíli.
</p>
        <p>
Máme view, ve view používáme “data binding”, ale nemáme ještě view modely, které fungují
pro view jako zdroj dat. 
</p>
        <p>
          <strong>V každém view modelu naší aplikace </strong>budeme používat objekt <em>IPosterousApplication</em> ke
komunikaci s Posterous, budeme chtít z view modelů navigovat na další view v aplikaci
a také bychom měli být schopni v každém view modelu získat  uživatelské jméno
a heslo zadané na na námi vytvářené přihlašovací obrazovce. To znamená, že společné
vlastnosti a služby view modelů pro naši aplikaci můžeme soustředit v bázové třídě
PosterousViewModelBase. Do projektové složky Views vložte novou třídu PosterousViewModelBase
a do ní zkopírujte následující kód. 
</p>
        <p>
PosterousViewModelBase je potomkem <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">naší
staré známé třídy ViewModelBase</a></p>
        <p>
          <script src="http://gist.github.com/793123.js">
          </script>
        </p>
        <p>
V konstruktoru třída PosterousViewModelBase přijímá odkaz na objekt <em>IPosterousApplication</em>,
který je základním rozcestnikem pro přístup k Posterous API, navigační službu <em>INavigationService</em>,
která view modelu dovolí navigovat na další view v aplikaci  (např. ze seznamu
článků na detail vybraného článku), a titulek zobrazené stránky.  <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">Titulek
převezme a nabízí poté ve vlastnosti PageTitle bázová třída ViewModelBase.</a></p>
        <p>
Navigační služba je představována rozhraním <em>INavigationService.</em></p>
        <p>
          <script src="http://gist.github.com/793126.js">
          </script>
        </p>
        <p>
Základní implementace rozhraní <em>INavigationService</em> pro WP7 je dostupná ve
třídě <em>DefaultWPNavigationService</em> a pouze obaluje navigační služby dostupné
v samotných WP7 aplikacích. 
</p>
        <script src="http://gist.github.com/793133.js">
        </script>
        <p>
Rozhraní <em>INavigationService</em> i třídu <em>DefaultWPNavigationService</em> vložte
do projektové složky HostServices.Více si o navigaci mezi různými view povíme v dalších
článcích.
</p>
        <p>
Vraťmě se k PosterousViewModelBase. V PosterousViewModelBase máme vždy uloženo ve
statických vlastnostech LastUsedUserName a LastUsedPassword poslední zadané přihlašovací
údaje, které může každý view model využít při získání nebo úpravě dat z Posterous. 
</p>
        <p>
          <em>Poznámka: Kdyby někoho z vás pohoršovali statické vlastnosti, klidně si jako domácí
úkol napište “CredentialsManager”, který bude injektován stejně jako již zmíněné dvě
další služby do view modelů. Prozatím nechci komplikovat kód víc, než je nutné.</em>
        </p>
        <p>
My máme dvě view, MainLoginView a LoginView, a proto vytvoříme i dva view modely.
Opět zdůrazňuju, že tato volba je na vás <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">a
díky “dědění view modelů”</a> bychom mohli ponechat třeba dvě view a vytvořit pro
ně jen jeden společný view model. 
</p>
        <p>
Do projektové složky ViewModels přidejte třídu nazvanou MainLoginViewModel – view
model pro MainLoginView. <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">Název
view modelu nyní musí odpovídat konvenci “NázevView +ViewModel”. Zdůrazňuju i zde,
že jde jen o konvenci a že si můžete jednoduše napsat jiný IViewModelResolver, který
dohledá dle vašich zcela jiných projektových konvencí k view vhodný view model.</a></p>
        <p>
MainLoginViewModel je sympaticky jednoduchý objekt. Má jen delegující konstruktor,
ve kterém předá své bázové třídě PosterousViewModelBase vyžadované povinné argumenty
posterousApplication, navigationService a titulek stránky. 
</p>
        <p>
          <script src="http://gist.github.com/793149.js">
          </script>
        </p>
        <p>
Texty v aplikaci nejsou prozatím lokalizovány a titulky stránek jsou uloženy ve třídě
GlobalConstants. Do “rootu” projektu přidejte třídu GlobalConstants.cs 
</p>
        <p>
          <script src="http://gist.github.com/793153.js">
          </script>
        </p>
        <p>
Název aplikace (APP_MAIN_TITLE) , podobně jako titulek stránky, <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">vydává
ve vlastnosti AppTitle  opět ViewModelBase</a></p>
        <p>
Jen o trochu složitější bude view model pro LoginView. Do projektové složky ViewModels
přidejte třídu LoginViewModel. 
</p>
        <p>
          <script src="http://gist.github.com/793171.js">
          </script>
        </p>
        <p>
V LoginViewModelu máme opět delegující konstruktor, jedinou změnou oproti MainLoginViewModelu
je to, že jako titulek stránky předáváme prázdný řetězec, protože předpokládáme, že
titulek na stránku dodá “nadřízené” view.
</p>
        <p>
Vlastnosti a jejich význam
</p>
        <table border="1" cellspacing="0" cellpadding="2" width="656">
          <tbody>
            <tr>
              <td valign="top" width="166">
                <strong>Název vlastnosti</strong>
              </td>
              <td valign="top" width="488">
                <strong>Popis</strong>
              </td>
            </tr>
            <tr>
              <td valign="top" width="170">
TextChangedAction</td>
              <td valign="top" width="484">
Akce, která má být vyvolána, když se ve view změní text přihlašovacího jména nebo
hesla. Tato akce je v konstruktoru inicializována tak, že si vynutíme opětovné vyhodnocení
toho, zda může být proveden LoginCommand. V článku popíšu, proč je to (prozatím?)
řešeno takto.</td>
            </tr>
            <tr>
              <td valign="top" width="170">
LoginCommand</td>
              <td valign="top" width="484">
Objekt podporující rozhraní ICommand,  který v metodě Execute zavolá metodu handleLogin.
Metoda handleLogin uloží zadané jméno a heslo do statických vlastností LastUsedPassword
a a LastUsedUserName a přesměruje uživatele na stránku se seznamem blogů. Instanční
vlastnost UserPassword je při každém pokusu o navigaci na stránku se seznamem blogů
“vyčištěna” tím, že je do ní uložen prázdný řetězec, a při návratu na přihlašovací
obrazovku tedy není automaticky předvyplněno heslo, což byl jeden z našich požadavků
na přihlašovací dialog.<br />
LoginCommand může být proveden jen tehdy, když bylo ve view zadáno a do view modelu
přes oboustranný (two way) binding zpropagováno uživatelské jméno a heslo. Pokud vlastnosti
UserName a UserPassword mají hodnotu null nebo obsahují prázdný řetězec, LoginCommand
nemůže být proveden.</td>
            </tr>
            <tr>
              <td valign="top" width="170">
UserName</td>
              <td valign="top" width="484">
Zadané přihlašovací jméno na službu Posterous. V <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">metodě
DoInternalInit, která je volána na začátku životního cyklu view modelu</a> předvyplníme
uživatelské jméno posledním zadaným uživatelským jménem, které jsme dříve uložili
do statické vlastnosti LastUsedUserName.</td>
            </tr>
            <tr>
              <td valign="top" width="170">
UserPassword</td>
              <td valign="top" width="484">
Heslo na službu Posterous.</td>
            </tr>
          </tbody>
        </table>
        <p>
Co potřebujeme, abychom mohli náš LoginViewModel zkompilovat? 
</p>
        <p>
Do třídy GlobalConstants přidejte URL dalšího view se seznamem blogů a článků. 
</p>
        <p>
          <script src="http://gist.github.com/793195.js">
          </script>
        </p>
        <p>
Stránku PostsListView.xaml vytvoříme v dalším článku, nyní ji celou vytvářet nemusíte.
Postačí do složky Views dát novou stránku (Page) s názvem PostsListView.xaml. 
</p>
        <p>
Jak jsem již psal, ve WP7 nemáme bohužel podporu pro objekty ICommand. Třída DelegateCommand,
jejíž instancí je LoginCommand, <strong>je minimalistickou implementací </strong>rozhraní
ICommand. 
</p>
        <p>
Pokud podobnou třídu nemáte, vložte si  do projektu třídu DelegateCommand. U
mě je v jmenném prostoru <strong>RStein.PosterousReader.Common.</strong></p>
        <p>
          <strong>
            <script src="http://gist.github.com/793206.js">
            </script>
          </strong>
        </p>
        <p>
Třídě DelegateCommand můžete předat dva delegáty. Delegát executeAction (“co má být
vykonáno”) je spuštěn v metodě Execute z rozhraní ICommand. Delegát canExecuteAction
představuje implementaci metody CanExecute (“může být  nyní command vykonán?”).
Minimalistická implementace je to proto, že nijak nepoužívám událost CanExecuteChanged,
a namísto toho jsem si pro “binding” vystavil speciální vlastnost CanExecuteCommand,
která v get akcesoru deleguje na metodu CanExecute.
</p>
        <p>
Vlastnost TextChangedAction v LoginViewModelu je delegát typu Action, který nám pomáhá
vyřešit jeden z požadavků na přihlášení. 
</p>
        <p>
          <em>“Jestliže není uživatelské jméno vyplněno (prázdný řetězec) a/nebo není vyplněno
heslo, tlačítko Přihlásit se je neaktivní.”</em>
        </p>
        <p>
To znamená, že potřebujeme po každém přidání nebo smazání znaku v textboxu pro zadání
jména uživatele i v textboxu pro zadání hesla zjišťovat, jestli můžeme ve view zpřístupnit
tlačítko pro přihlášení. Když je alespoň jeden textbox prázdný, tlačítko pro přihlášení
není dostupné, když je vyplněno alespoň jedním znakem jméno i heslo, tlačítko pro
přihlášení je dostupné.
</p>
        <p>
Jak je tento požadavek ve view a view modelu splněn?
</p>
        <p>
Ve view <em>LoginView</em> je vlastnost <em>IsEnabled</em> tlačítka “Přihlásit se“
z třídy <em>ButtonEx</em> “nabindována” na vlastnost <em>CanExecuteCommand</em> objektu <em>LoginCommand</em> ve
view modelu.
</p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_21.png">
            <img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_9.png" width="244" height="154" />
          </a>
        </p>
        <p>
Do projektové složky UI si přidejte třídu ButtonEx, která doplňuje standardní WP7
tlačítko o jednoduchou podporu objektů ICommand.
</p>
        <p>
          <strong>
            <script src="http://gist.github.com/793221.js">
            </script>
          </strong>
        </p>
        <p>
Vlastnost CanExecuteCommand musí vracet true, pokud je v každém textboxu alespoň jeden
znak, jinak false. Jak ale ve view modelu zjistíme, že uživatel zadal nebo smazal
v některém textovém poli další znak? Do view modelu se při oboustranném bindingu zpropaguje
hodnota z textového pole až po opuštění textového pole uživatelem, ale my přitom musíme
reagovat ve view modelu na zadání každého znaku.
</p>
        <p>
Takové chování textových polí ve WP7 skutečně nemáme a musíme si ho dopsat, a to nejlépe
za pomoci ”attached” vlastností a objektů <em>Behavior&lt;T&gt;</em>. Nejprve se podívejme,
jak vypadají objekty TextBox a PasswordBox v XAMLu, když jsou rozšířeny o “attached”
vlastnost <em>TextboxPasswordAttachedProperties.TextBoxChangedAction</em>, která je
“nabindována” na nám již známou vlastnost TextChangedAction typu Action ve view modelu. 
“Attached” vlastnost <em>TextBoxChangedAction</em> tedy říká: “Hej, kdykoli se změní
u prvku zadaný text, musí NĚKDO ochotný zavolat delegáta TextChangedAction, abychom
ve view modelu nebyli odříznuti od novinek ve světě view.”
</p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_23.png">
            <img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_10.png" width="244" height="154" />
          </a>
        </p>
        <p>
A ten někdo bude náš objekt Behavior , který zase světu sděluje: “Mám dobré vychování,
a když mi dovolíte vstoupit do bran tagu PasswordBox nebo TextBox, delegáta TextChangedAction
zavolám,  i když to sám WP7 TextBox a PasswordBox nezvládne.”
</p>
        <p>
          <script src="http://gist.github.com/793240.js">
          </script>
        </p>
        <p>
Další nepříjemností ve WP7 je, že i když objekt Behavior má mít pro TextBox a PasswordBox 
stejné chování, musíme napsat dva objekty Behavior pro každý prvek, protože TextBox
ani PasswordBox spolu kupodivu nemají moc společného. My se alespoň pokusíme kód v
obou objektech Behavior neduplikovat.
</p>
        <p>
 
</p>
        <p>
Do projektové složky Behaviors přidejte třídu TextboxPasswordAttachedProperties a
v ní vytvořte attached vlastnost TextBoxChangedAction.
</p>
        <p>
          <script src="http://gist.github.com/793248.js">
          </script>
        </p>
        <p>
Do složky Behaviors přidejte abstraktní třídu TextChangedBehaviorBase, která bude
fungovat jako základ pro dva podobné objekty Behavior určené pro TextBox (TextBoxTextChangedUpdateSourceBehavior)
a PasswordBox (PasswordTextChangedBehavior). <strong>Do projektu musíte přidat referenci
na knihovnu System.Windows.Interactivity, </strong>kterou naleznete většinou ve složce <em>c:\Program
Files\Microsoft SDKs\Expression\Blend\Windows Phone\v7.0\Libraries\System.Windows.Interactivity.dll. </em><strong>Bez
této knihovny není dostupná bázová třída Behavior&lt;T&gt;.</strong></p>
        <p>
          <script src="http://gist.github.com/793259.js">
          </script>
        </p>
        <p>
Metoda RunTextChangedAction se pro objekt Textbox a PasswordBox asociovaný s tímto
objektem Behavior  pokusí dohledat a spustit delegáta v “attached” vlastnost
TextBoxChangedAction. Metoda UpdateSource požádá odvozené třídy o vydání "objektu
BindingExpression” voláním metody GetBindingExpression. Vrácený objekt “BindingExpression“
by měl  zapouzdřovat propojení vlastnosti view modelu (např UserName) s textem
v textovém poli. Po kontrole, že se jedná o oboustranný (two way) binding, metoda
UpdateSource zavolá na objektu BindingExpression UpdateSource, což způsobí přenesení
hodnoty zadané uživatelem v textovém poli ve view do zdrojové vlastnosti (např. UserName)
ve view modelu.
</p>
        <p>
Potomek TextBoxTextChangedUpdateSourceBehavior v metodě GetBindingExpression vrátí
BindingExpression pro svou vlastnost Text. V přepsané metodě OnAttached, která je
volána vždy, když je objekt Behavior asociován s textboxem, si přihlásíme odběr události
TextChanged TextBoxu a při každé změně textu voláme zděděné a výše popsané metody
UpdateSource a RunTextChangedAction. V metodě OnDetaching si nezapomeneme odběr události
TextChanged odhlásit.
</p>
        <script src="http://gist.github.com/793285.js">
        </script>
        <p>
Pro PasswordBox máme dalšího potomka PasswordTextChangedBehavior, který se od třídy
TextBoxTextChangedUpdateSourceBehavior liší jen tím, že v metodě GetBindingExpression
vrací “BindingExpression” pro vlastnost Password a zadávaný text sleduje přes událost
PasswordChanged.
</p>
        <script src="https://gist.github.com/793557.js">
        </script>
        <p>
 
</p>
        <p>
V LoginView si nezapomeňte zkontrolovat, že máte namapovány správně xml prefixy <em>behaviors</em> a <em>i</em><strong></strong>na
správné jmenné prostory v C#, abyste mohli využívat novou attached vlastnost TextBoxChangedAction
a objekty TextBoxTextChangedUpdateSourceBehavior  a PasswordTextChangedBehavior.
</p>
        <p>
          <em>prostoryxmlns:behaviors="clr-namespace:RStein.PosterousReader.WP.Behaviors"<br />
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"</em>
        </p>
        <p>
          <a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_25.png">
            <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_11.png" width="244" height="154" />
          </a>
        </p>
        <p>
Dodejme, že náš delegát TextChangedAction ve view modelu simuluje změnu objektu LoginCommand,
který je přidružen k tlačítku Přihlásit se a tlačítko Přihlásit tedy po každém zadání
znaku zjistí, jestli má být dostupné.  Zopakujme, že vlastnost IsEnabled tlačítka
je “nabindována” na vlastnost LoginCommand.CanExecuteCommand. 
</p>
        <p>
Aplikaci můžete spustit.
</p>
        <p>
          <em>Poznámka: Ještě si ale nezapomeňte do složky UIServices dát kód rozhraní IViewModelResolver
a třídy ViewModelResolver, které jsem popisoval v článku </em>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">
            <em>propojení
view modelu s view (stránkou)</em>
          </a>
          <em>, protože bez třídy ViewModelResolver by
aplikace nebyla schopna pro naše MainLoginView a LoginView dohledat právě vytvořené
view modely. A v aplikaci musíte mít samozřejmě všechny další třídy z předchozích
článků, které jsou odpovědné za “tombstoning” apod.</em>
        </p>
        <p>
U aplikace si můžete zkontrolovat, že:
</p>
        <ul>
          <li>
Přihlašovací dialog plní všechny požadavky, které jsme vypsal  na začátku článku.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png" /><br /><br /></li>
          <li>
Nemusíme se nijak starat o “tombstoning” aplikace. Zmáčkněte tlačítko Win, poté se
tlačítkem Back vraťte do aplikace a všechny hodnoty v textových polích zůstanou zachovány.<br /><br /></li>
          <li>
Tlačítko pro přihlášení je dostupné jen tehdy, když textová pole pro zadání jména
a hesla jsou vyplněna. Pokud alespoň jedno pole vyplněno není, tlačítko je neaktivní.<br /><br /></li>
          <li>
I naše minimalistická podpora rozhraní ICommand vede k tomu, že ve View nemáme žádný 
“code behind”. Logika stojící za view je jen ve view modelech a XAML tahá data z view
modelů přes “data binding”. Pokud přesně tohle to považujete za důležité, budete určitě
nadšeni. Jak uvidíte v dalších článcích, já jsem vůči strategii “vše do XAMLu” hodně
skeptický, ale XAML puristé <strike>si </strike>mohou jít po dnešku jistě <strike>ožrat
držku </strike>slavit<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png" />.<br /><br /></li>
          <li>
I když šlo jen o přihlašovací formulář, vytvořili jsme si další skládací kostky (attached
vlastnosti, Behavior, PosterousViewModelBase), které se nám budou hodit při psani
dalších view a view modelů (nejen)  v této aplikaci.<br /></li>
        </ul>
        <p>
Zauvažujte nad tím, jestli by se nám také nehodila nějaká podpora ve view modelech
pro ukládání nejen tranzientního stavu, ale i pro ukládání “trvalejšího” stavu, který
bude dostupný i v další nezávislé instanci aplikace. Možná by stálo za to, aby si
aplikace pamatovala poslední zadané přihlašovací jméno nejen při “tombstoningu”, ale
aby přihlašovací jméno bylo nabídnuto i při novém spuštění aplikace. A z hlediska
vývojáře  bezbolestná podpora pro ukládání perzistentního stavu (<a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">data
s “delší záruční lhůtou”</a>) bude námětem dalšího WP7 intermezza. Doufám, že se těšíte. <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png" /></p>
        <p>
          <strong>Předchozí články:<br /><br /></strong>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx">Tipy
pro Windows Phone 7 aplikace I</a>
        </p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">Tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”</a>
        </p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">Tipy
pro Windows Phone 7 aplikace III–propojení view modelu s view (stránkou)</a>
        </p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IV+Intermezzo+I+Zjednoduscaronenaacute+Registrace+Serializovatelnyacutech+T%c5%99iacuted+Nesouciacutech+Tranzientniacute+Stav+V+KnownTypesDictionary.aspx">Tipy
pro Windows Phone 7 aplikace IV - intermezzo I - zjednodušená registrace serializovatelných
tříd nesoucích tranzientní stav v KnownTypesDictionary</a>
        </p>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=1ab0ecc7-7a79-4e17-b2f8-358bd7713695" />
      </body>
      <title>Tipy pro Windows Phone 7 aplikace V &amp;ndash; vytv&amp;aacute;ř&amp;iacute;me prvni aplikaci (a stav&amp;iacute;me ji na vytvořen&amp;yacute;ch z&amp;aacute;kladech)</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,1ab0ecc7-7a79-4e17-b2f8-358bd7713695.aspx</guid>
      <link>http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+V+Ndash+Vytvaacute%c5%99iacuteme+Prvni+Aplikaci+A+Staviacuteme+Ji+Na+Vytvo%c5%99enyacutech+Zaacutekladech.aspx</link>
      <pubDate>Mon, 24 Jan 2011 16:48:26 GMT</pubDate>
      <description>&lt;p&gt;
V &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;předchozích
článcích&lt;/a&gt; jsme si vytvořili miniframework pro &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;view
modely&lt;/a&gt;&amp;nbsp;&amp;nbsp; a ukázali si hostitele &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;našich
view modelů&lt;/a&gt;. Přišel čas naše znalosti, idiomy a návrhové vzory zakódované ve formě
aplikační infrastruktury v našem miniframeworku využít při tvorbě konkrétní aplikace.
Pro účely tohoto článku i následujících článků jsem se rozhodl, že vytvoříme aplikaci,
která nám dovolí spravovat vlastní blog na doméně &lt;a href="https://posterous.com/"&gt;Posterous&lt;/a&gt; s
využitím &lt;a href="http://posterousapi.codeplex.com/releases/view/55736#DownloadId=167194"&gt;Posterous
API&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Hlavní případy užití, které budeme v aplikaci podporovat.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Přihlášení uživatele ke svému účtu&amp;nbsp; - téma dnešního článku.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Zobrazení seznamu blogů, které patří přihlášenému uživateli.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Zobrazení seznamu příspěvků na vybraném blogu.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Zobrazení detailu příspěvku na blogu.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Úprava stávajícího příspěvku na blogu.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Zadání nového příspěvku na blog.&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Jako vždy nás tato prozatím letmo načrtnutá témata dovedou k dalším podivným zákoutím
vývoje WP7 aplikací&amp;nbsp; a my se z nich s úsměvem záludnostmi WP7 &lt;strike&gt;poučeného
idiota&amp;nbsp; &lt;/strike&gt;zoceleného harcovníka pokusíme dostat.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png"&gt;.
&lt;/p&gt;
&lt;p&gt;
Skutečně vás nechci urážet popisem klikání ve Visual Studiu ani popisem základů XAMLu,
“data bindingu”, “behaviors”, takže jen napíšu, že byste před vytvářením aplikace
měli:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Stáhnout si a nainstalovat &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce&amp;amp;displaylang=en"&gt;Windows
Phone Developer Tools.&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Ve Visual Studiu založte nový projekt Windows Phone Application – nejlepší bude, když
ho pojmenujete jako já &lt;em&gt;RStein.PosterousReader.WP&lt;/em&gt;, abyste nebyli zmateni názvy
jmenných prostorů dále v článku.&lt;br&gt;
&lt;br&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_5.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_1.png" width="244" height="170"&gt;&lt;/a&gt;
&lt;br&gt;
&amp;nbsp; 
&lt;li&gt;
Vývojářský život je na tomto projektu jednodušší o to, že k práci s Posterous API
použijeme můj &lt;a href="http://posterousapi.codeplex.com/releases/view/55736#DownloadId=167194"&gt;C#
Posterous API Wrapper pro WP7&lt;/a&gt;.&amp;nbsp; Po stažení přidejte referenci na knihovnu &lt;em&gt;RStein.Posterous.API.SLM &lt;/em&gt;do
svého projektu.&lt;br&gt;
A i když to dnes ještě není tak nutné, &lt;a href="https://posterous.com/"&gt;zřiďte si
na Posterous vlastní účet&lt;/a&gt;, abyste mohli aplikaci později testovat na reálných
datech. C# Posterous API pro nás v triádě Model-View-ViewModel bude představovat model,
což má pro nás výhodu, že se můžeme stále soustředit na view a view modely, o které
šlo i v předchozích článcích, a model můžeme považovat za černou skříňku.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
V novém projektu vytvořte hlavně dvě nové složky View a ViewModels. Na obrázku jsou
červeně podtrženy další složky, které si již dnes doporučuju přidat do projektu&amp;nbsp;
- Behaviors, Extensions, HostServices, Icons, SpecialTypes, UI, UIServices a hlavně
ViewModels a Views.&lt;br&gt;
&lt;br&gt;
&lt;br&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_7.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_2.png" width="94" height="244"&gt;&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Předpokládám, že jste schopni do svého projektu vložit kód tříd, které jsem popisoval
v předchozích článcích. Seznam předchozích článků s výpisy kódu naleznete na konci
tohoto článku.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Dnes vytvoříme přihlašovací obrazovku do naší aplikace. Pro lepší představu je zde
obrazovka, kterou byste měli mít hotovou na konci dnešního článku.
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.renestein.net/content/binary/Windows-Live-Writer/C-Posterous-API-.3--s-podporou-i-pro-WP7_D37E/image_2.png" width="379" height="633"&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp; 
&lt;p&gt;
Nejprve určíme, které funkce musí obrazovka a její podkladový kód zvládat: 
&lt;ol&gt;
&lt;li&gt;
Přihlašovací obrazovka se zobrazí ihned po startu aplikace.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Uživateli dovolíme zadat přihlašovací jméno a heslo.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Jestliže není uživatelské jméno vyplněno (prázdný řetězec) a/nebo není vyplněno heslo,
tlačítko Přihlásit se je neaktivní.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Jestliže dojde k &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;“tombstoningu&lt;/a&gt;”
stránky, bude jméno i heslo po návratu z “tombstonovaného” stavu zachováno – ověříme
si tak poprvé in vivo, že &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;naše
třída ViewModelBase podporuje “tombstoning” přesně dle našich požadavků&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Po návratu na přihlašovací obrazovku z jiné části aplikace bude zachován jen obsah
textového pole “uživatelské jméno”, textové pole “heslo” bude prázdné.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Po kliknutí na tlačítko Přihlásit nebudeme zadané jméno a heslo ihned ověřovat, ale
uložíme oba údaje&amp;nbsp; pro použití na dalších stránkách aplikace. Poté přesměrujeme
uživatele na další stránku se seznamem blogů, kde bude jméno a heslo využito k získání
seznamu blogů uživatele. Důvodem je to, že v Posterous API se jméno a heslo zasílá
při každém webovém požadavku, žádné jednorázové přihlášení neexistuje a nemá smysl
generovat nějaký “dummy” požadavek jen pro ověření hesla. Jestliže se na stránce se
seznamem blogů, na kterou z přihlašovací obrazovky přesměrováváme, data kvůli neplatným
přihlašovacím údajům získat nepodaří, aplikace nás vrátí na přihlašovací obrazovku.
Vytvoření stránky se seznamem blogů bude téma dalšího článku.&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
A začínáme: 
&lt;p&gt;
Do složky Views vložte nové View pro přihlášení uživatele. V dialogu Add new item
vyberte Windows Phone Portrait Page a pojmenujte ji MainLoginView.xaml.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_9.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_3.png" width="244" height="170"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Jedná se o úvodní&amp;nbsp; stránku aplikace, a proto v deskriptoru WP7 aplikace nazvaném
WAMppManifest.xml, který naleznete v projektové složce Properties, změníme startovací
stránku na View/mainLoginView.xaml. &lt;script src="https://gist.github.com/793066.js"&gt; &lt;/script&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_13.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_5.png" width="244" height="154"&gt;&lt;/a&gt; 
&lt;p&gt;
I když to není u přihlašovacího dialogu nutné, v dnešním článku si ukážeme, jak můžeme
jednoduše složit jedno view z dalších nezávislých view a také to, že view nemusí být
jen stránka (Page), ale i “User Control”. Naše MainLoginView bude zobrazovat titulek
aplikace (Posterous klient), titulek stránky (Přihlášení) , ale textová pole “heslo”,
“uživatelské jméno” a tlačítko “Přihlásit" se” bude obsahovat “user control” LoginView,
který můžeme použít jako součást i zcela jiného view (stránky) v aplikaci.&amp;nbsp; Do
složky Views přidejte Windows Phone User Control a nazvěte jej LoginView.xaml. 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_15.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_6.png" width="244" height="170"&gt;&lt;/a&gt; 
&lt;p&gt;
Zkompilujte (Build) “solution”. 
&lt;p&gt;
Do view MainLoginView vložte tento kód: 
&lt;p&gt;
&lt;script src="http://gist.github.com/793080.js"&gt;&lt;/script&gt;
&lt;p&gt;
Jak jsem zmiňoval v &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;jednom
z předešlých článků&lt;/a&gt;, všechny stránky v aplikaci by měly být potomkem naší třídy &lt;a href="https://gist.github.com/763320"&gt;PageBase&lt;/a&gt;,
která je hostitelem pro view modely. Proto je naše stránka uzavřena v elementu &lt;em&gt;&amp;lt;controlex:PageBase&amp;gt;&lt;/em&gt;.&amp;nbsp;
XML jmenný prostor controleex je u mě namapován na xmlns:controlex="clr-namespace:RStein.PosterousReader.WP.UI".
V projektovém adresáři UI musíte mít tedy třídu PageBase.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_19.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_8.png" width="244" height="154"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Také v “code behind souboru” musíte třídu MainLoginView učinit potomkem PageBase.
&lt;/p&gt;
&lt;script src="https://gist.github.com/793085.js"&gt; &lt;/script&gt;
&lt;p&gt;
Hlavní xaml pro přihlášení uživatele obsahuje “User Control” LoginView, na který se
v MainLoginView odkazujeme. &lt;em&gt;(&amp;lt;views:LoginView Grid.Row="1"&amp;gt;&amp;lt;/views:LoginView&amp;gt;&lt;/em&gt;).&amp;nbsp;
XML jmenný prostor &lt;em&gt;views&lt;/em&gt; je mapován na jmenný prostor &lt;em&gt;RStein.PosterousReader.WP.Views &lt;/em&gt;v
C# (&lt;em&gt;xmlns:views="clr-namespace:RStein.PosterousReader.WP.Views&lt;/em&gt;) – v našem
případě tedy na projektový adresář Views.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_17.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_7.png" width="244" height="154"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Do view s názvem LoginView vložte následující XAML:
&lt;/p&gt;
&lt;script src="https://gist.github.com/793102.js"&gt; &lt;/script&gt;
&lt;p&gt;
Jak bylo vidět na snímku obrazovky na počátku článku, LoginView obsahuje hlavně textové
pole pro zadání jména uživatele (txtName) a prvek pro zadání hesla uživatele (txtPassword)
a tlačítko “Přihlásit se”. U prvků pro zadání uživatelského jména a hesla vás mohou
zarazit jen tagy &amp;lt;i:Interaction.Behaviors&amp;gt; a atributy &lt;em&gt;jako behaviors:TextboxPasswordAttachedProperties.TextBoxChangedAction&lt;/em&gt;,
jejichž význam vysvětlím za chvíli. Také vás hned&amp;nbsp; upozorním, že tlačítko “Přihlásit
se” je speciální tlačítko ((&lt;em&gt;&amp;lt;controlex:ButtonEx&lt;/em&gt;) dovolující reagovat na
stisknutí tlačítka uživatelem tak, že spustí metodu Execute objektu ICommand, což
standardní WP7 tlačítko nezvládá. Znovu&amp;nbsp; připomínám, že Silverlight ve WP7 je
bohužel založen na poměrně staré verzi 3 desktopového Silverlightu. Kód třídy ButtonEx
uvidíte také za chvíli.
&lt;/p&gt;
&lt;p&gt;
Máme view, ve view používáme “data binding”, ale nemáme ještě view modely, které fungují
pro view jako zdroj dat. 
&lt;p&gt;
&lt;strong&gt;V každém view modelu naší aplikace &lt;/strong&gt;budeme používat objekt &lt;em&gt;IPosterousApplication&lt;/em&gt; ke
komunikaci s Posterous, budeme chtít z view modelů navigovat na další view v aplikaci
a také bychom měli být schopni v každém view modelu získat&amp;nbsp; uživatelské jméno
a heslo zadané na na námi vytvářené přihlašovací obrazovce. To znamená, že společné
vlastnosti a služby view modelů pro naši aplikaci můžeme soustředit v bázové třídě
PosterousViewModelBase. Do projektové složky Views vložte novou třídu PosterousViewModelBase
a do ní zkopírujte následující kód. 
&lt;p&gt;
PosterousViewModelBase je potomkem &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;naší
staré známé třídy ViewModelBase&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/793123.js"&gt;&lt;/script&gt;
&lt;p&gt;
V konstruktoru třída PosterousViewModelBase přijímá odkaz na objekt &lt;em&gt;IPosterousApplication&lt;/em&gt;,
který je základním rozcestnikem pro přístup k Posterous API, navigační službu &lt;em&gt;INavigationService&lt;/em&gt;,
která view modelu dovolí navigovat na další view v aplikaci&amp;nbsp; (např. ze seznamu
článků na detail vybraného článku), a titulek zobrazené stránky.&amp;nbsp; &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;Titulek
převezme a nabízí poté ve vlastnosti PageTitle bázová třída ViewModelBase.&lt;/a&gt; 
&lt;p&gt;
Navigační služba je představována rozhraním &lt;em&gt;INavigationService.&lt;/em&gt; 
&lt;p&gt;
&lt;script src="http://gist.github.com/793126.js"&gt;&lt;/script&gt;
&lt;p&gt;
Základní implementace rozhraní &lt;em&gt;INavigationService&lt;/em&gt; pro WP7 je dostupná ve
třídě &lt;em&gt;DefaultWPNavigationService&lt;/em&gt; a pouze obaluje navigační služby dostupné
v samotných WP7 aplikacích. 
&lt;/p&gt;
&lt;script src="http://gist.github.com/793133.js"&gt;&lt;/script&gt;
&lt;p&gt;
Rozhraní &lt;em&gt;INavigationService&lt;/em&gt; i třídu &lt;em&gt;DefaultWPNavigationService&lt;/em&gt; vložte
do projektové složky HostServices.Více si o navigaci mezi různými view povíme v dalších
článcích.
&lt;/p&gt;
&lt;p&gt;
Vraťmě se k PosterousViewModelBase. V PosterousViewModelBase máme vždy uloženo ve
statických vlastnostech LastUsedUserName a LastUsedPassword poslední zadané přihlašovací
údaje, které může každý view model využít při získání nebo úpravě dat z Posterous. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Poznámka: Kdyby někoho z vás pohoršovali statické vlastnosti, klidně si jako domácí
úkol napište “CredentialsManager”, který bude injektován stejně jako již zmíněné dvě
další služby do view modelů. Prozatím nechci komplikovat kód víc, než je nutné.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
My máme dvě view, MainLoginView a LoginView, a proto vytvoříme i dva view modely.
Opět zdůrazňuju, že tato volba je na vás &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;a
díky “dědění view modelů”&lt;/a&gt; bychom mohli ponechat třeba dvě view a vytvořit pro
ně jen jeden společný view model. 
&lt;p&gt;
Do projektové složky ViewModels přidejte třídu nazvanou MainLoginViewModel – view
model pro MainLoginView. &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;Název
view modelu nyní musí odpovídat konvenci “NázevView +ViewModel”. Zdůrazňuju i zde,
že jde jen o konvenci a že si můžete jednoduše napsat jiný IViewModelResolver, který
dohledá dle vašich zcela jiných projektových konvencí k view vhodný view model.&lt;/a&gt; 
&lt;p&gt;
MainLoginViewModel je sympaticky jednoduchý objekt. Má jen delegující konstruktor,
ve kterém předá své bázové třídě PosterousViewModelBase vyžadované povinné argumenty
posterousApplication, navigationService a titulek stránky. 
&lt;p&gt;
&lt;script src="http://gist.github.com/793149.js"&gt;&lt;/script&gt;
&lt;p&gt;
Texty v aplikaci nejsou prozatím lokalizovány a titulky stránek jsou uloženy ve třídě
GlobalConstants. Do “rootu” projektu přidejte třídu GlobalConstants.cs 
&lt;p&gt;
&lt;script src="http://gist.github.com/793153.js"&gt;&lt;/script&gt;
&lt;p&gt;
Název aplikace (APP_MAIN_TITLE) , podobně jako titulek stránky, &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;vydává
ve vlastnosti AppTitle&amp;nbsp; opět ViewModelBase&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Jen o trochu složitější bude view model pro LoginView. Do projektové složky ViewModels
přidejte třídu LoginViewModel. 
&lt;p&gt;
&lt;script src="http://gist.github.com/793171.js"&gt;&lt;/script&gt;
&lt;p&gt;
V LoginViewModelu máme opět delegující konstruktor, jedinou změnou oproti MainLoginViewModelu
je to, že jako titulek stránky předáváme prázdný řetězec, protože předpokládáme, že
titulek na stránku dodá “nadřízené” view.
&lt;/p&gt;
&lt;p&gt;
Vlastnosti a jejich význam
&lt;/p&gt;
&lt;table border="1" cellspacing="0" cellpadding="2" width="656"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign="top" width="166"&gt;
&lt;strong&gt;Název vlastnosti&lt;/strong&gt;&lt;/td&gt;
&lt;td valign="top" width="488"&gt;
&lt;strong&gt;Popis&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="170"&gt;
TextChangedAction&lt;/td&gt;
&lt;td valign="top" width="484"&gt;
Akce, která má být vyvolána, když se ve view změní text přihlašovacího jména nebo
hesla. Tato akce je v konstruktoru inicializována tak, že si vynutíme opětovné vyhodnocení
toho, zda může být proveden LoginCommand. V článku popíšu, proč je to (prozatím?)
řešeno takto.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="170"&gt;
LoginCommand&lt;/td&gt;
&lt;td valign="top" width="484"&gt;
Objekt podporující rozhraní ICommand,&amp;nbsp; který v metodě Execute zavolá metodu handleLogin.
Metoda handleLogin uloží zadané jméno a heslo do statických vlastností LastUsedPassword
a a LastUsedUserName a přesměruje uživatele na stránku se seznamem blogů. Instanční
vlastnost UserPassword je při každém pokusu o navigaci na stránku se seznamem blogů
“vyčištěna” tím, že je do ní uložen prázdný řetězec, a při návratu na přihlašovací
obrazovku tedy není automaticky předvyplněno heslo, což byl jeden z našich požadavků
na přihlašovací dialog.&lt;br&gt;
LoginCommand může být proveden jen tehdy, když bylo ve view zadáno a do view modelu
přes oboustranný (two way) binding zpropagováno uživatelské jméno a heslo. Pokud vlastnosti
UserName a UserPassword mají hodnotu null nebo obsahují prázdný řetězec, LoginCommand
nemůže být proveden.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="170"&gt;
UserName&lt;/td&gt;
&lt;td valign="top" width="484"&gt;
Zadané přihlašovací jméno na službu Posterous. V &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;metodě
DoInternalInit, která je volána na začátku životního cyklu view modelu&lt;/a&gt; předvyplníme
uživatelské jméno posledním zadaným uživatelským jménem, které jsme dříve uložili
do statické vlastnosti LastUsedUserName.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td valign="top" width="170"&gt;
UserPassword&lt;/td&gt;
&lt;td valign="top" width="484"&gt;
Heslo na službu Posterous.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
Co potřebujeme, abychom mohli náš LoginViewModel zkompilovat? 
&lt;p&gt;
Do třídy GlobalConstants přidejte URL dalšího view se seznamem blogů a článků. 
&lt;p&gt;
&lt;script src="http://gist.github.com/793195.js"&gt;&lt;/script&gt;
&lt;p&gt;
Stránku PostsListView.xaml vytvoříme v dalším článku, nyní ji celou vytvářet nemusíte.
Postačí do složky Views dát novou stránku (Page) s názvem PostsListView.xaml. 
&lt;p&gt;
Jak jsem již psal, ve WP7 nemáme bohužel podporu pro objekty ICommand. Třída DelegateCommand,
jejíž instancí je LoginCommand, &lt;strong&gt;je minimalistickou implementací &lt;/strong&gt;rozhraní
ICommand. 
&lt;p&gt;
Pokud podobnou třídu nemáte, vložte si&amp;nbsp; do projektu třídu DelegateCommand. U
mě je v jmenném prostoru &lt;strong&gt;RStein.PosterousReader.Common.&lt;/strong&gt; 
&lt;p&gt;
&lt;strong&gt;&lt;script src="http://gist.github.com/793206.js"&gt;&lt;/script&gt;&lt;/strong&gt; 
&lt;p&gt;
Třídě DelegateCommand můžete předat dva delegáty. Delegát executeAction (“co má být
vykonáno”) je spuštěn v metodě Execute z rozhraní ICommand. Delegát canExecuteAction
představuje implementaci metody CanExecute (“může být&amp;nbsp; nyní command vykonán?”).
Minimalistická implementace je to proto, že nijak nepoužívám událost CanExecuteChanged,
a namísto toho jsem si pro “binding” vystavil speciální vlastnost CanExecuteCommand,
která v get akcesoru deleguje na metodu CanExecute.
&lt;/p&gt;
&lt;p&gt;
Vlastnost TextChangedAction v LoginViewModelu je delegát typu Action, který nám pomáhá
vyřešit jeden z požadavků na přihlášení. 
&lt;p&gt;
&lt;em&gt;“Jestliže není uživatelské jméno vyplněno (prázdný řetězec) a/nebo není vyplněno
heslo, tlačítko Přihlásit se je neaktivní.”&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
To znamená, že potřebujeme po každém přidání nebo smazání znaku v textboxu pro zadání
jména uživatele i v textboxu pro zadání hesla zjišťovat, jestli můžeme ve view zpřístupnit
tlačítko pro přihlášení. Když je alespoň jeden textbox prázdný, tlačítko pro přihlášení
není dostupné, když je vyplněno alespoň jedním znakem jméno i heslo, tlačítko pro
přihlášení je dostupné.
&lt;/p&gt;
&lt;p&gt;
Jak je tento požadavek ve view a view modelu splněn?
&lt;/p&gt;
&lt;p&gt;
Ve view &lt;em&gt;LoginView&lt;/em&gt; je vlastnost &lt;em&gt;IsEnabled&lt;/em&gt; tlačítka “Přihlásit se“
z třídy &lt;em&gt;ButtonEx&lt;/em&gt; “nabindována” na vlastnost &lt;em&gt;CanExecuteCommand&lt;/em&gt; objektu &lt;em&gt;LoginCommand&lt;/em&gt; ve
view modelu.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_21.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_9.png" width="244" height="154"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Do projektové složky UI si přidejte třídu ButtonEx, která doplňuje standardní WP7
tlačítko o jednoduchou podporu objektů ICommand.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;script src="http://gist.github.com/793221.js"&gt;&lt;/script&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Vlastnost CanExecuteCommand musí vracet true, pokud je v každém textboxu alespoň jeden
znak, jinak false. Jak ale ve view modelu zjistíme, že uživatel zadal nebo smazal
v některém textovém poli další znak? Do view modelu se při oboustranném bindingu zpropaguje
hodnota z textového pole až po opuštění textového pole uživatelem, ale my přitom musíme
reagovat ve view modelu na zadání každého znaku.
&lt;/p&gt;
&lt;p&gt;
Takové chování textových polí ve WP7 skutečně nemáme a musíme si ho dopsat, a to nejlépe
za pomoci ”attached” vlastností a objektů &lt;em&gt;Behavior&amp;lt;T&amp;gt;&lt;/em&gt;. Nejprve se podívejme,
jak vypadají objekty TextBox a PasswordBox v XAMLu, když jsou rozšířeny o “attached”
vlastnost &lt;em&gt;TextboxPasswordAttachedProperties.TextBoxChangedAction&lt;/em&gt;, která je
“nabindována” na nám již známou vlastnost TextChangedAction typu Action ve view modelu.&amp;nbsp;
“Attached” vlastnost &lt;em&gt;TextBoxChangedAction&lt;/em&gt; tedy říká: “Hej, kdykoli se změní
u prvku zadaný text, musí NĚKDO ochotný zavolat delegáta TextChangedAction, abychom
ve view modelu nebyli odříznuti od novinek ve světě view.”
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_23.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_10.png" width="244" height="154"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
A ten někdo bude náš objekt Behavior , který zase světu sděluje: “Mám dobré vychování,
a když mi dovolíte vstoupit do bran tagu PasswordBox nebo TextBox, delegáta TextChangedAction
zavolám,&amp;nbsp; i když to sám WP7 TextBox a PasswordBox nezvládne.”
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/793240.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Další nepříjemností ve WP7 je, že i když objekt Behavior má mít pro TextBox a PasswordBox&amp;nbsp;
stejné chování, musíme napsat dva objekty Behavior pro každý prvek, protože TextBox
ani PasswordBox spolu kupodivu nemají moc společného. My se alespoň pokusíme kód v
obou objektech Behavior neduplikovat.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Do projektové složky Behaviors přidejte třídu TextboxPasswordAttachedProperties a
v ní vytvořte attached vlastnost TextBoxChangedAction.
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/793248.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Do složky Behaviors přidejte abstraktní třídu TextChangedBehaviorBase, která bude
fungovat jako základ pro dva podobné objekty Behavior určené pro TextBox (TextBoxTextChangedUpdateSourceBehavior)
a PasswordBox (PasswordTextChangedBehavior). &lt;strong&gt;Do projektu musíte přidat referenci
na knihovnu System.Windows.Interactivity, &lt;/strong&gt;kterou naleznete většinou ve složce &lt;em&gt;c:\Program
Files\Microsoft SDKs\Expression\Blend\Windows Phone\v7.0\Libraries\System.Windows.Interactivity.dll. &lt;/em&gt;&lt;strong&gt;Bez
této knihovny není dostupná bázová třída Behavior&amp;lt;T&amp;gt;.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/793259.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Metoda RunTextChangedAction se pro objekt Textbox a PasswordBox asociovaný s tímto
objektem Behavior&amp;nbsp; pokusí dohledat a spustit delegáta v “attached” vlastnost
TextBoxChangedAction. Metoda UpdateSource požádá odvozené třídy o vydání "objektu
BindingExpression” voláním metody GetBindingExpression. Vrácený objekt “BindingExpression“
by měl&amp;nbsp; zapouzdřovat propojení vlastnosti view modelu (např UserName) s textem
v textovém poli. Po kontrole, že se jedná o oboustranný (two way) binding, metoda
UpdateSource zavolá na objektu BindingExpression UpdateSource, což způsobí přenesení
hodnoty zadané uživatelem v textovém poli ve view do zdrojové vlastnosti (např. UserName)
ve view modelu.
&lt;/p&gt;
&lt;p&gt;
Potomek TextBoxTextChangedUpdateSourceBehavior v metodě GetBindingExpression vrátí
BindingExpression pro svou vlastnost Text. V přepsané metodě OnAttached, která je
volána vždy, když je objekt Behavior asociován s textboxem, si přihlásíme odběr události
TextChanged TextBoxu a při každé změně textu voláme zděděné a výše popsané metody
UpdateSource a RunTextChangedAction. V metodě OnDetaching si nezapomeneme odběr události
TextChanged odhlásit.
&lt;/p&gt;
&lt;script src="http://gist.github.com/793285.js"&gt;&lt;/script&gt;
&lt;p&gt;
Pro PasswordBox máme dalšího potomka PasswordTextChangedBehavior, který se od třídy
TextBoxTextChangedUpdateSourceBehavior liší jen tím, že v metodě GetBindingExpression
vrací “BindingExpression” pro vlastnost Password a zadávaný text sleduje přes událost
PasswordChanged.
&lt;/p&gt;
&lt;script src="https://gist.github.com/793557.js"&gt; &lt;/script&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
V LoginView si nezapomeňte zkontrolovat, že máte namapovány správně xml prefixy &lt;em&gt;behaviors&lt;/em&gt; a &lt;em&gt;i&lt;/em&gt;&lt;strong&gt; &lt;/strong&gt;na
správné jmenné prostory v C#, abyste mohli využívat novou attached vlastnost TextBoxChangedAction
a objekty TextBoxTextChangedUpdateSourceBehavior&amp;nbsp; a PasswordTextChangedBehavior.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;prostoryxmlns:behaviors="clr-namespace:RStein.PosterousReader.WP.Behaviors"&lt;br&gt;
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_25.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/image_thumb_11.png" width="244" height="154"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Dodejme, že náš delegát TextChangedAction ve view modelu simuluje změnu objektu LoginCommand,
který je přidružen k tlačítku Přihlásit se a tlačítko Přihlásit tedy po každém zadání
znaku zjistí, jestli má být dostupné.&amp;nbsp; Zopakujme, že vlastnost IsEnabled tlačítka
je “nabindována” na vlastnost LoginCommand.CanExecuteCommand. 
&lt;/p&gt;
&lt;p&gt;
Aplikaci můžete spustit.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Poznámka: Ještě si ale nezapomeňte do složky UIServices dát kód rozhraní IViewModelResolver
a třídy ViewModelResolver, které jsem popisoval v článku &lt;/em&gt;&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;&lt;em&gt;propojení
view modelu s view (stránkou)&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, protože bez třídy ViewModelResolver by
aplikace nebyla schopna pro naše MainLoginView a LoginView dohledat právě vytvořené
view modely. A v aplikaci musíte mít samozřejmě všechny další třídy z předchozích
článků, které jsou odpovědné za “tombstoning” apod.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
U aplikace si můžete zkontrolovat, že:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Přihlašovací dialog plní všechny požadavky, které jsme vypsal&amp;nbsp; na začátku článku.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png"&gt;
&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Nemusíme se nijak starat o “tombstoning” aplikace. Zmáčkněte tlačítko Win, poté se
tlačítkem Back vraťte do aplikace a všechny hodnoty v textových polích zůstanou zachovány.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Tlačítko pro přihlášení je dostupné jen tehdy, když textová pole pro zadání jména
a hesla jsou vyplněna. Pokud alespoň jedno pole vyplněno není, tlačítko je neaktivní.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
I naše minimalistická podpora rozhraní ICommand vede k tomu, že ve View nemáme žádný&amp;nbsp;
“code behind”. Logika stojící za view je jen ve view modelech a XAML tahá data z view
modelů přes “data binding”. Pokud přesně tohle to považujete za důležité, budete určitě
nadšeni. Jak uvidíte v dalších článcích, já jsem vůči strategii “vše do XAMLu” hodně
skeptický, ale XAML puristé &lt;strike&gt;si &lt;/strike&gt;mohou jít po dnešku jistě &lt;strike&gt;ožrat
držku &lt;/strike&gt;slavit&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png"&gt;.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
I když šlo jen o přihlašovací formulář, vytvořili jsme si další skládací kostky (attached
vlastnosti, Behavior, PosterousViewModelBase), které se nám budou hodit při psani
dalších view a view modelů (nejen)&amp;nbsp; v této aplikaci.&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Zauvažujte nad tím, jestli by se nám také nehodila nějaká podpora ve view modelech
pro ukládání nejen tranzientního stavu, ale i pro ukládání “trvalejšího” stavu, který
bude dostupný i v další nezávislé instanci aplikace. Možná by stálo za to, aby si
aplikace pamatovala poslední zadané přihlašovací jméno nejen při “tombstoningu”, ale
aby přihlašovací jméno bylo nabídnuto i při novém spuštění aplikace. A z hlediska
vývojáře&amp;nbsp; bezbolestná podpora pro ukládání perzistentního stavu (&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;data
s “delší záruční lhůtou”&lt;/a&gt;) bude námětem dalšího WP7 intermezza. Doufám, že se těšíte. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-V--vyt_92C1/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Předchozí články:&lt;br&gt;
&lt;br&gt;
&lt;/strong&gt;&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx"&gt;Tipy
pro Windows Phone 7 aplikace I&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;Tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”&lt;/a&gt; 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;Tipy
pro Windows Phone 7 aplikace III–propojení view modelu s view (stránkou)&lt;/a&gt; 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IV+Intermezzo+I+Zjednoduscaronenaacute+Registrace+Serializovatelnyacutech+T%c5%99iacuted+Nesouciacutech+Tranzientniacute+Stav+V+KnownTypesDictionary.aspx"&gt;Tipy
pro Windows Phone 7 aplikace IV - intermezzo I - zjednodušená registrace serializovatelných
tříd nesoucích tranzientní stav v KnownTypesDictionary&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=1ab0ecc7-7a79-4e17-b2f8-358bd7713695" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,1ab0ecc7-7a79-4e17-b2f8-358bd7713695.aspx</comments>
      <category>C# Posterous API</category>
      <category>Compact .Net Framework</category>
      <category>Návrhové vzory</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=0257bcba-1a86-4ec0-a779-e858ab369d9f</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,0257bcba-1a86-4ec0-a779-e858ab369d9f.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,0257bcba-1a86-4ec0-a779-e858ab369d9f.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=0257bcba-1a86-4ec0-a779-e858ab369d9f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
Dnešní článek je jen “intermezzem”, protože doplňuje <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">předchozí
článek</a> o slíbenou informaci, jak můžeme automaticky registrovat serializovatelné
třídy, jejichž instance  nesou tranzientní stav, který je uložen  v KnownTypesDictionary. <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">Přechozí
článek</a> končil <a href="https://gist.github.com/763469#file_known_types_dictionary.cs">ukázkou</a>,
jak můžeme vrátit staticky definovaný seznam typů, dnes se poohlédneme po trochu dynamičtějším
řešení. I když postup není omezen jen na WP7 aplikace, ale můžete ho použít v kterékoli
aplikaci, která využívá (WCF) <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx">DataContractSerializer</a>,
my se zaměříme v článku opět hlavně na řešení WP7 specialitek. 
</p>
        <p>
Přečetli jste si první odstavec a nevíte, co je tranzientní stav? Hledáte marně v
MSDN typ KnownTypesDictionary? Nedivte se, milostný akt sice můžete rozjet bez předehry,
ale abyste rozuměli  tomuto intermezzu, pečlivě a pomalu si přečtěte jako předehru
k intermezzu <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”</a>, i díl <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">třetí,
kde se bavíme o KnownTypesDctionary</a>.
</p>
        <p>
Předehru máte za sebou, takže víte, že KnownTypesDictionary je specializovaný objekt
Dictionary, ve kterém je klíčem řetězec a hodnotou libovolný objekt a že v objektech
KnownTypesDictionary ukládáme tranzientní stav view modelů při každém “tombstoningu”.
I když KnownTypesDictionary může jako hodnotu nést libovolný objekt, my musíme instruovat
DataContractSerializer, které objekty a hlavně z kterých odvozených tříd má v objektu
Dictionary očekávat.
</p>
        <p>
Když do KnownTypesDictionary ukládáme v jedné aplikaci instance z tříd OrderVO a InvoiceVO
a v jiné aplikaci instance TwitterPost a ObservableCollection&lt;TwitterPost &gt;,
musíme vždy znovu zmíněné třídy registrovat pomocí atributu <a href="http://msdn.microsoft.com/en-gb/library/system.runtime.serialization.knowntypeattribute.aspx">KnownType</a>.
</p>
        <p>
Pro připomenutí následuje výpis kódu, kterým jsme končili a který registruje serializovatelné
třídy v aplikaci “natvrdo” pomocí statické metody <em>GetKnownTypes</em>, jejíž název
je předán do konstruktoru atributu KnownType.
</p>
        <p>
 
</p>
        <p>
          <script src="https://gist.github.com/763469.js">
          </script>
Napevno zadrátované typy v <em>KnownTypesDctionary</em> nám nemusí vadit v jedné aplikaci,
ale když chceme používat KnownTypesDctionary v mnoha různých aplikacích, musím řešení
upravit.
</p>
        <p>
Místo abychom třídy v metodě <em>GetKnownTypes </em>registrovali přímo, delegujeme
odpovědnost za vrácení serializovatelných typů na specializovaného poskytovatele.<br /><em></em></p>
        <p>
          <em>BTW: To víte, že první a okouzlující zákon vztahu mezi třídami zní:  “Když
je třída vyčerpána množstvím odpovědností, vždy si může přičarovat otroka, který špinavou
práci udělá za ni”?. Občas se tomuto zákonu  také říká SRP – princip jedné odpovědnosti
třídy”.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows_9A1E/wlEmoticon-smile_2.png" /></em>
        </p>
        <p>
Poskytovatel je objekt podporující rozhraní IKnownTypeProvider s jednou samopopisnou
metodou.
</p>
        <p>
          <script src="http://gist.github.com/772649.js">
          </script>
        </p>
        <p>
Refaktorizujeme třídu KnownTypesDictionary, aby při vracení serializovatelných typů
využívala objekt IKnownTypeProvider. 
</p>
        <p>
          <script src="http://gist.github.com/772654.js">
          </script>
        </p>
        <p>
Do nové statické vlastnosti KnownTypeProvider je ve statickém konstruktoru přiřazen
DefaultKnownTypesProvider, o kterém budeme mluvit za chvíli, ale do vlastnosti KnownTypeProvider
můžete klidně vložit pro účely vaší aplikace lépe přizpůsobený IKnownTypeProvider. 
</p>
        <p>
Metoda GetKnownTypes vrátí všechny staticky registrované typy v poli KNOWN_TYPES společně
s  typy, které dodá  IKnownTypeProvider. Typy jsou získány jen při prvním
volání metody GetKnownTypes a jsou cachovány v proměnné _cachedKnownTypes, abychom
opakovaným získáním typů z  IKnownTypeProvider zbytečně neplýtvali výkonem WP7
telefonů ani trpělivostí uživatele. Předpokladem tohoto přístupu samozřejmě je, že
v aplikaci je fixní množina serializovatelných typů, která se za běhu aplikace již
nemění. Jestli vám to nevyhovuje, odstraníte cache z KnownTypesDictionary za 10 sekund. 
</p>
        <p>
Jaké odpovědnosti bude mít DefaultKnownTypesProvider? 
</p>
        <ol>
          <li>
DefaultKnownTypesProvider nám vrátí všechny deskriptory třídy (Type) označené atributem
[DataContract] v hlavní assembly aplikace.<br /><br /></li>
          <li>
DefaultKnownTypesProvider nám vrátí všechny deskriptory třídy (Type) označené atributem
[DataContract] v dalších assembly, ze kterých je složena aplikace.<br /><br /></li>
          <li>
DefaultKnownTypesProvider nalezne další a pro aktuální aplikaci specifické objekty
podporující rozhraní IKnownTypeProvider a vrátí seznam všech typů z těchto providerů.<br /><br /></li>
          <li>
Pro všechny nalezené typy T zaregistruje i kolekci Observable&lt;T&gt;. To znamená,
že pro třídu OrderVO označenou atributem DataContract je automaticky vrácen z poskytovatele
nejen její Type (typof(OrderVO), ale i deskriptor kolekce typeof(ObservableCollection&lt;OrderVO&gt;).<br /></li>
        </ol>
        <p>
Kód třídy DefaultKnownTypesProvider: 
</p>
        <p>
          <script src="http://gist.github.com/772673.js">
          </script>V metodě GetKnownTypes vyzvedneme
všechny typy z “hlavní”  (vstupní) assembly. Hlavní assembly získáme v metodě
getExecutingAssembly přes vlastnosti třídy Deployment. 
</p>
        <p>
          <script src="http://gist.github.com/772674.js">
          </script>Typy z hlavní  assembly
sloučíme s typy v dalších assembly voláním metody getRefencedAssembliesTypes(). Ve
WP7 jsem bohužel nenašel způsob, jak seznam dalších assembly získat, a proto další
assembly poskytují objekty <em>IAssemblyTypesProvider </em>nalezené v hlavní assembly.
</p>
        <p>
Chcete-li tedy automaticky vyhledat typy označené atributem <em>DataContract </em>v
další assembly, vložte do hlavní assembly třídu podporující rozhraní <em>IAssemblyTypesProvider<strong>.</strong></em></p>
        <script src="http://gist.github.com/772676.js">
        </script>
        <p>
Do proměnné <em>collectionTypes</em> v metodě <em>GetKnownTypes</em> vygenerujeme
pro všechny nalezené typy jejich kolekce. Možná trochu složitě vypadající kód jen
zabraňuje tomu, abyste nalezené deskriptory tříd typu ObservableCollection&lt;T&gt;
v proměnné <em>types</em> balili znovu do kolekce ObservableCollection. Jinými slovy,
když v proměnné <em>types</em> bude kolekce <em>ObservableCollection&lt;OrderVO&gt;</em>,
do proměnné collectionTypes <strong>nebude </strong>generována kolekce <em>ObservableCollection&lt;ObservableCollection&lt;OrderVO&gt;&gt;</em>.
</p>
        <p>
          <script src="http://gist.github.com/772696.js">
          </script>
        </p>
        <p>
Na konci vracíme nalezené typy sloučené s vygenerovanými typy kolekcí ObservableCollection&lt;T&gt;
a dalšími a pro aplikaci specifickými typy z ostatnich poskytovatelů . Za poskytovatele
považujeme další objekty IKnownTypeProvider nalezené v hlavní assembly. <script src="http://gist.github.com/772704.js"></script></p>
        <p>
A tím máme hotovo. 
</p>
        <p>
Připomínám, že DefaultKnownTypesProvider můžete využít nejen ve WP7 aplikacích, ale
ve všech aplikacích v .Net Frameworku, kde je používán DataContractSerializer a vy
chcete automaticky registrovat odvozené serializovatelné typy. 
</p>
        <p>
Příště již začneme stavět aplikaci založenou na našem "mini frameworku”, abyste viděli,
k čemu tyto počáteční díly seriálu včetně intermezza, které právě čtete, vůbec byly.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows_9A1E/wlEmoticon-smile_2.png" /></p>
        <p>
Předcházející články: 
</p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx">Tipy
pro Windows Phone 7 aplikace I</a>
        </p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">Tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”</a>
        </p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx">Tipy
pro Windows Phone 7 aplikace III–propojení view modelu s view (stránkou)</a>
        </p>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=0257bcba-1a86-4ec0-a779-e858ab369d9f" />
      </body>
      <title>Tipy pro Windows Phone 7 aplikace IV - intermezzo I - zjednodu&amp;scaron;en&amp;aacute; registrace serializovateln&amp;yacute;ch tř&amp;iacute;d nesouc&amp;iacute;ch tranzientn&amp;iacute; stav v KnownTypesDictionary</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,0257bcba-1a86-4ec0-a779-e858ab369d9f.aspx</guid>
      <link>http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IV+Intermezzo+I+Zjednoduscaronenaacute+Registrace+Serializovatelnyacutech+T%c5%99iacuted+Nesouciacutech+Tranzientniacute+Stav+V+KnownTypesDictionary.aspx</link>
      <pubDate>Mon, 10 Jan 2011 12:37:12 GMT</pubDate>
      <description>&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Dnešní článek je jen “intermezzem”, protože doplňuje &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;předchozí
článek&lt;/a&gt; o slíbenou informaci, jak můžeme automaticky registrovat serializovatelné
třídy, jejichž instance&amp;nbsp; nesou tranzientní stav, který je uložen&amp;nbsp; v KnownTypesDictionary. &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;Přechozí
článek&lt;/a&gt; končil &lt;a href="https://gist.github.com/763469#file_known_types_dictionary.cs"&gt;ukázkou&lt;/a&gt;,
jak můžeme vrátit staticky definovaný seznam typů, dnes se poohlédneme po trochu dynamičtějším
řešení. I když postup není omezen jen na WP7 aplikace, ale můžete ho použít v kterékoli
aplikaci, která využívá (WCF) &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx"&gt;DataContractSerializer&lt;/a&gt;,
my se zaměříme v článku opět hlavně na řešení WP7 specialitek. 
&lt;/p&gt;
&lt;p&gt;
Přečetli jste si první odstavec a nevíte, co je tranzientní stav? Hledáte marně v
MSDN typ KnownTypesDictionary? Nedivte se, milostný akt sice můžete rozjet bez předehry,
ale abyste rozuměli&amp;nbsp; tomuto intermezzu, pečlivě a pomalu si přečtěte jako předehru
k intermezzu &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”&lt;/a&gt;, i díl &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;třetí,
kde se bavíme o KnownTypesDctionary&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Předehru máte za sebou, takže víte, že KnownTypesDictionary je specializovaný objekt
Dictionary, ve kterém je klíčem řetězec a hodnotou libovolný objekt a že v objektech
KnownTypesDictionary ukládáme tranzientní stav view modelů při každém “tombstoningu”.
I když KnownTypesDictionary může jako hodnotu nést libovolný objekt, my musíme instruovat
DataContractSerializer, které objekty a hlavně z kterých odvozených tříd má v objektu
Dictionary očekávat.
&lt;/p&gt;
&lt;p&gt;
Když do KnownTypesDictionary ukládáme v jedné aplikaci instance z tříd OrderVO a InvoiceVO
a v jiné aplikaci instance TwitterPost a ObservableCollection&amp;lt;TwitterPost &amp;gt;,
musíme vždy znovu zmíněné třídy registrovat pomocí atributu &lt;a href="http://msdn.microsoft.com/en-gb/library/system.runtime.serialization.knowntypeattribute.aspx"&gt;KnownType&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Pro připomenutí následuje výpis kódu, kterým jsme končili a který registruje serializovatelné
třídy v aplikaci “natvrdo” pomocí statické metody &lt;em&gt;GetKnownTypes&lt;/em&gt;, jejíž název
je předán do konstruktoru atributu KnownType.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/763469.js"&gt; &lt;/script&gt;
Napevno zadrátované typy v &lt;em&gt;KnownTypesDctionary&lt;/em&gt; nám nemusí vadit v jedné aplikaci,
ale když chceme používat KnownTypesDctionary v mnoha různých aplikacích, musím řešení
upravit.
&lt;/p&gt;
&lt;p&gt;
Místo abychom třídy v metodě &lt;em&gt;GetKnownTypes &lt;/em&gt;registrovali přímo, delegujeme
odpovědnost za vrácení serializovatelných typů na specializovaného poskytovatele.&lt;br&gt;
&lt;em&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;BTW: To víte, že první a okouzlující zákon vztahu mezi třídami zní:&amp;nbsp; “Když
je třída vyčerpána množstvím odpovědností, vždy si může přičarovat otroka, který špinavou
práci udělá za ni”?. Občas se tomuto zákonu&amp;nbsp; také říká SRP – princip jedné odpovědnosti
třídy”.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows_9A1E/wlEmoticon-smile_2.png"&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Poskytovatel je objekt podporující rozhraní IKnownTypeProvider s jednou samopopisnou
metodou.
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/772649.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Refaktorizujeme třídu KnownTypesDictionary, aby při vracení serializovatelných typů
využívala objekt IKnownTypeProvider. 
&lt;p&gt;
&lt;script src="http://gist.github.com/772654.js"&gt;&lt;/script&gt;
&lt;p&gt;
Do nové statické vlastnosti KnownTypeProvider je ve statickém konstruktoru přiřazen
DefaultKnownTypesProvider, o kterém budeme mluvit za chvíli, ale do vlastnosti KnownTypeProvider
můžete klidně vložit pro účely vaší aplikace lépe přizpůsobený IKnownTypeProvider. 
&lt;p&gt;
Metoda GetKnownTypes vrátí všechny staticky registrované typy v poli KNOWN_TYPES společně
s&amp;nbsp; typy, které dodá&amp;nbsp; IKnownTypeProvider. Typy jsou získány jen při prvním
volání metody GetKnownTypes a jsou cachovány v proměnné _cachedKnownTypes, abychom
opakovaným získáním typů z&amp;nbsp; IKnownTypeProvider zbytečně neplýtvali výkonem WP7
telefonů ani trpělivostí uživatele. Předpokladem tohoto přístupu samozřejmě je, že
v aplikaci je fixní množina serializovatelných typů, která se za běhu aplikace již
nemění. Jestli vám to nevyhovuje, odstraníte cache z KnownTypesDictionary za 10 sekund. 
&lt;p&gt;
Jaké odpovědnosti bude mít DefaultKnownTypesProvider? 
&lt;ol&gt;
&lt;li&gt;
DefaultKnownTypesProvider nám vrátí všechny deskriptory třídy (Type) označené atributem
[DataContract] v hlavní assembly aplikace.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
DefaultKnownTypesProvider nám vrátí všechny deskriptory třídy (Type) označené atributem
[DataContract] v dalších assembly, ze kterých je složena aplikace.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
DefaultKnownTypesProvider nalezne další a pro aktuální aplikaci specifické objekty
podporující rozhraní IKnownTypeProvider a vrátí seznam všech typů z těchto providerů.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Pro všechny nalezené typy T zaregistruje i kolekci Observable&amp;lt;T&amp;gt;. To znamená,
že pro třídu OrderVO označenou atributem DataContract je automaticky vrácen z poskytovatele
nejen její Type (typof(OrderVO), ale i deskriptor kolekce typeof(ObservableCollection&amp;lt;OrderVO&amp;gt;).&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Kód třídy DefaultKnownTypesProvider: 
&lt;p&gt;
&lt;script src="http://gist.github.com/772673.js"&gt;&lt;/script&gt;V metodě GetKnownTypes vyzvedneme
všechny typy z “hlavní”&amp;nbsp; (vstupní) assembly. Hlavní assembly získáme v metodě
getExecutingAssembly přes vlastnosti třídy Deployment. 
&lt;p&gt;
&lt;script src="http://gist.github.com/772674.js"&gt;&lt;/script&gt;Typy z hlavní&amp;nbsp; assembly
sloučíme s typy v dalších assembly voláním metody getRefencedAssembliesTypes(). Ve
WP7 jsem bohužel nenašel způsob, jak seznam dalších assembly získat, a proto další
assembly poskytují objekty &lt;em&gt;IAssemblyTypesProvider &lt;/em&gt;nalezené v hlavní assembly.
&lt;/p&gt;
&lt;p&gt;
Chcete-li tedy automaticky vyhledat typy označené atributem &lt;em&gt;DataContract &lt;/em&gt;v
další assembly, vložte do hlavní assembly třídu podporující rozhraní &lt;em&gt;IAssemblyTypesProvider&lt;strong&gt;.&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;script src="http://gist.github.com/772676.js"&gt;&lt;/script&gt;
&lt;p&gt;
Do proměnné &lt;em&gt;collectionTypes&lt;/em&gt; v metodě &lt;em&gt;GetKnownTypes&lt;/em&gt; vygenerujeme
pro všechny nalezené typy jejich kolekce. Možná trochu složitě vypadající kód jen
zabraňuje tomu, abyste nalezené deskriptory tříd typu ObservableCollection&amp;lt;T&amp;gt;
v proměnné &lt;em&gt;types&lt;/em&gt; balili znovu do kolekce ObservableCollection. Jinými slovy,
když v proměnné &lt;em&gt;types&lt;/em&gt; bude kolekce &lt;em&gt;ObservableCollection&amp;lt;OrderVO&amp;gt;&lt;/em&gt;,
do proměnné collectionTypes &lt;strong&gt;nebude &lt;/strong&gt;generována kolekce &lt;em&gt;ObservableCollection&amp;lt;ObservableCollection&amp;lt;OrderVO&amp;gt;&amp;gt;&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;script src="http://gist.github.com/772696.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Na konci vracíme nalezené typy sloučené s vygenerovanými typy kolekcí ObservableCollection&amp;lt;T&amp;gt;
a dalšími a pro aplikaci specifickými typy z ostatnich poskytovatelů . Za poskytovatele
považujeme další objekty IKnownTypeProvider nalezené v hlavní assembly. &lt;script src="http://gist.github.com/772704.js"&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
A tím máme hotovo. 
&lt;p&gt;
Připomínám, že DefaultKnownTypesProvider můžete využít nejen ve WP7 aplikacích, ale
ve všech aplikacích v .Net Frameworku, kde je používán DataContractSerializer a vy
chcete automaticky registrovat odvozené serializovatelné typy. 
&lt;p&gt;
Příště již začneme stavět aplikaci založenou na našem "mini frameworku”, abyste viděli,
k čemu tyto počáteční díly seriálu včetně intermezza, které právě čtete, vůbec byly.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows_9A1E/wlEmoticon-smile_2.png"&gt; 
&lt;p&gt;
Předcházející články: 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx"&gt;Tipy
pro Windows Phone 7 aplikace I&lt;/a&gt; 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;Tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”&lt;/a&gt; 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx"&gt;Tipy
pro Windows Phone 7 aplikace III–propojení view modelu s view (stránkou)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=0257bcba-1a86-4ec0-a779-e858ab369d9f" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,0257bcba-1a86-4ec0-a779-e858ab369d9f.aspx</comments>
      <category>.NET Framework</category>
      <category>C#</category>
      <category>Návrhové vzory</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=38539832-2f1d-42cf-8549-b59697b093c4</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,38539832-2f1d-42cf-8549-b59697b093c4.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,38539832-2f1d-42cf-8549-b59697b093c4.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=38539832-2f1d-42cf-8549-b59697b093c4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <em>
            <font color="#ff0000">Update 4. 1.   2011  - upraven kód objektu
UIHelper a spolupracující metody tak, aby byl klíč generovaný pro tranzientní stav
každého view modelu skutečně unikátní.</font>
          </em>
          <font color="#ff0000">Když rozkliknete
GISTy, můžete se podívat i na původní verzi kódu.</font>
        </p>
        <p>
V <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">předchozím
článku</a> jsme se podrobně věnovali vytvoření bázové třídy pro view modely včetně
podpory ukládání tranzientního stavu během “tombstoningu” a na konci jsem slíbil,
že další díl bude věnován hlavně propojení našich view modelů s view. 
</p>
        <p>
View pro nás bude hostitel view modelu a v souladu s WP7 modelem navigace mezi jednotlivými
stránkami budeme za hlavního hostitele považovat potomka třídy <em>PhoneApplicationPage<strong>. </strong></em>Uvidíme
ale, že při vytváření View nejsme omezeni na potomky <em>PhoneApplicationPage, </em>protože
budeme schopni vytvořit i view jako potomka třídy <em>UserControl.</em></p>
        <p>
Zrekapitujme hlavní funkce, které by měl náš hostitel view modelů zvládat: 
</p>
        <ol>
          <li>
Při vytvoření stránky je třeba najít ke stránce přidružený view model. Dodejme již
nyní, že povinností hostitele bude dohledat i vnořené (dceřiné) view modely, jestliže
je jedna stránka složena z více nezávislých view a každé view může být asociováno
s jiným view modelem.<br /><br /></li>
          <li>
Při vytvoření stránky je nutné u view modelu volat metodu <em>Init</em> pro základní
inicializaci view modelu, jestliže view model podporuje naše rozhraní <em>IInittialize<strong>. </strong></em>Znovu
připomínám, co zaznělo v <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">minulém
článku</a>, že si implementaci žádných rozhraní u view modelů nevynucujeme.<br /><br /></li>
          <li>
Jestliže se stránka stane poprvé nebo po návratu uživatele “aktivní” (zobrazenou),
je nutné volat na view modelu metodu <em>Activate</em>, když view model podporuje
rozhraní <em>IActivated.<br /><br /></em>. 
</li>
          <li>
Jestliže uživatel ze stránky odchází, hostitel na view modelu volá metodu Deactivate
z rozhraní IDeactivated.<br /><br /></li>
          <li>
Hostitel musí být schopen při “tombstoningu” uložit tranzientní stav view modelu.<br /><br /></li>
          <li>
Po návratu z “tombstoningu” hostitel dovolí view modelu obnovit tranzientní stav.<br /><br /></li>
          <li>
            <strong>Hostitel se nás bude snažit ve view modelech odstínit od všech  WP7 nedomyšleností,
záludností, nesmyslných omezení a programátorských vrtochů, které jsou nedílnou a
z pohledu mobilní MS divize jistě i zábavnou součástí celkově kapriciozního životního
cyklu třídy PhoneApplicationPage.<br /></strong>
          </li>
        </ol>
        <p>
Nyní již můžeme přístoupit k vytvoření hostitele. Našim hostitelem bude třída <em>PageBase, </em>která
je potomkem PhoneApplicationPage z WP7 frameworku. Nakonec jsem pro účely článku zvolil
toto řešení, i když není problém v dalších dílech ukázat adaptér, který nás nutnosti
vlastní stránky v aplikaci odvozovat z bázové třídy <em>PageBase</em> zbaví. Myslím
si ale, že navigační model WP7 aplikací neposkytuje sám o sobě mnoho prostoru pro
kreativitu, a proto nutnost dědit z PageBase místo třídy PhoneApplicationPage z WP7
za nějak zvlášť restriktivní nepovažuju.
</p>
        <p>
Třída PageBase:
</p>
        <script src="https://gist.github.com/763320.js">
        </script>
        <p>
Kdykoli  dojde k aktivaci stránky, čímž míním první navigaci na stránku, nebo
návrat na stránku pomocí tlačítka Back, je volána metoda <em>OnNavigatedTo. </em>My
jsme přepsali metodu OnNavigatedTo a v ní vždy nastavíme svou vlastnost WasLayoutUpdateCalled
na false. <strong>Vlastnost WasLayoutUpdateCalled použijeme za chvíli, zde jen řekněme,
že tuto vlastnost potřebujeme k tomu, abychom poznali, že již je vytvořen celý vizuální
strom ovládacích prvků a že můžeme s ovládacími prvky bez obav pracovat. </strong>Bohužel
v metodě OnNavigatedTo vizuální strom prvků vytvořen být nemusí. O některých problémech,
které je nutné řešit, když není zcela vytvořen vizuální strom prvků, jsem již mluvil
u ovládacího prvku <em>WebBrowser </em>v <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx">první
části tohoto seriálu</a>. 
</p>
        <p>
Metoda OnNavigatedTo také dá příkaz k vyzvednutí dříve uloženého tranzientního stavu
pomocí metody loadSavedTransientState z vlastnosti PhoneApplicationPage.State. Tranzientní
stav, pokud existuje, je pouze uložen do vlastnosti LastSavedTransientState a zatím
se s ním nijak nepracuje. Klíčem, pod kterým je uložen stav celé stránky včetně tranzientního
stavu view modelů, je plně kvalifikované jméno aktuální stránky (string stateKey =
GetType().FullName). <strong>Měli bychom si být vědomi, že při této implementaci nesmíme
mít jednu stránku v aplikaci nahranou vícekrát, protože by různé instance stejné stránky
mezi sebou sdílely stav. Když budete trvat na tom, že jedna stránka může mít v systému
několik instancí, není problém změnit generování klíče, pod kterým bude stav pro každou
unikátně identifikovanou instanci uložen.</strong></p>
        <script src="https://gist.github.com/763335.js">
        </script>
        <p>
Pokračujme v našem scénáři. V konstruktoru si přihlašujeme odběr události LayoutUpdated
(<em>LayoutUpdated += PageBase_LayoutUpdated;)<strong>, </strong></em>abychom byli
notifikováni, že již můžeme bezpečně pracovat s ovládacími prvky.
</p>
        <p>
 
</p>
        <p>
Obslužná metoda <em>handleLayoutUpdated</em> je po každé navigaci na stránku spouštěna 
jen jednou, a proto se podíváme na hodnotu vlastnosti  WasLayoutUpdateCalled
– jestliže má hodnotu true, nic dalšího neděláme. <strong>Jinak metoda zkontroluje,
zda instance PageBase je nově vytvořena, k čemuž dojde při první navigaci na stránku
a také po obnovení z “tombstonovaného" stavu. Jinak řečeno – když je volán konstruktor
třídy PageBase, znamená to, že máme stránku v “panenském” stavu, protože v ní nejsou
žádná data a dokonce ani nebyly připojeny view modely. A proto bezparametrický konstruktor
PageBase nastavuje vlastnost IsNewInstance na true, abychom v metodě <em>handleLayoutUpdated</em> 
věděli, že máme co do činění s novou instancí stránky. U nové stránky je třeba získat
view modely, a pokud je stránka obnovena po “tombstoningu”, je třeba do view modelů
nahrát tranzientní stav.  Při variantě “nová instance stránky” metoda <em>handleLayoutUpdated</em> volá
metodu LoadState.</strong></p>
        <p>
Jestliže nebyl volán konstruktor a stránka obsahuje veškerý stav, k čemuž většinou
dojde, když se vrátíme bez “tombstoningu” pomocí tlačítka Back na stránku, metoda <em>handleLayoutUpdated</em> volá
pouze pomocnou metodu <em>handleAllActivated, </em>která proiteruje všechny dříve
nahrané view modely, a když podporují rozhraní <em>IActivated</em>, tak na nich zavolá
metodu <em>Activate</em>.
</p>
        <script src="https://gist.github.com/763340.js">
        </script>
        <p>
Metoda <em>LoadState</em> ihned deleguje na metodu <em>restoreTransientState</em>,
jíž předá v objektu ElementIndexPair odkaz na aktuální stránku (this), která představuje
“root” všech prvků, a relativní index nastavený na 0 (první prvek na této úrovni).
V dalším argumentu jako prvek, pro který má být obnoven stav, předá opět odkaz na
aktuální stránku (this) a poslední argument, ve kterém metoda <em>restoreTransientState</em> očekává
naposledy použitý view model, je null, protože se žádnými view modely se ještě nepracuje.
</p>
        <p>
Metoda <em>restoreTransientState</em> nejprve zkontroluje, jestli předaný ovládací
prvek představuje View. K tomu použije objekt podporující rozhraní IViewModelResolver,
který je uložen ve statické vlastnosti ViewModelManager. Přesněji řečeno, ve vlastnosti
ViewModelManager můžete uložit delegáta (<em>Func<iviewmodelresolver>
)
</iviewmodelresolver></em>, který vrací objekt realizující rozhraní IViewModelResolver.
Ve statickém konstruktoru třídy PageBase ukládám do vlastnosti ViewModelManager funkci,
která vytváří v mé aplikaci výchozí IViewModelResolver s názvem ViewModelResolver
(<em>ViewModelManager = () =&gt; new ViewModelResolver();)</em></p>
        <p>
Rozhraní IViewModelResolver
</p>
        <p>
          <script src="https://gist.github.com/763365.js">
          </script>
        </p>
        <p>
Metodě IsView předáte vybraný objekt a ona vám vrátí true, jestliže objekt považuje
za view, pro které by měl existovat view model. Metoda ResolveViewModel přijme objekt
představující view a dohledá k němu view model.
</p>
        <p>
Pro lepší představu vám mohu bez podrobnějšího komentáře ukázat třídu, která v aplikaci
používající Posterous API dohledá k view view model na základě jmenné konvence. Za
View se považuje každá instance z třídy, jejíž název končí znaky “View”, a k tomuto
View je vrácen view model, který se jmenuje stejně jako view, ale končí znaky “ViewModel”.
K view s názvem Login<em>View </em>je tedy vrácen view model s názvem Login<em>ViewModel.</em></p>
        <script src="https://gist.github.com/763375.js">
        </script>
        <p>
Vraťme se k metodě restoreTransientState. Když metoda zjistí, že objekt představuje
view, pokusí se dohledat dříve uložený tranzientní stav. Stav je uložen pro každé
view v objektu IDictionary, konkrétně v třídě KnownTypesDictionary, pod klíčem, kterým
je úplné jméno ovládacího prvku – úplným jménem se rozumí jméno třídy ovládacího prvku
+ jména tříd všech jeho vizuálních předků (<em>ancestors</em>). Ke jménu třídy každého
prvku je přidán pořadový indexu prvku mezi prvky na stejné úrovni vizuálního stromu.
Klíč generuje třída UIHelper v metodě GetTransientStateKey.
</p>
        <p>
          <script src="https://gist.github.com/763381.js">
          </script>
Metoda restoreTransientState se poté s s využitím metody prepareViewModel pokusí získat
přes ViewModelManager view model (<em>ViewModelManager().ResolveViewModel(obj</em>),
dále zjistí, jestli view model podporuje rozhraní ITransientStateManager, IInitialize
a a IActivated a pokračuje takto:
</p>
        <ol>
          <li>
Jestliže máme uložen tranzientní stav (došlo k “tombstoningu”) a view model podporuje
rozhraní ITransientStateManager, zavoláme metodu LoadState z rozhraní ITransientStateManager
(<em>stateManager.LoadState(LastSavedTransientState[stateKey]); </em>a view model
tak dostane šanci načíst dříve uložená tranzientní data.<br /><br /></li>
          <li>
Když nemáme uložen tranzientní stav a view model podporuje rozhraní IInitialize, zavoláme
metodu IInitialize.Init. View model tak dostane šanci nahrát data, ať už se souboru,
z webové služby nebo jiného datového zdroje, která mají být zobrazena v aktuálním
view.<br /></li>
        </ol>
        <p>
Poté, co view model obnoví nebo inicializuje svůj stav, je volána metoda activateAndSetDataContext,
která na view modelech podporujících rozhraní IActivated zavolá metodu Activate a
nastaví view model jako datový zdroj (“DataContext”) view.
</p>
        <p>
Nakonec pro všechny dceřiné prvky, které mohou představovat vnořená view (např. user
control), rekurzivně zavoláme opět metodu restoreTransientState. K získání dceřiných
prvků a jejich relativního indexu mezi prvky na stejné úrovni zanoření ve vizuálním
stromu je použita metoda UIHelper.GetChildren.
</p>
        <script src="https://gist.github.com/763405.js">
        </script>
        <p>
Metoda LoadState, restoreTransientState a další pomocné metody, o kterých jsme mluvili
v předchozích odstavcích:
</p>
        <script src="https://gist.github.com/763410.js">
        </script>
        <p>
Za povšimnutí stojí ve scénáři metody restoreTransientState ještě několik dalších
věcí:
</p>
        <ul>
          <li>
Když zjišťujeme, jestli objekt podporuje rozhraní IInitialize (metoda <em>getInitObjectWithSyncContext</em>),
ihned do view modelu zpropagujeme synchronizační kontext (<em>initObject.SynchContext
= SynchronizationContext.Current</em>;), aby například událost PropertyChanged mohla
být vyvolávána vždy v UI vláknu.<br /><br /></li>
          <li>
Pomocná metoda <em>selectViewModel(frameworkElement, lastViewModel, currentViewModel);</em> odpovědná
za výběr view modelu zajistí, že když IViewModelResolver nenalezne pro view žádný
view model, automaticky view přiřadí view model použitý u předchozího view. Kdy to
potřebujete? Třeba když stránku rozdělíte na několik nezávislých “user controls”,
tak se můžete rozhodnout, jestli bude mít každý user control (view) svůj view model,
nebo view model vytvoříte jen pro celou stránku a “user controls” view modely automaticky
“zdědí”. To byl jen jeden příklad - úroveň zanoření view je zcela ve vaší režii. Slovo
“zdědí” je v uvozovkách, protože nejde o klasické dědení DataContextu, ale k předání
posledně použitého view modelu dojde i tehdy, když dvě view nemají společné “nadview”.<br /></li>
        </ul>
        <p>
          <em>Poznámka: Nejprve jsem chtěl volání metod Init a LoadState na view modelech a
následné nastavení DataContextu u view dát do jiného vlákna. Problém je v tomto případě
s dědením view modelů. Když přiřadíte view model, na kterém jste zavolali asynchronně
metodu Init, dalšímu vnořenému View, tak se může stát, že metoda Init ještě nedoběhla,
view model u prvního view nastaven není, ale u vnořeného (druhého) view již nastaven
je, což může vést k podivným a kvůli použití více vláken obtížně reprodukovatelným
chybám. Za asynchronní zpracování časově náročných scénářů zodpovídají samotné view
modely, které by měly přepisovat virtuální metodu DoInternalAsyncInit z ViewModelBase.
Metodu DoInternalAsyncInit jsem <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">popisoval
v předchozím článku</a>.</em>
        </p>
        <p>
Viděli jsme, kdy hostitel volá metody Init, Activate a kdy voláním metody LoadState
obnoví tranzientní stav ve view modelech. Ještě nám zbývá projít, kdy ukládáme tranzientní
stav a kdy notifikujeme view modely voláním jejich metody Deactivate o tom, že k nim
přidružené view (stránka) není již aktivní.
</p>
        <p>
          <strong>Nebudeme při ukládání tranzientního stavu nijak pátrat, jestli došlo k “tombstoningu”,
ale stav view modelů do <em>PhoneApplicationPage.State</em> uložíme vždy, když dojde
k opuštění stránky. Hlavním důsledkem tohoto rozhodnutí je, že s obsluhou metod 
Application_Launching, Application_Activated, Application_Deactivated a Application_Closing,
kterou jsem popisoval minule, se nemusíte kvůli “tombstoningu” trápit a zmíněné metody
můžete většinou zcela ignorovat.</strong>
        </p>
        <p>
O opuštění stránky jsm informováni v metodě OnNavigatedFrom, kterou přepíšeme. Metoda
OnNavigatedFrom voláním metody SaveState uloží stav všech view modelů a poté metoda
handleAllDeactivated na všech modelech  podporujících rozhraní IDeactivated zavolá
metodu Deactivate.
</p>
        <script src="https://gist.github.com/763441.js">
        </script>
        <p>
Popisovat kompletně logiku v metodě SaveState nemá smysl, protože tato metoda je reverzní
k metodě LoadState. Pro všechny view rekurzivně vyhledá jejich view modely a dovolí
jim uložit pod unikátním klíčem view, který je vygenerován třídou UIHelper, tranzientní
stav. Ten samý tranzientní stav view modelů, jehož obnovení v metodě LoadState jsem
popisoval výše.  <script src="https://gist.github.com/763445.js"></script></p>
        <p>
Za komentář stojí, že podmínka if<em> (stateManager != null &amp;&amp; stateManager
!= lastDataContext) </em>ošetřuje, abychom neukládali trazientní stav view modelu,
který slouží jako DataContext u více View, opakovaně, ale vždy pouze jednou.
</p>
        <p>
Tranzientní stav všech view modelů je ukládán do speciálního objektu Dictionary s
názvem KnownTypesDictionary.
</p>
        <p>
          <em>var statebag = new KnownTypesDictionary();</em>
        </p>
        <p>
Připomínám, že při tombstoningu je možné uložit jen serializovatelné objekty. Představme
si nyní, že KnownTypesDictionary je potomek třídy  Dictionary&lt;string, object&gt;.
Do takového objektu Dictionary můžeme vložit kteroukoli instanci z třídy, která je
přímo či nepřimo potomkem třídy Object, ale při pokusu o serializaci dostaneme chybu,
protože naše potomky DataContractSerializer nezná a očekává, že v kolekci budou jen
instance třídy Object, a ne instance odvozených tříd. Pomocí atributu <a href="http://msdn.microsoft.com/en-gb/library/system.runtime.serialization.knowntypeattribute.aspx">KnownType</a>,
který je aplikován na KnownTypesDictionary, můžeme DataContractSerializer informovat,
které všechny třídy má v objektu Dictionary očekávat. Jednou z  možností, jak
to udělat, je předat atributu KnownType název statické metody, která seznam “známých”
tříd vrací. 
</p>
        <p>
Dnes si ukážeme jednoduchou verzi třídy  <em>KnownTypesDictionary</em>, která
v metodě GetKnownTypes vrátí fixní seznam "známých” tříd. Příště si ukážeme, jak budou
“známé” třídy dohledány a registrovány  automaticky bez nutnosti vytvářet seznam
známých tříd vždy znovu a “natvrdo” v každé aplikaci. V dalších dílech také zjistíme,
jak právě vytvořená infrastruktura nám dovolí vytvářet WP7 aplikace příslovečným lusknutím
prstu, tedy spíš nečetným lusknutím prstů o klávesnici. <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/8b4a80e9bf58_926F/wlEmoticon-smile_2.png" /><script src="https://gist.github.com/763469.js"></script></p>
        <p>
.
</p>
        <p>
 
</p>
        <p>
Předcházející články: 
</p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx">Tipy
pro Windows Phone 7 aplikace I</a>
        </p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx">Tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”</a>
        </p>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=38539832-2f1d-42cf-8549-b59697b093c4" />
      </body>
      <title>Tipy pro Windows Phone 7 aplikace III&amp;ndash;propojen&amp;iacute; view modelu s view (str&amp;aacute;nkou)</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,38539832-2f1d-42cf-8549-b59697b093c4.aspx</guid>
      <link>http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+IIIndashpropojeniacute+View+Modelu+S+View+Straacutenkou.aspx</link>
      <pubDate>Mon, 03 Jan 2011 14:46:50 GMT</pubDate>
      <description>&lt;p&gt;
&lt;em&gt;&lt;font color="#ff0000"&gt;Update 4. 1.&amp;nbsp;&amp;nbsp; 2011&amp;nbsp; - upraven kód objektu
UIHelper a spolupracující metody tak, aby byl klíč generovaný pro tranzientní stav
každého view modelu skutečně unikátní.&lt;/font&gt;&lt;/em&gt; &lt;font color="#ff0000"&gt;Když rozkliknete
GISTy, můžete se podívat i na původní verzi kódu.&lt;/font&gt; 
&lt;p&gt;
V &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;předchozím
článku&lt;/a&gt; jsme se podrobně věnovali vytvoření bázové třídy pro view modely včetně
podpory ukládání tranzientního stavu během “tombstoningu” a na konci jsem slíbil,
že další díl bude věnován hlavně propojení našich view modelů s view. 
&lt;p&gt;
View pro nás bude hostitel view modelu a v souladu s WP7 modelem navigace mezi jednotlivými
stránkami budeme za hlavního hostitele považovat potomka třídy &lt;em&gt;PhoneApplicationPage&lt;strong&gt;. &lt;/strong&gt;&lt;/em&gt;Uvidíme
ale, že při vytváření View nejsme omezeni na potomky &lt;em&gt;PhoneApplicationPage, &lt;/em&gt;protože
budeme schopni vytvořit i view jako potomka třídy &lt;em&gt;UserControl.&lt;/em&gt; 
&lt;p&gt;
Zrekapitujme hlavní funkce, které by měl náš hostitel view modelů zvládat: 
&lt;ol&gt;
&lt;li&gt;
Při vytvoření stránky je třeba najít ke stránce přidružený view model. Dodejme již
nyní, že povinností hostitele bude dohledat i vnořené (dceřiné) view modely, jestliže
je jedna stránka složena z více nezávislých view a každé view může být asociováno
s jiným view modelem.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Při vytvoření stránky je nutné u view modelu volat metodu &lt;em&gt;Init&lt;/em&gt; pro základní
inicializaci view modelu, jestliže view model podporuje naše rozhraní &lt;em&gt;IInittialize&lt;strong&gt;. &lt;/strong&gt;&lt;/em&gt;Znovu
připomínám, co zaznělo v &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;minulém
článku&lt;/a&gt;, že si implementaci žádných rozhraní u view modelů nevynucujeme.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Jestliže se stránka stane poprvé nebo po návratu uživatele “aktivní” (zobrazenou),
je nutné volat na view modelu metodu &lt;em&gt;Activate&lt;/em&gt;, když view model podporuje
rozhraní &lt;em&gt;IActivated.&lt;br&gt;
&lt;br&gt;
&lt;/em&gt;. 
&lt;li&gt;
Jestliže uživatel ze stránky odchází, hostitel na view modelu volá metodu Deactivate
z rozhraní IDeactivated.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Hostitel musí být schopen při “tombstoningu” uložit tranzientní stav view modelu.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Po návratu z “tombstoningu” hostitel dovolí view modelu obnovit tranzientní stav.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
&lt;strong&gt;Hostitel se nás bude snažit ve view modelech odstínit od všech&amp;nbsp; WP7 nedomyšleností,
záludností, nesmyslných omezení a programátorských vrtochů, které jsou nedílnou a
z pohledu mobilní MS divize jistě i zábavnou součástí celkově kapriciozního životního
cyklu třídy PhoneApplicationPage.&lt;br&gt;
&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Nyní již můžeme přístoupit k vytvoření hostitele. Našim hostitelem bude třída &lt;em&gt;PageBase, &lt;/em&gt;která
je potomkem PhoneApplicationPage z WP7 frameworku. Nakonec jsem pro účely článku zvolil
toto řešení, i když není problém v dalších dílech ukázat adaptér, který nás nutnosti
vlastní stránky v aplikaci odvozovat z bázové třídy &lt;em&gt;PageBase&lt;/em&gt; zbaví. Myslím
si ale, že navigační model WP7 aplikací neposkytuje sám o sobě mnoho prostoru pro
kreativitu, a proto nutnost dědit z PageBase místo třídy PhoneApplicationPage z WP7
za nějak zvlášť restriktivní nepovažuju.
&lt;/p&gt;
&lt;p&gt;
Třída PageBase:
&lt;/p&gt;
&lt;script src="https://gist.github.com/763320.js"&gt; &lt;/script&gt;
&lt;p&gt;
Kdykoli&amp;nbsp; dojde k aktivaci stránky, čímž míním první navigaci na stránku, nebo
návrat na stránku pomocí tlačítka Back, je volána metoda &lt;em&gt;OnNavigatedTo. &lt;/em&gt;My
jsme přepsali metodu OnNavigatedTo a v ní vždy nastavíme svou vlastnost WasLayoutUpdateCalled
na false. &lt;strong&gt;Vlastnost WasLayoutUpdateCalled použijeme za chvíli, zde jen řekněme,
že tuto vlastnost potřebujeme k tomu, abychom poznali, že již je vytvořen celý vizuální
strom ovládacích prvků a že můžeme s ovládacími prvky bez obav pracovat. &lt;/strong&gt;Bohužel
v metodě OnNavigatedTo vizuální strom prvků vytvořen být nemusí. O některých problémech,
které je nutné řešit, když není zcela vytvořen vizuální strom prvků, jsem již mluvil
u ovládacího prvku &lt;em&gt;WebBrowser &lt;/em&gt;v &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx"&gt;první
části tohoto seriálu&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Metoda OnNavigatedTo také dá příkaz k vyzvednutí dříve uloženého tranzientního stavu
pomocí metody loadSavedTransientState z vlastnosti PhoneApplicationPage.State. Tranzientní
stav, pokud existuje, je pouze uložen do vlastnosti LastSavedTransientState a zatím
se s ním nijak nepracuje. Klíčem, pod kterým je uložen stav celé stránky včetně tranzientního
stavu view modelů, je plně kvalifikované jméno aktuální stránky (string stateKey =
GetType().FullName). &lt;strong&gt;Měli bychom si být vědomi, že při této implementaci nesmíme
mít jednu stránku v aplikaci nahranou vícekrát, protože by různé instance stejné stránky
mezi sebou sdílely stav. Když budete trvat na tom, že jedna stránka může mít v systému
několik instancí, není problém změnit generování klíče, pod kterým bude stav pro každou
unikátně identifikovanou instanci uložen.&lt;/strong&gt;
&lt;/p&gt;
&lt;script src="https://gist.github.com/763335.js"&gt; &lt;/script&gt;
&lt;p&gt;
Pokračujme v našem scénáři. V konstruktoru si přihlašujeme odběr události LayoutUpdated
(&lt;em&gt;LayoutUpdated += PageBase_LayoutUpdated;)&lt;strong&gt;, &lt;/strong&gt;&lt;/em&gt;abychom byli
notifikováni, že již můžeme bezpečně pracovat s ovládacími prvky.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Obslužná metoda &lt;em&gt;handleLayoutUpdated&lt;/em&gt; je po každé navigaci na stránku spouštěna&amp;nbsp;
jen jednou, a proto se podíváme na hodnotu vlastnosti&amp;nbsp; WasLayoutUpdateCalled
– jestliže má hodnotu true, nic dalšího neděláme. &lt;strong&gt;Jinak metoda zkontroluje,
zda instance PageBase je nově vytvořena, k čemuž dojde při první navigaci na stránku
a také po obnovení z “tombstonovaného" stavu. Jinak řečeno – když je volán konstruktor
třídy PageBase, znamená to, že máme stránku v “panenském” stavu, protože v ní nejsou
žádná data a dokonce ani nebyly připojeny view modely. A proto bezparametrický konstruktor
PageBase nastavuje vlastnost IsNewInstance na true, abychom v metodě &lt;em&gt;handleLayoutUpdated&lt;/em&gt;&amp;nbsp;
věděli, že máme co do činění s novou instancí stránky. U nové stránky je třeba získat
view modely, a pokud je stránka obnovena po “tombstoningu”, je třeba do view modelů
nahrát tranzientní stav.&amp;nbsp; Při variantě “nová instance stránky” metoda &lt;em&gt;handleLayoutUpdated&lt;/em&gt; volá
metodu LoadState.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Jestliže nebyl volán konstruktor a stránka obsahuje veškerý stav, k čemuž většinou
dojde, když se vrátíme bez “tombstoningu” pomocí tlačítka Back na stránku, metoda &lt;em&gt;handleLayoutUpdated&lt;/em&gt; volá
pouze pomocnou metodu &lt;em&gt;handleAllActivated, &lt;/em&gt;která proiteruje všechny dříve
nahrané view modely, a když podporují rozhraní &lt;em&gt;IActivated&lt;/em&gt;, tak na nich zavolá
metodu &lt;em&gt;Activate&lt;/em&gt;.
&lt;/p&gt;
&lt;script src="https://gist.github.com/763340.js"&gt; &lt;/script&gt;
&lt;p&gt;
Metoda &lt;em&gt;LoadState&lt;/em&gt; ihned deleguje na metodu &lt;em&gt;restoreTransientState&lt;/em&gt;,
jíž předá v objektu ElementIndexPair odkaz na aktuální stránku (this), která představuje
“root” všech prvků, a relativní index nastavený na 0 (první prvek na této úrovni).
V dalším argumentu jako prvek, pro který má být obnoven stav, předá opět odkaz na
aktuální stránku (this) a poslední argument, ve kterém metoda &lt;em&gt;restoreTransientState&lt;/em&gt; očekává
naposledy použitý view model, je null, protože se žádnými view modely se ještě nepracuje.
&lt;/p&gt;
&lt;p&gt;
Metoda &lt;em&gt;restoreTransientState&lt;/em&gt; nejprve zkontroluje, jestli předaný ovládací
prvek představuje View. K tomu použije objekt podporující rozhraní IViewModelResolver,
který je uložen ve statické vlastnosti ViewModelManager. Přesněji řečeno, ve vlastnosti
ViewModelManager můžete uložit delegáta (&lt;em&gt;Func&lt;iviewmodelresolver&gt;
)
&lt;/em&gt;, který vrací objekt realizující rozhraní IViewModelResolver. Ve statickém konstruktoru
třídy PageBase ukládám do vlastnosti ViewModelManager funkci, která vytváří v mé aplikaci
výchozí IViewModelResolver s názvem ViewModelResolver (&lt;em&gt;ViewModelManager = () =&amp;gt;
new ViewModelResolver();)&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Rozhraní IViewModelResolver
&lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/763365.js"&gt; &lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Metodě IsView předáte vybraný objekt a ona vám vrátí true, jestliže objekt považuje
za view, pro které by měl existovat view model. Metoda ResolveViewModel přijme objekt
představující view a dohledá k němu view model.
&lt;/p&gt;
&lt;p&gt;
Pro lepší představu vám mohu bez podrobnějšího komentáře ukázat třídu, která v aplikaci
používající Posterous API dohledá k view view model na základě jmenné konvence. Za
View se považuje každá instance z třídy, jejíž název končí znaky “View”, a k tomuto
View je vrácen view model, který se jmenuje stejně jako view, ale končí znaky “ViewModel”.
K view s názvem Login&lt;em&gt;View &lt;/em&gt;je tedy vrácen view model s názvem Login&lt;em&gt;ViewModel.&lt;/em&gt;
&lt;/p&gt;
&lt;script src="https://gist.github.com/763375.js"&gt; &lt;/script&gt;
&lt;p&gt;
Vraťme se k metodě restoreTransientState. Když metoda zjistí, že objekt představuje
view, pokusí se dohledat dříve uložený tranzientní stav. Stav je uložen pro každé
view v objektu IDictionary, konkrétně v třídě KnownTypesDictionary, pod klíčem, kterým
je úplné jméno ovládacího prvku – úplným jménem se rozumí jméno třídy ovládacího prvku
+ jména tříd všech jeho vizuálních předků (&lt;em&gt;ancestors&lt;/em&gt;). Ke jménu třídy každého
prvku je přidán pořadový indexu prvku mezi prvky na stejné úrovni vizuálního stromu.
Klíč generuje třída UIHelper v metodě GetTransientStateKey.
&lt;/p&gt;
&lt;p&gt;
&lt;script src="https://gist.github.com/763381.js"&gt; &lt;/script&gt;
Metoda restoreTransientState se poté s s využitím metody prepareViewModel pokusí získat
přes ViewModelManager view model (&lt;em&gt;ViewModelManager().ResolveViewModel(obj&lt;/em&gt;),
dále zjistí, jestli view model podporuje rozhraní ITransientStateManager, IInitialize
a a IActivated a pokračuje takto:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Jestliže máme uložen tranzientní stav (došlo k “tombstoningu”) a view model podporuje
rozhraní ITransientStateManager, zavoláme metodu LoadState z rozhraní ITransientStateManager
(&lt;em&gt;stateManager.LoadState(LastSavedTransientState[stateKey]); &lt;/em&gt;a view model
tak dostane šanci načíst dříve uložená tranzientní data.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Když nemáme uložen tranzientní stav a view model podporuje rozhraní IInitialize, zavoláme
metodu IInitialize.Init. View model tak dostane šanci nahrát data, ať už se souboru,
z webové služby nebo jiného datového zdroje, která mají být zobrazena v aktuálním
view.&lt;br&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Poté, co view model obnoví nebo inicializuje svůj stav, je volána metoda activateAndSetDataContext,
která na view modelech podporujících rozhraní IActivated zavolá metodu Activate a
nastaví view model jako datový zdroj (“DataContext”) view.
&lt;/p&gt;
&lt;p&gt;
Nakonec pro všechny dceřiné prvky, které mohou představovat vnořená view (např. user
control), rekurzivně zavoláme opět metodu restoreTransientState. K získání dceřiných
prvků a jejich relativního indexu mezi prvky na stejné úrovni zanoření ve vizuálním
stromu je použita metoda UIHelper.GetChildren.
&lt;/p&gt;
&lt;script src="https://gist.github.com/763405.js"&gt; &lt;/script&gt;
&lt;p&gt;
Metoda LoadState, restoreTransientState a další pomocné metody, o kterých jsme mluvili
v předchozích odstavcích:
&lt;/p&gt;
&lt;script src="https://gist.github.com/763410.js"&gt; &lt;/script&gt;
&lt;p&gt;
Za povšimnutí stojí ve scénáři metody restoreTransientState ještě několik dalších
věcí:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Když zjišťujeme, jestli objekt podporuje rozhraní IInitialize (metoda &lt;em&gt;getInitObjectWithSyncContext&lt;/em&gt;),
ihned do view modelu zpropagujeme synchronizační kontext (&lt;em&gt;initObject.SynchContext
= SynchronizationContext.Current&lt;/em&gt;;), aby například událost PropertyChanged mohla
být vyvolávána vždy v UI vláknu.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Pomocná metoda &lt;em&gt;selectViewModel(frameworkElement, lastViewModel, currentViewModel);&lt;/em&gt; odpovědná
za výběr view modelu zajistí, že když IViewModelResolver nenalezne pro view žádný
view model, automaticky view přiřadí view model použitý u předchozího view. Kdy to
potřebujete? Třeba když stránku rozdělíte na několik nezávislých “user controls”,
tak se můžete rozhodnout, jestli bude mít každý user control (view) svůj view model,
nebo view model vytvoříte jen pro celou stránku a “user controls” view modely automaticky
“zdědí”. To byl jen jeden příklad - úroveň zanoření view je zcela ve vaší režii. Slovo
“zdědí” je v uvozovkách, protože nejde o klasické dědení DataContextu, ale k předání
posledně použitého view modelu dojde i tehdy, když dvě view nemají společné “nadview”.&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;em&gt;Poznámka: Nejprve jsem chtěl volání metod Init a LoadState na view modelech a
následné nastavení DataContextu u view dát do jiného vlákna. Problém je v tomto případě
s dědením view modelů. Když přiřadíte view model, na kterém jste zavolali asynchronně
metodu Init, dalšímu vnořenému View, tak se může stát, že metoda Init ještě nedoběhla,
view model u prvního view nastaven není, ale u vnořeného (druhého) view již nastaven
je, což může vést k podivným a kvůli použití více vláken obtížně reprodukovatelným
chybám. Za asynchronní zpracování časově náročných scénářů zodpovídají samotné view
modely, které by měly přepisovat virtuální metodu DoInternalAsyncInit z ViewModelBase.
Metodu DoInternalAsyncInit jsem &lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;popisoval
v předchozím článku&lt;/a&gt;.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Viděli jsme, kdy hostitel volá metody Init, Activate a kdy voláním metody LoadState
obnoví tranzientní stav ve view modelech. Ještě nám zbývá projít, kdy ukládáme tranzientní
stav a kdy notifikujeme view modely voláním jejich metody Deactivate o tom, že k nim
přidružené view (stránka) není již aktivní.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Nebudeme při ukládání tranzientního stavu nijak pátrat, jestli došlo k “tombstoningu”,
ale stav view modelů do &lt;em&gt;PhoneApplicationPage.State&lt;/em&gt; uložíme vždy, když dojde
k opuštění stránky. Hlavním důsledkem tohoto rozhodnutí je, že s obsluhou metod&amp;nbsp;
Application_Launching, Application_Activated, Application_Deactivated a Application_Closing,
kterou jsem popisoval minule, se nemusíte kvůli “tombstoningu” trápit a zmíněné metody
můžete většinou zcela ignorovat.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
O opuštění stránky jsm informováni v metodě OnNavigatedFrom, kterou přepíšeme. Metoda
OnNavigatedFrom voláním metody SaveState uloží stav všech view modelů a poté metoda
handleAllDeactivated na všech modelech&amp;nbsp; podporujících rozhraní IDeactivated zavolá
metodu Deactivate.
&lt;/p&gt;
&lt;script src="https://gist.github.com/763441.js"&gt; &lt;/script&gt;
&lt;p&gt;
Popisovat kompletně logiku v metodě SaveState nemá smysl, protože tato metoda je reverzní
k metodě LoadState. Pro všechny view rekurzivně vyhledá jejich view modely a dovolí
jim uložit pod unikátním klíčem view, který je vygenerován třídou UIHelper, tranzientní
stav. Ten samý tranzientní stav view modelů, jehož obnovení v metodě LoadState jsem
popisoval výše.&amp;nbsp; &lt;script src="https://gist.github.com/763445.js"&gt; &lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
Za komentář stojí, že podmínka if&lt;em&gt; (stateManager != null &amp;amp;&amp;amp; stateManager
!= lastDataContext) &lt;/em&gt;ošetřuje, abychom neukládali trazientní stav view modelu,
který slouží jako DataContext u více View, opakovaně, ale vždy pouze jednou.
&lt;/p&gt;
&lt;p&gt;
Tranzientní stav všech view modelů je ukládán do speciálního objektu Dictionary s
názvem KnownTypesDictionary.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;var statebag = new KnownTypesDictionary();&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Připomínám, že při tombstoningu je možné uložit jen serializovatelné objekty. Představme
si nyní, že KnownTypesDictionary je potomek třídy&amp;nbsp; Dictionary&amp;lt;string, object&amp;gt;.
Do takového objektu Dictionary můžeme vložit kteroukoli instanci z třídy, která je
přímo či nepřimo potomkem třídy Object, ale při pokusu o serializaci dostaneme chybu,
protože naše potomky DataContractSerializer nezná a očekává, že v kolekci budou jen
instance třídy Object, a ne instance odvozených tříd. Pomocí atributu &lt;a href="http://msdn.microsoft.com/en-gb/library/system.runtime.serialization.knowntypeattribute.aspx"&gt;KnownType&lt;/a&gt;,
který je aplikován na KnownTypesDictionary, můžeme DataContractSerializer informovat,
které všechny třídy má v objektu Dictionary očekávat. Jednou z&amp;nbsp; možností, jak
to udělat, je předat atributu KnownType název statické metody, která seznam “známých”
tříd vrací. 
&lt;/p&gt;
&lt;p&gt;
Dnes si ukážeme jednoduchou verzi třídy&amp;nbsp; &lt;em&gt;KnownTypesDictionary&lt;/em&gt;, která
v metodě GetKnownTypes vrátí fixní seznam "známých” tříd. Příště si ukážeme, jak budou
“známé” třídy dohledány a registrovány&amp;nbsp; automaticky bez nutnosti vytvářet seznam
známých tříd vždy znovu a “natvrdo” v každé aplikaci. V dalších dílech také zjistíme,
jak právě vytvořená infrastruktura nám dovolí vytvářet WP7 aplikace příslovečným lusknutím
prstu, tedy spíš nečetným lusknutím prstů o klávesnici. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/8b4a80e9bf58_926F/wlEmoticon-smile_2.png"&gt; &lt;script src="https://gist.github.com/763469.js"&gt; &lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;
.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Předcházející články: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx"&gt;Tipy
pro Windows Phone 7 aplikace I&lt;/a&gt; 
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx"&gt;Tipy
pro Windows Phone 7 aplikace II – podpora životního cyklu aplikace (včetně tombstoningu)
ve "view modelech”&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=38539832-2f1d-42cf-8549-b59697b093c4" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,38539832-2f1d-42cf-8549-b59697b093c4.aspx</comments>
      <category>Compact .Net Framework</category>
      <category>Návrhové vzory</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=060fbd09-0368-4733-92ad-aaecf48409a4</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,060fbd09-0368-4733-92ad-aaecf48409a4.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,060fbd09-0368-4733-92ad-aaecf48409a4.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=060fbd09-0368-4733-92ad-aaecf48409a4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
Již v <a href="http://Tipy pro Windows Phone 7 aplikace I">prvním dílu seriálu o vývoji
WP7 aplikací</a> jsem zmiňoval nejen to, že mobilní verze Silverlightu ve WP7 je založena
na Silverlightu 3, ale také, že mobilní Silverlight má své unikátní rysy, které v
žádné desktopové verzi Silverlightu nenalezneme. Jednou ze změn je životní cyklus
aplikace, včetně tzv. tombstoningu. Termín ”tombstoning”, kterého se i  v tomto
článku budu držet, abych nemusel zavádět nějaké směšně znějící české ekvivalenty,
má asi naznačovat, že WP7 podporují nejen tradiční spuštění a ukončení aplikace, ale
i jakýsi hybridní stav, v němž instance naší aplikace může být dočasně ukončena (“umrtvena”)
například tím, že uživatel spustí jinou aplikaci, a poté může být z hlediska uživatele
WP7 telefonu naše původní aplikace navrácena k životu,  a to dokonce ve stavu,
v jakém ji předtím uživatel zanechal. O smysluplnosti “tombstoningu” mám své pochybnosti
a raději bych ve WP7 viděl tradiční multitasking, ale vývojářův boj s chováním “zombie”
aplikací ve stavu “tombstoningu” má také něco do sebe. V tomto článku bych rád posunul
boj se “zombie-tombstonovanými” aplikacemi do dalšího levelu a nabídnul pár “cheatů”
.<img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-II_A042/wlEmoticon-smile_2.png" /></p>
        <p>
Přechody mezi stavy WP7 aplikace nám nejlépe objasní  metody pro obsluhu životního
cyklu aplikace, které jsou po založení projektu automaticky vygenerovány v souboru
App.xaml.cs.
</p>
        <script src="https://gist.github.com/744872.js">
        </script>
        <p>
Metoda  <em>Application_Launching </em>je  provedena jednou po spuštění
aplikace. Jde o metodu, ve které můžete načíst dříve uložená data z “isolated storage”. 
Tato metoda NENÍ volána při  obnovení “tombstonované” aplikace.
</p>
        <p>
Metoda <em>Application_Closing </em>je provedena jednou při ukončení aplikace. Jde
o metodu, ve které typicky uložíte data do “isolated storage”. Jde o stejná data,
která  načtete při dalším spuštění aplikace v již popsané metodě <em>Application_Launching </em>a
můžeme tedy říci, že jde o data s delší záruční lhůtou<em>, </em>která mají význam
pro různé instance aplikace. Když stáhnete z webové služby nějaké číselníky (typy
zákazníků, kategorie objednávek) a nechcete je po startu aplikace stahovat vždy znovu,
uložíte si je a při příštím spuštění aplikace rychleji naběhne, protože nemusí stahovat
všechna data z webových služeb ihned po startu.
</p>
        <p>
Další metody se týkají již tombstoningu. Metoda <em>Application_Deactivated</em> je
volána vždy, když je vaše aplikace “tombstonována” a v této metodě byste měli uložit
všechna data, která potřebujete k tomu, abyste mohli po návratu z “tombstonovaného”
stavu aplikaci zobrazit uživateli tak, jako kdyby běžela celou dobu a k žádnému “tombstoningu”
nedošlo. Pro vývojáře ale “tombstoning” ve skutečnosti znamená, že aktuálně běžící
instance aplikace je zlikvidována! Můžeme tedy říci, že v této metodě hlavně ukládáme
data s kratší záruční lhůtou, která mají význam jen pro další instanci aplikace po
návratu z “tombstonovaného” stavu. Data, která chcete mít k dispozici i po obnovení
z “tombstoningu” můžete ukládat pod vámi zvolenými identifikátory v objektu typu IDictionary
ve vlastnosti PhoneApplicationService.Current.State. <strong>Data, která zde uložíte,
musí být serializovatelná, protože se nedrží jen v paměti telefonu, ale jsou ukládána
i do souboru.</strong></p>
        <p>
Je ale nutné si uvědomit, že když je aplikace “tombstonována”, nemáte garantováno,
že se uživatel do vaší aplikace vrátí a že budete obnoveni z “tombstonovaného” stavu.
I v této metodě je proto vhodné ukládat data, která ukládáte v metodě <em>Application_Closing </em>popsané
výše. 
</p>
        <p>
Uživatel může také spustit vaší aplikaci znovu, tedy spustit novou instanci aplikace,
aniž by se vrátil k dříve “"tombstonované” aplikaci a vy svůj stav - data, o nichž
jsem říkal, že mají kratší záruční lhůtu - dříve uložený v metodě <em>Application_Deactivated </em>nikdy
nepoužijete. Když se uživatel vrátí do vaší aplikace, což většinou nastane po stisknutí
tlačítko “Back”, kdy se v zásobníku dříve spuštěných aplikací, který je spravován
přímé operačním systémem, stane aktivním vaše aplikace, musíte obnovit dříve uložený
stav v metodě <em>Application_Activated</em>. Napsal jsem, že jde o zásobník aplikací,
ale je potřeba si uvědomit, že jde spíš o metaforu, protože aplikace a jejich stránky
nejsou nikdy fyzicky uloženy, ale při “tombstoningu” většinou bez milosti zlikvidovány,
a metoda <em>Application_Activated </em>je volána v nové instanci naší aplikace. WP7
si jen v zásobníku pamatují, jaké aplikace a v jakém pořadí byly  spuštěny a
která stránka v konkrétní aplikaci byla aktivní. 
</p>
        <p>
Dále je potřeba si osvojit tato pravidla:
</p>
        <ul>
          <li>
Metoda <em>Application_Activated </em><strong>NENÍ</strong> volána po spuštění nové
(“netombstonované”) instance aplikace. Po spuštění nové (“netombstonované”) instance
aplikace je volána pouze metoda <em>Application_Launching.<br /></em></li>
          <li>
Metoda <em>Application_Deactivated</em><strong>NENÍ</strong> volána při  úplném
ukončení aplikace. Při  úplném ukončení aplikace je volána pouze metoda <em><em>Application_Closing</em>.</em></li>
        </ul>
        <p>
Zjednodušeně bychom mohli odpovědnosti metod v souboru App.xaml.cs popsat tímto fragmentem
kódu:
</p>
        <script src="https://gist.github.com/744916.js">
        </script>
        <p>
Měli bychom ale vědět, že k tombstoningu může dojít kdykoli a podle mých testů na
emulátoru i reálném zařízení může být aplikace “tombstonována”, i když se zrovna obnovuje
z předchozího “tombstonovaného” stavu a je v metodě “<em>Application_Activated“.  </em>Autoři
WP7 se s “tombstoningem” moc nepatlají a bez skrupulí po určité době zlikvidují vlákna
aplikace, což poznáte podle výjimky <em>ThreadAbortException.</em></p>
        <p>
Také se mi nelíbí, že bych měl v tomto jediném souboru ukládat a obnovovat data pro
všechny stránky (“formuláře”) aplikace. Rozhodl jsem se, že na obsluhu těchto metod
rezignuju a místo životní cyklu aplikace se budu zajímat jen o životní cyklus view
modelu (presentation modelu, chcete-li) u každé stránky ve WP7 aplikaci.
</p>
        <p>
Dnes si ukážeme bázovou třídu pro view modely a další podpůrné třídy se službami,
která nás svou spoluprací zbaví nutnosti při psaní každé stránky myslet na to, že
autoři WP7 aplikací se vyžívají v recidivě nekrofilního chování u WP7 aplikací. Drahý
bratr Sigmund Freud by se po prohlídce stavového automatu “tombstonované“ aplikace
od architektů WP7 na své pohovce jistě tetelil radostí nad předaným šokujícím materiálem. <img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-II_A042/wlEmoticon-smile_2.png" /></p>
        <p>
Nejdříve si ale navrhneme minimální množinu vlastností, kterou by měl každý view model
splňovat, abychom se již nemuseli životním cyklem WP7 aplikace příliš zabývat při
návrhu každé stránky.
</p>
        <ol>
          <li>
Musíme být schopni nahrát data při vytvoření nového view modulu. Také bychom měli
zajistit, že když dojde k “tombstoningu” aplikace ještě před získáním všech dat, nezůstane
view model v nějakém nekonzistentním stavu s třetinou nahraných dat, ale po obnovení
z “tombstoningu” dostane šanci nahrát data znovu. 
<br /><br /><script src="https://gist.github.com/744974.js"></script></li>
          <li>
Budeme schopni při “tombstoningu” automaticky perzistovat dočasný stav každého view
modelu. Od této chvíle začneme říkat dočasnému stavu stav tranzientní.<em> V tomto
článku se zabývám jen tranzientním stavem aplikace, o perzistování “trvanlivějších”
dat do “isolated storage” se pobavíme v některém z dalších článků.</em><br /></li>
          <li>
Po obnovení aplikace z “tombstonovaného” stavu každý view model automaticky nahraje
svůj tranzientní stav.<br />
Pro uložení a nahrání tranzientního stavu nadefinujeme rozhrani ITransientStateManager.<br /><br /><script src="https://gist.github.com/744980.js"></script></li>
          <li>
Měli bychom dát šanci view modelům zareagovat na to, že stránka, ke které jsou přidruženy,
se stala aktivní stránkou, i na to, že k nim přidružená stránka aktivní už není, ať
už proto, že došlo k “tombstoningu” nebo uživatel přešel na jinou stránku v aplikaci.<br />
Pro tyto účely máme rozhraní IActivated a IDeactivated.<br /><br /><script src="https://gist.github.com/744991.js"></script></li>
          <li>
Budeme mít sice bázovou třídu pro view modely, ale její použití si nebudeme vynucovat.
View model může být v aplikaci kterákoli třída. I když tato třída nebude potomkem
bázové třídy pro view modely, bude moci volitelně využít většinu služeb, které jsou
popsány v přechozích bodech.<br /><br /></li>
          <li>
Jedná se o view modely, měli bychom tedy na úrovní bázové třídy podporovat rozhraní
INotifyPropertyChanged, které nám dovoluje notifikovat o změně hodnoty ve vlastnostech
view modelu. Rozhraní INotifyPropertyChanged je ve WPF i v Silverlight aplikacích
všudypřítomné, proto si navrhneme další bázovou třídu PropertyChangedBase, která nám
kromě implementace rozhraní INotifyPropertyChanged přinese další užitečné služby.<br /><script src="https://gist.github.com/745001.js"></script></li>
        </ol>
        <p>
 
</p>
        <p>
Jaké další užitečné služby má třída PropertyChangedBase?
</p>
        <p>
Nemusíme vyvolávat událost PropertyChanged zadáním jen zadáním názvu vlastnosti (<em>RaisePropertyChanged(“UserName”)</em>),
což může vést k chybě za běhu aplikace, když uděláme překlep v názvu vlastnosti (<em>(RaisePropertyChanged(“UseName”)</em>),
ale můžeme předat název vlastnosti ve formě lambda výrazu, jehož syntaxe je zkontrolována
již kompilátorem. K tomu nám slouží metoda <em>RaisePropertyChangedEvent<treturn>
(Expression<func><treturn>
&gt; propertyDefinition)
</treturn></func></treturn></em>. Potomci třídy PropertyChangedBase mohou o změně hodnoty vlastnosti
informovat takto:
</p>
        <script src="https://gist.github.com/745018.js">
        </script>
        <p>
U potomků třídy PropertyChangedBase, kterými budou i naše view modely, si můžeme také
zavoláním metody <em>RaiseAllPropertiesChanged</em> vynutit vyvolání události o změně
hodnoty pro každou vlastnost. Další metodě s názvem <em>RaisePropertiesChanged(params
string[] properties) </em>můžeme předat názvy vlastností, pro které má být vyvolána
metoda PropertyChanged.
</p>
        <p>
A teď si  již můžeme vytvořit slibovanou třídu ViewModelBase, která je potomkem
třídy PropertyChangedBase a podporuje všechna rozhraní zmíněná dříve.
</p>
        <script src="https://gist.github.com/745046.js">
        </script>
        <p>
 
</p>
        <p>
V konstruktoru třída ViewModelBase přijímá titulek zobrazované stránky, který je uložen
do vlastnosti PageTitle.
</p>
        <script src="https://gist.github.com/745079.js">
        </script>
        <p>
Metoda Init z rozhraní Initialize by měla být volána vždy, když je view model vytvořen,
nebo když je po obnovení aplikace z “tombstonovaného” stavu zřejmé, že view model
nenahrál všechna data, což se zjistí voláním virtuální metody <em>IsAllInitDataLoaded</em>,
která v této abstraktní třídě vždy  vrací true a čeká na to, až odvozené konkrétní
view modely dosadí svou logiku, kdy je považován view model za nahraný. Metoda Init
by měla být taky volána, když odvozený view model obnovená tranzientní data považuje
za špatná / zastaralá a nemůže je používat, což nám dá najevo nastavením vlastnosti <em>IsInvalidModel</em> na
true. K rychlému zjištění, jestli  je možné view model dále používat slouží derivovaná
vlastnost <em>CanUseModel</em>, která spojuje logiku obsaženou ve vlastnosti <em>IsInvalidModel</em> a
metodě <em>IsAllInitDataLoaded.</em></p>
        <script src="https://gist.github.com/745094.js">
        </script>
        <p>
 
</p>
        <p>
Metoda <em>Initialize.Init</em></p>
        <script src="https://gist.github.com/745104.js">
        </script>
        <p>
V metodě <em>Init</em> nejdříve nastavíme vlastnost <em>IsInvalidModel</em> na true,
protože naše metoda <em>Init</em> probíhá a kdyby došlo k “tombstoningu”, nemáme všechna
data a je potřeba volat metodu <em>Init</em> znovu. Poté jen načteme titulek aplikace
do vlastnosti <em>AppTitle</em>,  inicializujeme vlastnost <em>SuppressValidating</em>,
která slouží k dočasnému potlačení ověřování platnosti data zadaných uživatelem ve
view modelu, na hodnotu false. <em>O vlastnosti SuppressValidating budeme více mluvit
v dalším článku včetně vysvětlení významu metody ValidateData a vlastnosti HasValidData. 
<br /></em></p>
        <p>
Dále <em>ViewModelBase</em> nastavením vlastnosti <em>IsInvalidModel</em> na false
sděluje, že jeho inicializace proběhla, všechna data v modelu považuje za platná a
dá šanci odvozeným třídám, aby inicializovaly svá data voláním chráněné virtuální
metody <em>DoInternalInit</em>, která má ve <em>ViewModelBase</em> prázdnou implementaci
a do které odvozené třídy dají svou specifickou logiku pro načtení dat. Vlastnost <em>IsInvalidModel</em> mohou
samozřejmě odvozené třídy nastavit v metodě <em>DoInternalInit</em> opět na true,
ale my ve vlastnosti <em>IsInvalidModel</em> hodnotu true nenecháváme, protože si
přepsání metody <em>DoInternalInit</em> v odvozených třídách nevynucujeme a v bázové
třídě ViewModelBase nemůžeme vědět, kdy odvozené třídy považují svá data za neplatná.
</p>
        <p>
V metodě <strong>Init </strong>nakonec také voláním metody další chráněné virtuální
metody s názvem <em>DoInternalAsyncInit</em> v <strong>samostatném vlákně </strong>šanci
odvozeným třídám <strong>asynchronně </strong>inicializovat svá data. Metodu <em>DoInternalAsyncInit</em> by
měly odvozené třídy používat k časově náročné inicializaci, kterou není vhodné vhodné
dávat do synchronně  volané metody DoInternalInit a blokovat tak hlavní thread
aplikace.
</p>
        <p>
Mohlo by vás také zaujmout, že v sekci catch má speciální zacházení výjimka <em>ThreadAbortException
– </em>tato výjimka není propagována výše, protože ji vyvolá samotné běhové prostředí
Silverlightu při násilném “tombstoningu”, jak jsem poznamenal na začátku tohoto článku.
</p>
        <p>
 
</p>
        <p>
Rozhraní <em>IActivated</em> s metodou <strong>Activate </strong>a<strong></strong>rozhraní<strong></strong><em>IDeactivated </em>s
metodou <strong>Deactivate</strong> ve <em>ViewModelBase</em> mají jen prázdnou implementaci
a čekají na to, jakou logiku do nich vloží odvozené třídy. Mimochodem  – na tomto
místě bychom měli poprvé vytušit, že budeme potřebovat “hostitele” našich view modelů,
který bude vědět, kdy volat metody <em>Activate</em>, <em>Deactivate</em>, <em>Init</em> a
další.<br /></p>
        <p>
Třída ViewModelBase explicitně implementuje rozhraní <em>ITransientStateManager</em>,
které jsme si zavedli pro podporu automatického ukládání a nahrávání tranzientního
stavu. Metody <em>LoadState</em> a <em>SaveState</em> ale po svém vyvolání jen předají
řízení chráněným virtuálním metodám <em>DoInternalLoadTransientState</em> a <em>DoInternalSaveTransientState, </em>aby
dali šanci i odvozeným třídám změnit způsob uložení a nahrání tranzientního stavu,
i když odvozené třídy jsou většinou spokojeni s tím, že to za ně zvládne předek ViewModelBase.
</p>
        <p>
 
</p>
        <script src="https://gist.github.com/745208.js">
        </script>
        <p>
Třída ViewModelBase ve svém statickém konstruktoru dosazuje výchozí objekt podporující
rozhraní <em>ITransientStateHelper</em>, které je klíčové pro uložení a obnovení tranzientního
stavu view modelů a na které delegují i metody <em>DoInternalLoadTransientState</em> 
a <em>DoInternalSaveTransientState</em> v předchozím výpisu.
</p>
        <p>
Všimněte si, že metoda <em>DoInternalLoadTransientState </em>po obnovení tranzientního
stavu zkontroluje, jestli se dá view model používat, a pokud ne, zavolá i v této fázi
metodu Init.
</p>
        <p>
          <em>if (!CanUseModel)<br />
{</em>
        </p>
        <p>
          <em>  Init();<br />
}</em>
        </p>
        <p>
A nyní se podíváme na mocné rozhraní <em>ITransientStateHelper</em></p>
        <strong>
        </strong>
        <script src="https://gist.github.com/745212.js">
        </script>
        <p>
Je asi zřejmé, že metoda <em>GetTransientState</em> vrátí v objektu Dictionary tranzientní
stav objektu, který jí byl předán v argumentu obj. Metoda <em>RestoreTransientState</em> naopak
obnoví tranzientní stav objektu v argumentu obj hodnotami v argumentu savedState.
</p>
        <p>
Metoda <em>IsTransientStateEnabledForObject</em> zjistí, jestli je možné z předaného
objektu získat tranzientní stav. Jak uvidíme, odvozené view modely mohou odmítnout
uložení tranzientního stavu a kdekoli v aplikaci  můžeme jejich rozhodnutí jednoduše
zjistit předáním instance view modelu této metodě.
</p>
        <p>
Zde je jedna z možných realizací rozhraní IStateTransientStateHelper, kterou používá
i naše třída ViewModelBase.
</p>
        <script src="https://gist.github.com/745247.js">
        </script>
        <p>
 
</p>
        <p>
Odpovědnosti metod <em>GetTransientState</em> a <em>RestoreTransientState</em> jsem
již popsal, nyní jen zmíním pár specialitek v kódu třídy TransientStateHelper.
</p>
        <p>
Metoda GetTransientState zjistí, jestli předaný objekt  má tranzientní stav tak,
že zavolá metodu <strong>IsTransientStateEnabledForObject(obj)<em>.</em></strong></p>
        <p>
Metoda IsTransientStateEnabledForObject kontroluje, jestli třída, ze které objekt
pochází, nezakázala vydání tranzientního stavu tím, že je na ní aplikován atribut
[NonTransientState].
</p>
        <p>
Atribut NonTransientState
</p>
        <script src="https://gist.github.com/745279.js">
        </script>
        <p>
Atribut NonTransientState může být aplikován nejen na celou třídu, ale i na jednotlivé
vlastnosti objektu, které nemají být součástí tranzientního stavu.  <strong>Metoda
GetTransientState neukládá celé view modely, ale s využitím reflexe jen hodnoty jejich
vlastností. Atribut NonTransientState dovoluje vyřadit vlastnosti, které v tranzientním
stavu view modelu nemají co dělat.</strong> To ale není vše – přímo metoda GetTransientState
dle jmenné konvence vyřadí všechny vlastnosti, jejichž suffix je v poli IGNORE_METHOD_SUFFIX_LIST 
</p>
        <p>
          <em>public static readonly IEnumerable<string>
IGNORE_METHOD_SUFFIX_LIST = new[] { "Command", "Action", "Helper", "Service", "SynchContext"};
</string></em>
        </p>
        <p>
Do tranzientního stavu se tak nedostanou ve view modelech se často nacházející, ale
s tranzientním stavem view modelu nic nemající a navíc většinou neserializovatelné
objekty jako jsou objekty ICommand (vlastnost Select<strong>Command</strong>, Save<strong>Command</strong>),
delegáti  TextboxTextChanged<strong>Action</strong>, služby (ILogger<strong>Service</strong>)
a další.
</p>
        <p>
Metoda <em>RestoreTransientState</em> obnoví tranzientní stav objektu. Za zmínku stojí,
že když je předaný objekt potomkem PropertyNotificationBase, tak nastavením vlastnosti
notificationBase.SuppressPropertyChangedNotification na true potlačíme dočasně vyvolání
události OnPropertyChanged, protože je vhodné, abychom událost nevyvolávali, když
view model neobsahuje všechna data a nevíme, kdo všechno na událost reaguje a jaká
další, nyní ve view modelu se nenacházející data, by chtěl načíst. Jak jsem ale psal
v požadavcích na začátku článku, view model nemusí podporovat žádná rozhraní, nemusí
být potomkem ViewModelBase ani PropertyNotificationBase, a proto si ani dědění z PropertyNotificationBase
v této metodě nevynucujeme. Poté, co metoda <em>RestoreTransientState </em>obnoví
hodnoty všech vlastností, má TransientStateHelper povinnost notifikovat okolí o změně
hodnot všech vlastností view modelu. Jestliže je objekt s obnoveným tranzientním stavem
potomkem PropertyNotificationBase, zavoláme metodu RaisePropertiesChanged(propertyNames.ToArray()),
jinak se metoda <em>RestoreTransientState</em> pokusí dohledat opět za pomoci reflexe
na objektu metodu nazvanou RaisePropertyChangedEvent, která přijímá název vlastnosti
a kterou použije pro hromadnou distribuci událostí OnPropertyChanged.
</p>
        <p>
Ovládací prvky obsažené (nejen) v control toolkitu jsou  přecitlivělé na pořadí
vyvolávání události, a proto jsou vlastnosti seřazeny nyní tak, aby vlastnosti začínající
slovem <em>Selected</em><strong></strong>vyvolávaly událost OnPropertyChanged jako
poslední. Máte-li ve view modelu kolekci nazvanou Orders (všechny objednávky) a SelectedOrder
(vybraná objednávka z této kolekce), je zaručeno, že <strong>událost OnPropertyChanged
pro vlastnost SelectedOrder bude vyvolána až po události OnPropertyChanged pro vlastnost
Orders.</strong></p>
        <p>
          <em>Prefixy vlastností, které mají vyvolávat události jako poslední, jsou v proměnné
LAST_SET_VALUE_METHOD_PREFIX. Tyto vlastnosti jsou označeny příznakem LastInit z enumerace
PropertyType.</em>
        </p>
        <p>
          <em>
          </em>
        </p>
        <p>
          <em>public static readonly IEnumerable<string>
LAST_SET_VALUE_METHOD_PREFIX = new[] { "Selected" };
</string></em>
        </p>
        <p>
To by pro dnešek k třídě ViewModelBase a jejím pomocníkům stačilo:
</p>
        <p>
Příště se podíváme hlavně na “hostitele” view modelů, který by měl být schopen:
</p>
        <ul>
          <li>
Volat na view modelech ve “správnou dobu” metody Init, LoadState, SaveState, Activate,
Deactivate. 
<br /></li>
          <li>
Připojit view modely k view (stránce).<br /></li>
          <li>
Náš hostitel bude podporovat i více view modelů na jedné stránce, včetně “dědění”
a sdílení použitých view modelů mezi různými view na stránce.</li>
        </ul>
        <p>
A také si příště vysvětlíme, proč při získání tranzientního stavu ve ViewModelbase
místo objektu Dictionary používáme vlastní třídu KnownTypesDictionary. Jak možná tušíte,
i název “KnownTypes” odkazuje k tomu, že mají-li být hodnoty uložené v tranzientním
stavu serializovatelné, tak <em>DataContractSerializer,</em> používaný infrastrukturou
WP7 k serializaci tranzientního stavu, musíme přesvědčit, že v objektu Dictionary
jsou jen objekty z jemu “známých” tříd.
</p>
        <p>
Předcházející články:
</p>
        <p>
          <a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx">Tipy
pro Windows Phone 7 aplikace I</a>
        </p>
        <img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=060fbd09-0368-4733-92ad-aaecf48409a4" />
      </body>
      <title>Tipy pro Windows Phone 7 aplikace II &amp;ndash; podpora životn&amp;iacute;ho cyklu aplikace (včetně tombstoningu) ve &amp;quot;view modelech&amp;rdquo;</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,060fbd09-0368-4733-92ad-aaecf48409a4.aspx</guid>
      <link>http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+II+Ndash+Podpora+%c5%bdivotniacuteho+Cyklu+Aplikace+V%c4%8detn%c4%9b+Tombstoningu+Ve+Quotview+Modelechrdquo.aspx</link>
      <pubDate>Fri, 17 Dec 2010 18:25:14 GMT</pubDate>
      <description>&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Již v &lt;a href="http://Tipy pro Windows Phone 7 aplikace I"&gt;prvním dílu seriálu o vývoji
WP7 aplikací&lt;/a&gt; jsem zmiňoval nejen to, že mobilní verze Silverlightu ve WP7 je založena
na Silverlightu 3, ale také, že mobilní Silverlight má své unikátní rysy, které v
žádné desktopové verzi Silverlightu nenalezneme. Jednou ze změn je životní cyklus
aplikace, včetně tzv. tombstoningu. Termín ”tombstoning”, kterého se i&amp;nbsp; v tomto
článku budu držet, abych nemusel zavádět nějaké směšně znějící české ekvivalenty,
má asi naznačovat, že WP7 podporují nejen tradiční spuštění a ukončení aplikace, ale
i jakýsi hybridní stav, v němž instance naší aplikace může být dočasně ukončena (“umrtvena”)
například tím, že uživatel spustí jinou aplikaci, a poté může být z hlediska uživatele
WP7 telefonu naše původní aplikace navrácena k životu,&amp;nbsp; a to dokonce ve stavu,
v jakém ji předtím uživatel zanechal. O smysluplnosti “tombstoningu” mám své pochybnosti
a raději bych ve WP7 viděl tradiční multitasking, ale vývojářův boj s chováním “zombie”
aplikací ve stavu “tombstoningu” má také něco do sebe. V tomto článku bych rád posunul
boj se “zombie-tombstonovanými” aplikacemi do dalšího levelu a nabídnul pár “cheatů”
.&lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-II_A042/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
Přechody mezi stavy WP7 aplikace nám nejlépe objasní&amp;nbsp; metody pro obsluhu životního
cyklu aplikace, které jsou po založení projektu automaticky vygenerovány v souboru
App.xaml.cs.
&lt;/p&gt;
&lt;script src="https://gist.github.com/744872.js"&gt; &lt;/script&gt;
&lt;p&gt;
Metoda&amp;nbsp; &lt;em&gt;Application_Launching &lt;/em&gt;je&amp;nbsp; provedena jednou po spuštění
aplikace. Jde o metodu, ve které můžete načíst dříve uložená data z “isolated storage”.&amp;nbsp;
Tato metoda NENÍ volána při&amp;nbsp; obnovení “tombstonované” aplikace.
&lt;/p&gt;
&lt;p&gt;
Metoda &lt;em&gt;Application_Closing &lt;/em&gt;je provedena jednou při ukončení aplikace. Jde
o metodu, ve které typicky uložíte data do “isolated storage”. Jde o stejná data,
která&amp;nbsp; načtete při dalším spuštění aplikace v již popsané metodě &lt;em&gt;Application_Launching &lt;/em&gt;a
můžeme tedy říci, že jde o data s delší záruční lhůtou&lt;em&gt;, &lt;/em&gt;která mají význam
pro různé instance aplikace. Když stáhnete z webové služby nějaké číselníky (typy
zákazníků, kategorie objednávek) a nechcete je po startu aplikace stahovat vždy znovu,
uložíte si je a při příštím spuštění aplikace rychleji naběhne, protože nemusí stahovat
všechna data z webových služeb ihned po startu.
&lt;/p&gt;
&lt;p&gt;
Další metody se týkají již tombstoningu. Metoda &lt;em&gt;Application_Deactivated&lt;/em&gt; je
volána vždy, když je vaše aplikace “tombstonována” a v této metodě byste měli uložit
všechna data, která potřebujete k tomu, abyste mohli po návratu z “tombstonovaného”
stavu aplikaci zobrazit uživateli tak, jako kdyby běžela celou dobu a k žádnému “tombstoningu”
nedošlo. Pro vývojáře ale “tombstoning” ve skutečnosti znamená, že aktuálně běžící
instance aplikace je zlikvidována! Můžeme tedy říci, že v této metodě hlavně ukládáme
data s kratší záruční lhůtou, která mají význam jen pro další instanci aplikace po
návratu z “tombstonovaného” stavu. Data, která chcete mít k dispozici i po obnovení
z “tombstoningu” můžete ukládat pod vámi zvolenými identifikátory v objektu typu IDictionary
ve vlastnosti PhoneApplicationService.Current.State. &lt;strong&gt;Data, která zde uložíte,
musí být serializovatelná, protože se nedrží jen v paměti telefonu, ale jsou ukládána
i do souboru.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Je ale nutné si uvědomit, že když je aplikace “tombstonována”, nemáte garantováno,
že se uživatel do vaší aplikace vrátí a že budete obnoveni z “tombstonovaného” stavu.
I v této metodě je proto vhodné ukládat data, která ukládáte v metodě &lt;em&gt;Application_Closing &lt;/em&gt;popsané
výše. 
&lt;/p&gt;
&lt;p&gt;
Uživatel může také spustit vaší aplikaci znovu, tedy spustit novou instanci aplikace,
aniž by se vrátil k dříve “"tombstonované” aplikaci a vy svůj stav - data, o nichž
jsem říkal, že mají kratší záruční lhůtu - dříve uložený v metodě &lt;em&gt;Application_Deactivated &lt;/em&gt;nikdy
nepoužijete. Když se uživatel vrátí do vaší aplikace, což většinou nastane po stisknutí
tlačítko “Back”, kdy se v zásobníku dříve spuštěných aplikací, který je spravován
přímé operačním systémem, stane aktivním vaše aplikace, musíte obnovit dříve uložený
stav v metodě &lt;em&gt;Application_Activated&lt;/em&gt;. Napsal jsem, že jde o zásobník aplikací,
ale je potřeba si uvědomit, že jde spíš o metaforu, protože aplikace a jejich stránky
nejsou nikdy fyzicky uloženy, ale při “tombstoningu” většinou bez milosti zlikvidovány,
a metoda &lt;em&gt;Application_Activated &lt;/em&gt;je volána v nové instanci naší aplikace. WP7
si jen v zásobníku pamatují, jaké aplikace a v jakém pořadí byly&amp;nbsp; spuštěny a
která stránka v konkrétní aplikaci byla aktivní. 
&lt;/p&gt;
&lt;p&gt;
Dále je potřeba si osvojit tato pravidla:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Metoda &lt;em&gt;Application_Activated &lt;/em&gt;&lt;strong&gt;NENÍ&lt;/strong&gt; volána po spuštění nové
(“netombstonované”) instance aplikace. Po spuštění nové (“netombstonované”) instance
aplikace je volána pouze metoda &lt;em&gt;Application_Launching.&lt;br&gt;
&lt;/em&gt; 
&lt;li&gt;
Metoda &lt;em&gt;Application_Deactivated&lt;/em&gt; &lt;strong&gt;NENÍ&lt;/strong&gt; volána při&amp;nbsp; úplném
ukončení aplikace. Při&amp;nbsp; úplném ukončení aplikace je volána pouze metoda &lt;em&gt;&lt;em&gt;Application_Closing&lt;/em&gt;.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Zjednodušeně bychom mohli odpovědnosti metod v souboru App.xaml.cs popsat tímto fragmentem
kódu:
&lt;/p&gt;
&lt;script src="https://gist.github.com/744916.js"&gt; &lt;/script&gt;
&lt;p&gt;
Měli bychom ale vědět, že k tombstoningu může dojít kdykoli a podle mých testů na
emulátoru i reálném zařízení může být aplikace “tombstonována”, i když se zrovna obnovuje
z předchozího “tombstonovaného” stavu a je v metodě “&lt;em&gt;Application_Activated“.&amp;nbsp; &lt;/em&gt;Autoři
WP7 se s “tombstoningem” moc nepatlají a bez skrupulí po určité době zlikvidují vlákna
aplikace, což poznáte podle výjimky &lt;em&gt;ThreadAbortException.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Také se mi nelíbí, že bych měl v tomto jediném souboru ukládat a obnovovat data pro
všechny stránky (“formuláře”) aplikace. Rozhodl jsem se, že na obsluhu těchto metod
rezignuju a místo životní cyklu aplikace se budu zajímat jen o životní cyklus view
modelu (presentation modelu, chcete-li) u každé stránky ve WP7 aplikaci.
&lt;/p&gt;
&lt;p&gt;
Dnes si ukážeme bázovou třídu pro view modely a další podpůrné třídy se službami,
která nás svou spoluprací zbaví nutnosti při psaní každé stránky myslet na to, že
autoři WP7 aplikací se vyžívají v recidivě nekrofilního chování u WP7 aplikací. Drahý
bratr Sigmund Freud by se po prohlídce stavového automatu “tombstonované“ aplikace
od architektů WP7 na své pohovce jistě tetelil radostí nad předaným šokujícím materiálem. &lt;img style="border-bottom-style: none; border-right-style: none; border-top-style: none; border-left-style: none" class="wlEmoticon wlEmoticon-smile" alt="Smile" src="http://blog.renestein.net/content/binary/Windows-Live-Writer/Tipy-pro-Windows-Phone-7-aplikace-II_A042/wlEmoticon-smile_2.png"&gt;
&lt;/p&gt;
&lt;p&gt;
Nejdříve si ale navrhneme minimální množinu vlastností, kterou by měl každý view model
splňovat, abychom se již nemuseli životním cyklem WP7 aplikace příliš zabývat při
návrhu každé stránky.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Musíme být schopni nahrát data při vytvoření nového view modulu. Také bychom měli
zajistit, že když dojde k “tombstoningu” aplikace ještě před získáním všech dat, nezůstane
view model v nějakém nekonzistentním stavu s třetinou nahraných dat, ale po obnovení
z “tombstoningu” dostane šanci nahrát data znovu. 
&lt;br&gt;
&lt;br&gt;
&lt;script src="https://gist.github.com/744974.js"&gt; &lt;/script&gt;
&lt;li&gt;
Budeme schopni při “tombstoningu” automaticky perzistovat dočasný stav každého view
modelu. Od této chvíle začneme říkat dočasnému stavu stav tranzientní.&lt;em&gt; V tomto
článku se zabývám jen tranzientním stavem aplikace, o perzistování “trvanlivějších”
dat do “isolated storage” se pobavíme v některém z dalších článků.&lt;/em&gt;
&lt;br&gt;
&lt;li&gt;
Po obnovení aplikace z “tombstonovaného” stavu každý view model automaticky nahraje
svůj tranzientní stav.&lt;br&gt;
Pro uložení a nahrání tranzientního stavu nadefinujeme rozhrani ITransientStateManager.&lt;br&gt;
&lt;br&gt;
&lt;script src="https://gist.github.com/744980.js"&gt; &lt;/script&gt;
&lt;li&gt;
Měli bychom dát šanci view modelům zareagovat na to, že stránka, ke které jsou přidruženy,
se stala aktivní stránkou, i na to, že k nim přidružená stránka aktivní už není, ať
už proto, že došlo k “tombstoningu” nebo uživatel přešel na jinou stránku v aplikaci.&lt;br&gt;
Pro tyto účely máme rozhraní IActivated a IDeactivated.&lt;br&gt;
&lt;br&gt;
&lt;script src="https://gist.github.com/744991.js"&gt; &lt;/script&gt;
&lt;li&gt;
Budeme mít sice bázovou třídu pro view modely, ale její použití si nebudeme vynucovat.
View model může být v aplikaci kterákoli třída. I když tato třída nebude potomkem
bázové třídy pro view modely, bude moci volitelně využít většinu služeb, které jsou
popsány v přechozích bodech.&lt;br&gt;
&lt;br&gt;
&lt;li&gt;
Jedná se o view modely, měli bychom tedy na úrovní bázové třídy podporovat rozhraní
INotifyPropertyChanged, které nám dovoluje notifikovat o změně hodnoty ve vlastnostech
view modelu. Rozhraní INotifyPropertyChanged je ve WPF i v Silverlight aplikacích
všudypřítomné, proto si navrhneme další bázovou třídu PropertyChangedBase, která nám
kromě implementace rozhraní INotifyPropertyChanged přinese další užitečné služby.&lt;br&gt;
&lt;script src="https://gist.github.com/745001.js"&gt; &lt;/script&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Jaké další užitečné služby má třída PropertyChangedBase?
&lt;/p&gt;
&lt;p&gt;
Nemusíme vyvolávat událost PropertyChanged zadáním jen zadáním názvu vlastnosti (&lt;em&gt;RaisePropertyChanged(“UserName”)&lt;/em&gt;),
což může vést k chybě za běhu aplikace, když uděláme překlep v názvu vlastnosti (&lt;em&gt;(RaisePropertyChanged(“UseName”)&lt;/em&gt;),
ale můžeme předat název vlastnosti ve formě lambda výrazu, jehož syntaxe je zkontrolována
již kompilátorem. K tomu nám slouží metoda &lt;em&gt;RaisePropertyChangedEvent&lt;treturn&gt;
(Expression&lt;func&gt;
&lt;treturn&gt;
&amp;gt; propertyDefinition)
&lt;/em&gt;. Potomci třídy PropertyChangedBase mohou o změně hodnoty vlastnosti informovat
takto:
&lt;/p&gt;
&lt;script src="https://gist.github.com/745018.js"&gt; &lt;/script&gt;
&lt;p&gt;
U potomků třídy PropertyChangedBase, kterými budou i naše view modely, si můžeme také
zavoláním metody &lt;em&gt;RaiseAllPropertiesChanged&lt;/em&gt; vynutit vyvolání události o změně
hodnoty pro každou vlastnost. Další metodě s názvem &lt;em&gt;RaisePropertiesChanged(params
string[] properties) &lt;/em&gt;můžeme předat názvy vlastností, pro které má být vyvolána
metoda PropertyChanged.
&lt;/p&gt;
&lt;p&gt;
A teď si&amp;nbsp; již můžeme vytvořit slibovanou třídu ViewModelBase, která je potomkem
třídy PropertyChangedBase a podporuje všechna rozhraní zmíněná dříve.
&lt;/p&gt;
&lt;script src="https://gist.github.com/745046.js"&gt; &lt;/script&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
V konstruktoru třída ViewModelBase přijímá titulek zobrazované stránky, který je uložen
do vlastnosti PageTitle.
&lt;/p&gt;
&lt;script src="https://gist.github.com/745079.js"&gt; &lt;/script&gt;
&lt;p&gt;
Metoda Init z rozhraní Initialize by měla být volána vždy, když je view model vytvořen,
nebo když je po obnovení aplikace z “tombstonovaného” stavu zřejmé, že view model
nenahrál všechna data, což se zjistí voláním virtuální metody &lt;em&gt;IsAllInitDataLoaded&lt;/em&gt;,
která v této abstraktní třídě vždy&amp;nbsp; vrací true a čeká na to, až odvozené konkrétní
view modely dosadí svou logiku, kdy je považován view model za nahraný. Metoda Init
by měla být taky volána, když odvozený view model obnovená tranzientní data považuje
za špatná / zastaralá a nemůže je používat, což nám dá najevo nastavením vlastnosti &lt;em&gt;IsInvalidModel&lt;/em&gt; na
true. K rychlému zjištění, jestli&amp;nbsp; je možné view model dále používat slouží derivovaná
vlastnost &lt;em&gt;CanUseModel&lt;/em&gt;, která spojuje logiku obsaženou ve vlastnosti &lt;em&gt;IsInvalidModel&lt;/em&gt; a
metodě &lt;em&gt;IsAllInitDataLoaded.&lt;/em&gt;
&lt;/p&gt;
&lt;script src="https://gist.github.com/745094.js"&gt; &lt;/script&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Metoda &lt;em&gt;Initialize.Init&lt;/em&gt; 
&lt;/p&gt;
&lt;script src="https://gist.github.com/745104.js"&gt; &lt;/script&gt;
&lt;p&gt;
V metodě &lt;em&gt;Init&lt;/em&gt; nejdříve nastavíme vlastnost &lt;em&gt;IsInvalidModel&lt;/em&gt; na true,
protože naše metoda &lt;em&gt;Init&lt;/em&gt; probíhá a kdyby došlo k “tombstoningu”, nemáme všechna
data a je potřeba volat metodu &lt;em&gt;Init&lt;/em&gt; znovu. Poté jen načteme titulek aplikace
do vlastnosti &lt;em&gt;AppTitle&lt;/em&gt;,&amp;nbsp; inicializujeme vlastnost &lt;em&gt;SuppressValidating&lt;/em&gt;,
která slouží k dočasnému potlačení ověřování platnosti data zadaných uživatelem ve
view modelu, na hodnotu false. &lt;em&gt;O vlastnosti SuppressValidating budeme více mluvit
v dalším článku včetně vysvětlení významu metody ValidateData a vlastnosti HasValidData. 
&lt;br&gt;
&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Dále &lt;em&gt;ViewModelBase&lt;/em&gt; nastavením vlastnosti &lt;em&gt;IsInvalidModel&lt;/em&gt; na false
sděluje, že jeho inicializace proběhla, všechna data v modelu považuje za platná a
dá šanci odvozeným třídám, aby inicializovaly svá data voláním chráněné virtuální
metody &lt;em&gt;DoInternalInit&lt;/em&gt;, která má ve &lt;em&gt;ViewModelBase&lt;/em&gt; prázdnou implementaci
a do které odvozené třídy dají svou specifickou logiku pro načtení dat. Vlastnost &lt;em&gt;IsInvalidModel&lt;/em&gt; mohou
samozřejmě odvozené třídy nastavit v metodě &lt;em&gt;DoInternalInit&lt;/em&gt; opět na true,
ale my ve vlastnosti &lt;em&gt;IsInvalidModel&lt;/em&gt; hodnotu true nenecháváme, protože si
přepsání metody &lt;em&gt;DoInternalInit&lt;/em&gt; v odvozených třídách nevynucujeme a v bázové
třídě ViewModelBase nemůžeme vědět, kdy odvozené třídy považují svá data za neplatná.
&lt;/p&gt;
&lt;p&gt;
V metodě &lt;strong&gt;Init &lt;/strong&gt;nakonec také voláním metody další chráněné virtuální
metody s názvem &lt;em&gt;DoInternalAsyncInit&lt;/em&gt; v &lt;strong&gt;samostatném vlákně &lt;/strong&gt;šanci
odvozeným třídám &lt;strong&gt;asynchronně &lt;/strong&gt;inicializovat svá data. Metodu &lt;em&gt;DoInternalAsyncInit&lt;/em&gt; by
měly odvozené třídy používat k časově náročné inicializaci, kterou není vhodné vhodné
dávat do synchronně&amp;nbsp; volané metody DoInternalInit a blokovat tak hlavní thread
aplikace.
&lt;/p&gt;
&lt;p&gt;
Mohlo by vás také zaujmout, že v sekci catch má speciální zacházení výjimka &lt;em&gt;ThreadAbortException
– &lt;/em&gt;tato výjimka není propagována výše, protože ji vyvolá samotné běhové prostředí
Silverlightu při násilném “tombstoningu”, jak jsem poznamenal na začátku tohoto článku.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Rozhraní &lt;em&gt;IActivated&lt;/em&gt; s metodou &lt;strong&gt;Activate &lt;/strong&gt;a&lt;strong&gt; &lt;/strong&gt;rozhraní&lt;strong&gt; &lt;/strong&gt;&lt;em&gt;IDeactivated &lt;/em&gt;s
metodou &lt;strong&gt;Deactivate&lt;/strong&gt; ve &lt;em&gt;ViewModelBase&lt;/em&gt; mají jen prázdnou implementaci
a čekají na to, jakou logiku do nich vloží odvozené třídy. Mimochodem&amp;nbsp; – na tomto
místě bychom měli poprvé vytušit, že budeme potřebovat “hostitele” našich view modelů,
který bude vědět, kdy volat metody &lt;em&gt;Activate&lt;/em&gt;, &lt;em&gt;Deactivate&lt;/em&gt;, &lt;em&gt;Init&lt;/em&gt; a
další.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
Třída ViewModelBase explicitně implementuje rozhraní &lt;em&gt;ITransientStateManager&lt;/em&gt;,
které jsme si zavedli pro podporu automatického ukládání a nahrávání tranzientního
stavu. Metody &lt;em&gt;LoadState&lt;/em&gt; a &lt;em&gt;SaveState&lt;/em&gt; ale po svém vyvolání jen předají
řízení chráněným virtuálním metodám &lt;em&gt;DoInternalLoadTransientState&lt;/em&gt; a &lt;em&gt;DoInternalSaveTransientState, &lt;/em&gt;aby
dali šanci i odvozeným třídám změnit způsob uložení a nahrání tranzientního stavu,
i když odvozené třídy jsou většinou spokojeni s tím, že to za ně zvládne předek ViewModelBase.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;script src="https://gist.github.com/745208.js"&gt; &lt;/script&gt;
&lt;p&gt;
Třída ViewModelBase ve svém statickém konstruktoru dosazuje výchozí objekt podporující
rozhraní &lt;em&gt;ITransientStateHelper&lt;/em&gt;, které je klíčové pro uložení a obnovení tranzientního
stavu view modelů a na které delegují i metody &lt;em&gt;DoInternalLoadTransientState&lt;/em&gt;&amp;nbsp;
a &lt;em&gt;DoInternalSaveTransientState&lt;/em&gt; v předchozím výpisu.
&lt;/p&gt;
&lt;p&gt;
Všimněte si, že metoda &lt;em&gt;DoInternalLoadTransientState &lt;/em&gt;po obnovení tranzientního
stavu zkontroluje, jestli se dá view model používat, a pokud ne, zavolá i v této fázi
metodu Init.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;if (!CanUseModel)&lt;br&gt;
{&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&amp;nbsp; Init();&lt;br&gt;
}&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
A nyní se podíváme na mocné rozhraní &lt;em&gt;ITransientStateHelper&lt;/em&gt;
&lt;/p&gt;
&lt;strong&gt;&lt;/strong&gt;&lt;script src="https://gist.github.com/745212.js"&gt; &lt;/script&gt;
&lt;p&gt;
Je asi zřejmé, že metoda &lt;em&gt;GetTransientState&lt;/em&gt; vrátí v objektu Dictionary tranzientní
stav objektu, který jí byl předán v argumentu obj. Metoda &lt;em&gt;RestoreTransientState&lt;/em&gt; naopak
obnoví tranzientní stav objektu v argumentu obj hodnotami v argumentu savedState.
&lt;/p&gt;
&lt;p&gt;
Metoda &lt;em&gt;IsTransientStateEnabledForObject&lt;/em&gt; zjistí, jestli je možné z předaného
objektu získat tranzientní stav. Jak uvidíme, odvozené view modely mohou odmítnout
uložení tranzientního stavu a kdekoli v aplikaci&amp;nbsp; můžeme jejich rozhodnutí jednoduše
zjistit předáním instance view modelu této metodě.
&lt;/p&gt;
&lt;p&gt;
Zde je jedna z možných realizací rozhraní IStateTransientStateHelper, kterou používá
i naše třída ViewModelBase.
&lt;/p&gt;
&lt;script src="https://gist.github.com/745247.js"&gt; &lt;/script&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Odpovědnosti metod &lt;em&gt;GetTransientState&lt;/em&gt; a &lt;em&gt;RestoreTransientState&lt;/em&gt; jsem
již popsal, nyní jen zmíním pár specialitek v kódu třídy TransientStateHelper.
&lt;/p&gt;
&lt;p&gt;
Metoda GetTransientState zjistí, jestli předaný objekt&amp;nbsp; má tranzientní stav tak,
že zavolá metodu &lt;strong&gt;IsTransientStateEnabledForObject(obj)&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Metoda IsTransientStateEnabledForObject kontroluje, jestli třída, ze které objekt
pochází, nezakázala vydání tranzientního stavu tím, že je na ní aplikován atribut
[NonTransientState].
&lt;/p&gt;
&lt;p&gt;
Atribut NonTransientState
&lt;/p&gt;
&lt;script src="https://gist.github.com/745279.js"&gt; &lt;/script&gt;
&lt;p&gt;
Atribut NonTransientState může být aplikován nejen na celou třídu, ale i na jednotlivé
vlastnosti objektu, které nemají být součástí tranzientního stavu.&amp;nbsp; &lt;strong&gt;Metoda
GetTransientState neukládá celé view modely, ale s využitím reflexe jen hodnoty jejich
vlastností. Atribut NonTransientState dovoluje vyřadit vlastnosti, které v tranzientním
stavu view modelu nemají co dělat.&lt;/strong&gt; To ale není vše – přímo metoda GetTransientState
dle jmenné konvence vyřadí všechny vlastnosti, jejichž suffix je v poli IGNORE_METHOD_SUFFIX_LIST 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;public static readonly IEnumerable&lt;string&gt;
IGNORE_METHOD_SUFFIX_LIST = new[] { "Command", "Action", "Helper", "Service", "SynchContext"};
&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Do tranzientního stavu se tak nedostanou ve view modelech se často nacházející, ale
s tranzientním stavem view modelu nic nemající a navíc většinou neserializovatelné
objekty jako jsou objekty ICommand (vlastnost Select&lt;strong&gt;Command&lt;/strong&gt;, Save&lt;strong&gt;Command&lt;/strong&gt;),
delegáti&amp;nbsp; TextboxTextChanged&lt;strong&gt;Action&lt;/strong&gt;, služby (ILogger&lt;strong&gt;Service&lt;/strong&gt;)
a další.
&lt;/p&gt;
&lt;p&gt;
Metoda &lt;em&gt;RestoreTransientState&lt;/em&gt; obnoví tranzientní stav objektu. Za zmínku stojí,
že když je předaný objekt potomkem PropertyNotificationBase, tak nastavením vlastnosti
notificationBase.SuppressPropertyChangedNotification na true potlačíme dočasně vyvolání
události OnPropertyChanged, protože je vhodné, abychom událost nevyvolávali, když
view model neobsahuje všechna data a nevíme, kdo všechno na událost reaguje a jaká
další, nyní ve view modelu se nenacházející data, by chtěl načíst. Jak jsem ale psal
v požadavcích na začátku článku, view model nemusí podporovat žádná rozhraní, nemusí
být potomkem ViewModelBase ani PropertyNotificationBase, a proto si ani dědění z PropertyNotificationBase
v této metodě nevynucujeme. Poté, co metoda &lt;em&gt;RestoreTransientState &lt;/em&gt;obnoví
hodnoty všech vlastností, má TransientStateHelper povinnost notifikovat okolí o změně
hodnot všech vlastností view modelu. Jestliže je objekt s obnoveným tranzientním stavem
potomkem PropertyNotificationBase, zavoláme metodu RaisePropertiesChanged(propertyNames.ToArray()),
jinak se metoda &lt;em&gt;RestoreTransientState&lt;/em&gt; pokusí dohledat opět za pomoci reflexe
na objektu metodu nazvanou RaisePropertyChangedEvent, která přijímá název vlastnosti
a kterou použije pro hromadnou distribuci událostí OnPropertyChanged.
&lt;/p&gt;
&lt;p&gt;
Ovládací prvky obsažené (nejen) v control toolkitu jsou&amp;nbsp; přecitlivělé na pořadí
vyvolávání události, a proto jsou vlastnosti seřazeny nyní tak, aby vlastnosti začínající
slovem &lt;em&gt;Selected&lt;/em&gt;&lt;strong&gt; &lt;/strong&gt;vyvolávaly událost OnPropertyChanged jako
poslední. Máte-li ve view modelu kolekci nazvanou Orders (všechny objednávky) a SelectedOrder
(vybraná objednávka z této kolekce), je zaručeno, že &lt;strong&gt;událost OnPropertyChanged
pro vlastnost SelectedOrder bude vyvolána až po události OnPropertyChanged pro vlastnost
Orders.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Prefixy vlastností, které mají vyvolávat události jako poslední, jsou v proměnné
LAST_SET_VALUE_METHOD_PREFIX. Tyto vlastnosti jsou označeny příznakem LastInit z enumerace
PropertyType.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;public static readonly IEnumerable&lt;string&gt;
LAST_SET_VALUE_METHOD_PREFIX = new[] { "Selected" };
&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
To by pro dnešek k třídě ViewModelBase a jejím pomocníkům stačilo:
&lt;/p&gt;
&lt;p&gt;
Příště se podíváme hlavně na “hostitele” view modelů, který by měl být schopen:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Volat na view modelech ve “správnou dobu” metody Init, LoadState, SaveState, Activate,
Deactivate. 
&lt;br&gt;
&lt;li&gt;
Připojit view modely k view (stránce).&lt;br&gt;
&lt;li&gt;
Náš hostitel bude podporovat i více view modelů na jedné stránce, včetně “dědění”
a sdílení použitých view modelů mezi různými view na stránce.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
A také si příště vysvětlíme, proč při získání tranzientního stavu ve ViewModelbase
místo objektu Dictionary používáme vlastní třídu KnownTypesDictionary. Jak možná tušíte,
i název “KnownTypes” odkazuje k tomu, že mají-li být hodnoty uložené v tranzientním
stavu serializovatelné, tak &lt;em&gt;DataContractSerializer,&lt;/em&gt; používaný infrastrukturou
WP7 k serializaci tranzientního stavu, musíme přesvědčit, že v objektu Dictionary
jsou jen objekty z jemu “známých” tříd.
&lt;/p&gt;
&lt;p&gt;
Předcházející články:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx"&gt;Tipy
pro Windows Phone 7 aplikace I&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=060fbd09-0368-4733-92ad-aaecf48409a4" /&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,060fbd09-0368-4733-92ad-aaecf48409a4.aspx</comments>
      <category>C#</category>
      <category>Compact .Net Framework</category>
      <category>Návrhové vzory</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=131d4068-9718-43a6-abea-0651f8c8c790</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,131d4068-9718-43a6-abea-0651f8c8c790.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,131d4068-9718-43a6-abea-0651f8c8c790.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=131d4068-9718-43a6-abea-0651f8c8c790</wfw:commentRss>
      <title>Tipy pro Windows Phone 7 aplikace I</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,131d4068-9718-43a6-abea-0651f8c8c790.aspx</guid>
      <link>http://blog.renestein.net/Tipy+Pro+Windows+Phone+7+Aplikace+I.aspx</link>
      <pubDate>Mon, 06 Dec 2010 09:57:19 GMT</pubDate>
      <description>První slíbený článek na téma vývoje Windows Phone 7 aplikací je venku. Dnes si ukážeme většinou kód, který řeší některé od CTP  se vlekoucí chyby ve WP7 SDK, nebo řeší některé nedomyšlenosti a omezení mobilní verze Silverlightu. Mobilní verze Silverlightu vychází totiž ze Silverlightu 3, i když se objevují náznaky, že v lednu přijde aktualizace, která z WP7 udělá zase o něco lepší systém. Nezbývá než doufat, že sousloví “pořádná aktualizace” neoznačuje jen dodání “Copy-Paste” za zvuků fanfár.&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=131d4068-9718-43a6-abea-0651f8c8c790"/&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,131d4068-9718-43a6-abea-0651f8c8c790.aspx</comments>
      <category>Compact .Net Framework</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
    <item>
      <trackback:ping>http://blog.renestein.net/Trackback.aspx?guid=90c71b5b-7324-4a73-a7a4-5ee017c8b136</trackback:ping>
      <pingback:server>http://blog.renestein.net/pingback.aspx</pingback:server>
      <pingback:target>http://blog.renestein.net/PermaLink,guid,90c71b5b-7324-4a73-a7a4-5ee017c8b136.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.renestein.net/CommentView,guid,90c71b5b-7324-4a73-a7a4-5ee017c8b136.aspx</wfw:comment>
      <wfw:commentRss>http://blog.renestein.net/SyndicationService.asmx/GetEntryCommentsRss?guid=90c71b5b-7324-4a73-a7a4-5ee017c8b136</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <title>C# Posterous API Wrapper verze 0.0.3 &amp;ndash; pro .NF 3.5+, Silverlight 4 a nově i s podporou pro Windows Phone 7</title>
      <guid isPermaLink="false">http://blog.renestein.net/PermaLink,guid,90c71b5b-7324-4a73-a7a4-5ee017c8b136.aspx</guid>
      <link>http://blog.renestein.net/C+Posterous+API+Wrapper+Verze+003+Ndash+Pro+NF+35+Silverlight+4+A+Nov%c4%9b+I+S+Podporou+Pro+Windows+Phone+7.aspx</link>
      <pubDate>Mon, 15 Nov 2010 15:25:38 GMT</pubDate>
      <description>Ke stažení jsem uvolnil další verzi API wrapperu služby Posterous. Pracuji nyní na komerčním a delší dobu plánovaném projektu pro WP7, a proto jsem v rámci vývojářského ducha povznášejícího testování různých nedomyšleností a špeků tohoto nového nadělení od mobilní divize MS cvičně  přidal už v Beta/RC verzi WP7 do Posterous API zkušební verzi pro WP7, kterou jsem nyní otestoval a doladil na “ostré”(sic! skutečně?) verzi WP7.

Další sarkasmy na adresu WP7 si dnes odpustím, těch už bylo dost na Twitteru...
&lt;img width="0" height="0" src="http://blog.renestein.net/aggbug.ashx?id=90c71b5b-7324-4a73-a7a4-5ee017c8b136"/&gt;</description>
      <comments>http://blog.renestein.net/CommentView,guid,90c71b5b-7324-4a73-a7a4-5ee017c8b136.aspx</comments>
      <category>.NET Framework</category>
      <category>C# Posterous API</category>
      <category>Silverlight</category>
      <category>WP7</category>
    </item>
  </channel>
</rss>