<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>andrzej.net.pl &#187; c#</title>
	<atom:link href="http://andrzej.net.pl/index.php/category/csharp/feed/" rel="self" type="application/rss+xml" />
	<link>http://andrzej.net.pl</link>
	<description>Blog o programowaniu C#, ASP.NET</description>
	<lastBuildDate>Mon, 28 Jun 2010 07:03:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>ErrorProvider i focus po nieudanej walidacji</title>
		<link>http://andrzej.net.pl/index.php/2010/05/errorprovider-i-focus-po-nieudanej-walidacji/</link>
		<comments>http://andrzej.net.pl/index.php/2010/05/errorprovider-i-focus-po-nieudanej-walidacji/#comments</comments>
		<pubDate>Thu, 13 May 2010 21:59:43 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[windows forms]]></category>
		<category><![CDATA[autovalidate]]></category>
		<category><![CDATA[errorprovider]]></category>
		<category><![CDATA[focus]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=771</guid>
		<description><![CDATA[Notka to bardziej &#8211; ku pamięci &#8211; niż pełnowartościowy wpis. Na co dzień programuję głównie dla weba używając ASP.NET, od czasu do czasu zdarza mi się napisać proste rzeczy w Windows Forms. Dziś przez dobre 30 minut (jeśli nie lepiej) rwałem sobie włosy z głowy zastanawiając się jakie property i w czym przestawić, żeby kontrolka [...]


Nie znaleziono powiązanych wpisów.

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p>Notka to bardziej &#8211; ku pamięci &#8211; niż pełnowartościowy wpis. Na co dzień programuję głównie dla weba używając ASP.NET, od czasu do czasu zdarza mi się napisać proste rzeczy w Windows Forms. Dziś przez dobre 30 minut (jeśli nie lepiej) rwałem sobie włosy z głowy zastanawiając się jakie property i w czym przestawić, żeby kontrolka ErrorProvider po zwalidowaniu TextBoxa pokazała błąd ale <strong>pozwoliła przejść dalej w formularzu</strong> (zmienić focus).</p>
<p><span id="more-771"></span></p>
<p>Im dłużej szukałem tym bardziej irytacja narastała. Przypadek ala &#8222;<a href="http://czasdzieci.pl/czytanki/id,41f74-julian_tuwim_okulary.html" onclick="pageTracker._trackPageview('/outgoing/czasdzieci.pl/czytanki/id_41f74-julian_tuwim_okulary.html?referer=');">Biega, krzyczy pan Hilary: Gdzie są moje okulary?&#8221;</a> Pamiętałem, że chodziło o coś w stylu &#8222;AllowTabChange&#8221;, &#8222;AllowFocusChaneOnError&#8221; czy inne cudo.</p>
<p>Najbardziej naturalne wydało mi się poszukiwanie we właściwościach samej kontrolki error provider. Oczywiście &#8211; nic bardziej mylnego :]</p>
<p><a href="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider3.png" rel="lightbox[771]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider3-212x300.png" alt="" title="ErrorProvider properties" width="212" height="300" class="alignnone size-medium wp-image-772" /></a></p>
<p>BlinkRate, BlinkStyle.. Nie ma nic pomocnego w rozwiązaniu mojego ogromnego, egzystencjonalnego problemu.<br />
Później zacząłem się przyglądać właściwościom samego TextBoxa&#8230; CausingValidation! Nie.. też nie to. Wtedy przestały się odpalać zdarzenia Validating i Validated &#8211; w sumie czemu miałoby być inaczej niż mówi opis tej właściwości ;) ?</p>
<p>Nadal uparcie blokował się focus na TextBoxie, jeśli jego zawartość nie spełniała warunków walidacji.. a ja tylko chciałem wypelnić sobie formularz w dowolnej kolejności!</p>
<p><a href="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider1.png" rel="lightbox[771]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider1.png" alt="" title="ErrorProvider - focus zablokowany" width="244" height="212" class="alignnone size-full wp-image-773" /></a></p>
<p>Przyszło oświecenie i zacząłem szukać we właściwościach samej formy.. Wiadomo &#8211; im bardziej czegoś się szuka tym bardziej się to ukrywa. Chyba za trzecim razem znalazłem property <strong>AutoValidate</strong>! Tak &#8211; to było to&#8230; Oklaski, owacje na stojąco, kurtyna&#8230; Zapamiętam już raczej do końca życia ;)</p>
<p><a href="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider4.png" rel="lightbox[771]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider4-228x300.png" alt="" title="ErrorProvider - AutoValidate" width="228" height="300" class="alignnone size-medium wp-image-774" /></a> <a href="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider5.png" rel="lightbox[771]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/05/error_provider5.png" alt="" title="ErrorProvider - uff" width="263" height="230" class="alignnone size-full wp-image-775" /></a></p>
<p>Oj potrafią dać w kość czasem takie głupoty. Człowiek nagle nie wie jak odpytać google&#8217;a, by coś sensownego podpowiedział, nikogo znajomego na żadnym komunikatorze. Strach i przerażenie ;)</p>
<p>Też zdarzają się Wam takie małe przeszkadzajki, odbierające więcej energii niż kilka godzin programowania :) ?</p>


<p>Nie znaleziono powiązanych wpisów.</p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2010/05/errorprovider-i-focus-po-nieudanej-walidacji/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Shallow copy a deep copy &#8211; klonowanie obiektu z MemberwiseClone oraz przy użyciu serializacji</title>
		<link>http://andrzej.net.pl/index.php/2010/01/shallow-copy-a-deep-copy-klonowanie-obiektu-z-memberwiseclone-oraz-przy-uzyciu-serializacji/</link>
		<comments>http://andrzej.net.pl/index.php/2010/01/shallow-copy-a-deep-copy-klonowanie-obiektu-z-memberwiseclone-oraz-przy-uzyciu-serializacji/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 22:40:53 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[nowe]]></category>
		<category><![CDATA[ogólne]]></category>
		<category><![CDATA[C# klonowanie]]></category>
		<category><![CDATA[deep copy]]></category>
		<category><![CDATA[ICloneable]]></category>
		<category><![CDATA[serializacja]]></category>
		<category><![CDATA[shallow copy]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=692</guid>
		<description><![CDATA[Rozróżnia się dwie możliwości klonowania obiektów: shallow copy &#8211; tzw. płytka kopia. Najczęściej wykonywana przy użyciu metody MemberwiseClone z klasy Object. deep copy &#8211; tzw. głęboka, pełna kopia. Przyjrzymy się jednej z możliwości jej realizacji &#8211; wykorzystania serializacji do strumienia w pamięci. Zapewne wszyscy wiedzą o istnieniu metody MemberwiseClone w klasie Object. Pozwala ona na [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/' rel='bookmark' title='Permanent Link: Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#'>Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify">
Rozróżnia się dwie możliwości klonowania obiektów:</p>
<ul>
<li>shallow copy &#8211; tzw. płytka kopia. Najczęściej wykonywana przy użyciu metody MemberwiseClone z klasy Object.</li>
<li>deep copy &#8211; tzw. głęboka, pełna kopia. Przyjrzymy się jednej z możliwości jej realizacji &#8211; wykorzystania serializacji do strumienia w pamięci.</li>
</ul>
<p style="text-align:justify">
Zapewne wszyscy wiedzą o istnieniu metody <a href="http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx?referer=');">MemberwiseClone</a> w klasie Object.<br />
Pozwala ona na wykonanie tzw. &#8222;shallow copy&#8221;, czyli &#8222;płytkiej kopii&#8221; obiektu. Kopia taka nie radzi sobie jednak z typami referencyjnymi zagnieżdżonymi w klonowanym obiekcie. Potrafi poprawnie kopiować tylko Value Types.
</p>
<p><span id="more-692"></span></p>
<p style="text-align:justify">
Weźmy przykładową klasę Person:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Person<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> FirstName <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> LastName <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> DateTime BirthDate <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> Person Boss <span style="color: #008000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> Person<span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">string</span> firstName, <span style="color: #6666cc; font-weight: bold;">string</span> lastName, DateTime birthDate <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">FirstName</span> <span style="color: #008000;">=</span> firstName<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">LastName</span> <span style="color: #008000;">=</span> lastName<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">BirthDate</span> <span style="color: #008000;">=</span> birthDate<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span> &nbsp; &nbsp; &nbsp;<br />
<span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
<p>Możemy zaimplementować interfejs <a href="http://msdn.microsoft.com/en-us/library/system.icloneable.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.icloneable.aspx?referer=');">ICloneable</a> dla &#8222;shallow copy&#8221; w ten sposób:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">object</span> Clone<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">MemberwiseClone</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
<p>Co się jednak stanie, gdy wykonamy kopię zmiennej kowalski z poniższego przykładu?
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Person jankowski <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Person<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Stefan&quot;</span>, <span style="color: #666666;">&quot;Jankowski&quot;</span>, <span style="color: #008000;">new</span> DateTime<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">1977</span>,<span style="color: #FF0000;">2</span>,<span style="color: #FF0000;">25</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
Person kowalski <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Person<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Jan&quot;</span>, <span style="color: #666666;">&quot;Kowalski&quot;</span>, <span style="color: #008000;">new</span> DateTime<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">1980</span>,<span style="color: #FF0000;">12</span>,<span style="color: #FF0000;">4</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
kowalski<span style="color: #008000;">.</span><span style="color: #0000FF;">Boss</span> <span style="color: #008000;">=</span> jankowski<span style="color: #008000;">;</span><br />
<br />
Person kowalskiCopy <span style="color: #008000;">=</span> <span style="color: #008000;">&#40;</span>Person<span style="color: #008000;">&#41;</span>kowalski<span style="color: #008000;">.</span><span style="color: #0000FF;">Clone</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
Debug<span style="color: #008000;">.</span><span style="color: #0000FF;">Write</span><span style="color: #008000;">&#40;</span>kowalski<span style="color: #008000;">.</span><span style="color: #0000FF;">Boss</span> <span style="color: #008000;">==</span> kowalskiCopy<span style="color: #008000;">.</span><span style="color: #0000FF;">Boss</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p style="text-align:justify">
<p>Wynik? Tak jak oczekiwaliśmy, Boss w obiekcie kowalski oraz kowalskiCopy wskazują na ten sam obiekt &#8211; jankowski.</p>
<p>Jak widać nie jest to idealne wyjście. Rzadko zdarza się, by obiekt zawierał wyłącznie value types. Ponadto metodę MemberwiseClone możemy wywołać tylko w klasie, do której mamy dostęp. Dlaczego? Ponieważ jest ona oznaczona jako protected w klasie Object. Oznacza to, że nie użyjemy jej, gdy chcemy sklonować typ z innej biblioteki, której źródła nie jesteśmy w stanie sami zmodyfikować implementując ICloneable.</p>
<p>Właśnie tutaj z pomocą przychodzi nam serializacja. Wystarczy zserializować obiekt do strumienia w pamięci i zdeserializować do innej instancji. Gotowe.</p>
<p>Jak z realizacją?<br />
Nic nie stoi na przeszkodze, aby zamknąć kod w statycznej metodzie i wykorzystać typ generyczny. Dzięki temu będziemy mogli przy użyciu jednej metody serializować wszystkie typy! No &#8211; prawie wszystkie.</p>
<p>Należy pamiętać, że typ, który chcemy serializować:</p>
<ul>
<li>musi być oznaczony atrybutem <a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.serializableattribute.aspx?referer=');">Serializable</a></li>
<li>wszystkie jego pola muszą być serializowalne</li>
</ul>
<p>Jeśli klasa nie będzie spełniać powyższych wymagań, w runtime otrzymamy SerializationException.</p>
<p> Do naszej klasy wprowadzamy więc małą modyfikację:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&#91;</span>Serializable<span style="color: #008000;">&#93;</span><br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Person<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">...</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
<p>Metoda, którą będziemy serializować nasze obiekty jest dość prosta.</p>
<p>W dyrektywie using tworzymy nowy MemoryStream. Następnie tworzymy instancję <a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx?referer=');">BinaryFormattera</a>, informując go w konstruktorze, że będzie użyty w kontekście serializacji.<br />
Serializujemy przekazany obiekt, przewijamy stream do początku i deserializujemy. Musimy przeprowadzić rzutowanie (Deserialize zwraca Object). Trochę kodu:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> T CloneObject<span style="color: #008000;">&lt;</span>T<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span> T item <span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008000;">&#40;</span> MemoryStream ms <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> MemoryStream<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//instancja BinaryFormattera - informujemy go,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//ze bedzie uzyty w celu klonowania</span><br />
&nbsp; &nbsp; &nbsp; BinaryFormatter bf <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> BinaryFormatter<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">null</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">new</span> StreamingContext<span style="color: #008000;">&#40;</span>StreamingContextStates<span style="color: #008000;">.</span><span style="color: #0000FF;">Clone</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//serializacja</span><br />
&nbsp; &nbsp; &nbsp; bf<span style="color: #008000;">.</span><span style="color: #0000FF;">Serialize</span><span style="color: #008000;">&#40;</span>ms, item<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//przewijamy memoryStream do poczatku</span><br />
&nbsp; &nbsp; &nbsp; ms<span style="color: #008000;">.</span><span style="color: #0000FF;">Seek</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">0</span>, SeekOrigin<span style="color: #008000;">.</span><span style="color: #0000FF;">Begin</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//deserializacja</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span> T <span style="color: #008000;">&#41;</span>bf<span style="color: #008000;">.</span><span style="color: #0000FF;">Deserialize</span><span style="color: #008000;">&#40;</span>ms<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
<p>To wszystko. Przykład użycia:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Person kowalskiCopy <span style="color: #008000;">=</span> Tools<span style="color: #008000;">.</span><span style="color: #0000FF;">CloneObject</span><span style="color: #008000;">&lt;</span>Person<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span>kowalski<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
Debug<span style="color: #008000;">.</span><span style="color: #0000FF;">Write</span><span style="color: #008000;">&#40;</span>kowalski<span style="color: #008000;">.</span><span style="color: #0000FF;">Boss</span> <span style="color: #008000;">==</span> kowalskiCopy<span style="color: #008000;">.</span><span style="color: #0000FF;">Boss</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p>Efekt wykonania tej metody? W oknie output pojawi się false. Oznacza to, że obiekt został w pełni sklonowany &#8211; łącznie z referencją do szefa.</p>
<p>Jest jeszcze kilka niewielkich niuansów związanych z serializacją &#8211; jak np. delegaty czy propertiesy, które nie powinny być serializowalne. To jednak materiał na odrębny, obszerny wpis.</p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/' rel='bookmark' title='Permanent Link: Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#'>Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2010/01/shallow-copy-a-deep-copy-klonowanie-obiektu-z-memberwiseclone-oraz-przy-uzyciu-serializacji/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Visual Studio &#8211; jednoczesne debugowanie kilku projektów w solution</title>
		<link>http://andrzej.net.pl/index.php/2010/01/visual-studio-jednoczesne-debugowanie-kilku-projektow-w-solution/</link>
		<comments>http://andrzej.net.pl/index.php/2010/01/visual-studio-jednoczesne-debugowanie-kilku-projektow-w-solution/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 21:45:06 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[nowe]]></category>
		<category><![CDATA[visual studio tricks]]></category>
		<category><![CDATA[debugowanie wielu projektów]]></category>
		<category><![CDATA[visual studio 2008]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=685</guid>
		<description><![CDATA[Najprostsze rozwiązania często są w Visual Studio sprytnie ukryte. Takie czasem odnoszę wrażenie. Jedną z rzeczy, na które narzekałem przy debugowaniu np. WebService&#8217;ów czy aplikacji współdzielących niektóre zasoby był brak możliwości ustawienia jako &#8222;Startup&#8221; kilku projektów w ramach jednej solucji. Okazuje się jednak, że jest to banalnie proste.. Przeważnie ustawiałem jeden projekt jako startowy korzystając [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/08/the-web-application-is-configured-to-use-iis-the-iis-web-server-is-not-installed-on-this-computer/' rel='bookmark' title='Permanent Link: The Web Application is configured to use IIS. The IIS Web server is not installed on this computer.'>The Web Application is configured to use IIS. The IIS Web server is not installed on this computer.</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify">
Najprostsze rozwiązania często są w Visual Studio sprytnie ukryte. Takie czasem odnoszę wrażenie. Jedną z rzeczy, na które narzekałem przy debugowaniu np. WebService&#8217;ów czy aplikacji współdzielących niektóre zasoby był brak możliwości ustawienia jako &#8222;Startup&#8221; kilku projektów w ramach jednej solucji. Okazuje się jednak, że jest to banalnie proste..
</p>
<p><span id="more-685"></span></p>
<p style="text-align:justify">
Przeważnie ustawiałem jeden projekt jako startowy korzystając z opcji w menu kontekstowym na projekcie: &#8222;Set as startup project&#8221;.<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2010/01/plik046.jpg" rel="lightbox[685]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/01/plik046-150x150.jpg" alt="" title="Opcja &quot;Set as startup project&quot;" width="150" height="150" class="aligncenter size-thumbnail wp-image-686" /></a>
</p>
<p style="text-align:justify">
Możliwe jest jednak ustawienie wielu projektów jako startowych. W tym celu należy wywołać menu kontekstowe na Solution i wybrać Properties:<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2010/01/plik047.jpg" rel="lightbox[685]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/01/plik047-150x150.jpg" alt="" title="Solution, menu kontekstowe" width="150" height="150" class="aligncenter size-thumbnail wp-image-687" /></a>
</p>
<p style="text-align:justify">
Naszym oczom ukaże się okno właściwości. Wybieramy po lewej opcję Common Properties -> Startup Project.<br />
Teraz wystarczy przełączyć je w tryb &#8222;Multiple startup projects&#8221; i wybrać akcję na tych projektach, które nas interesują:<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2010/01/plik048.jpg" rel="lightbox[685]"><img src="http://andrzej.net.pl/wp-content/uploads/2010/01/plik048-150x150.jpg" alt="" title="Właściwości solucji" width="150" height="150" class="aligncenter size-thumbnail wp-image-688" /></a>
</p>
<p style="text-align:justify">
Można ustawić projekt w trybie:</p>
<ul>
<li>None &#8211; wiadomo ;)</li>
<li>Start &#8211; uruchamia z debuggerem</li>
<li>Start without debugging &#8211; wiadomo ;)</li>
</ul>
<p>Także.. happy debugging! ;)</p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/08/the-web-application-is-configured-to-use-iis-the-iis-web-server-is-not-installed-on-this-computer/' rel='bookmark' title='Permanent Link: The Web Application is configured to use IIS. The IIS Web server is not installed on this computer.'>The Web Application is configured to use IIS. The IIS Web server is not installed on this computer.</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2010/01/visual-studio-jednoczesne-debugowanie-kilku-projektow-w-solution/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mutex i sprawdzanie czy aplikacja jest jedyną uruchomioną</title>
		<link>http://andrzej.net.pl/index.php/2010/01/mutex-i-sprawdzanie-czy-aplikacja-jest-jedyna-uruchomiona/</link>
		<comments>http://andrzej.net.pl/index.php/2010/01/mutex-i-sprawdzanie-czy-aplikacja-jest-jedyna-uruchomiona/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 21:30:55 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[nowe]]></category>
		<category><![CDATA[jedna instancja aplikacji]]></category>
		<category><![CDATA[mutex]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=677</guid>
		<description><![CDATA[Uzupełniam ostatnio braki w wiedzy, dotyczące synchronizacji wątków. Gdzieś w podrozdziale dotyczącym tego tematu przykuł moją uwagę Mutex. Mutex to, obok monitorów i semaforów, jedna z &#8222;prymitywnych&#8221; metod synchronizacji. Ma jednak bardzo ciekawą właściwość, odróżniającą ją od kolegów po fachu&#8230; Otóż co to za właściwość? Tatusiem Mutexu jest bezpośrednio windowsowy kernel a jego właścicielem może [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/10/throw-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek/' rel='bookmark' title='Permanent Link: &#8222;throw&#8221; czy &#8222;throw exc&#8221; &#8211; czyli jak najlepiej przerzucić wyjątek wyżej'>&#8222;throw&#8221; czy &#8222;throw exc&#8221; &#8211; czyli jak najlepiej przerzucić wyjątek wyżej</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify">
Uzupełniam ostatnio braki w wiedzy, dotyczące synchronizacji wątków. Gdzieś w podrozdziale dotyczącym tego tematu przykuł moją uwagę <a href="http://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.threading.mutex.aspx?referer=');">Mutex</a>. Mutex to, obok monitorów i semaforów, jedna z &#8222;prymitywnych&#8221; metod synchronizacji. Ma jednak bardzo ciekawą właściwość, odróżniającą ją od kolegów po fachu&#8230;
</p>
<p><span id="more-677"></span></p>
<p style="text-align:justify">
Otóż co to za właściwość? Tatusiem Mutexu jest bezpośrednio windowsowy kernel a jego właścicielem może być w jednej chwili tylko jeden wątek. Wątek, który przejmuje obiekt typu Mutex na własność nie blokuje sam siebie ale musi zwolnić go przy użyciu metody ReleaseMutex. Co w tym nadzwyczajnego? Jeszcze jedna sztuczka!
</p>
<p style="text-align:justify">
Korzystając z jednego z przeciążonych konstruktorów, możemy nadać obiektowi typu Mutex nazwę. Uwaga, kurtyna w górę ;) <strong>Nazwa ta jest unikalna</strong> wśród wszystkich procesów w systemie! Otóż to, panie i panowie ;) Całe to cudeńko pozwala nam niejako udostępniać obiekt Mutex pomiędzy różnymi aplikacjami. Przeważnie użylibyśmy tej właściwości do synchronizacji dostępu tych aplikacji np. do zasobów dyskowych, sieciowych itp. Jednak jest jeszcze jedno interesujące użycie.
</p>
<p style="text-align:justify">
Do sedna. Wykorzystując <a href="http://msdn.microsoft.com/en-us/library/bwe34f1k.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/bwe34f1k.aspx?referer=');">konstruktor z trzema parametrami</a>:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> Mutex<span style="color: #008000;">&#40;</span><br />
&nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">bool</span> initiallyOwned,<br />
&nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">string</span> name,<br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">out</span> <span style="color: #6666cc; font-weight: bold;">bool</span> createdNew<br />
<span style="color: #008000;">&#41;</span></div></div>
<p>Możemy skonstruować sprytny kod, który pozwoli uruchomić jednocześnie tylko jedną instancję pisanej przez nas aplikacji. Przykład?</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Main<span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> args <span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #6666cc; font-weight: bold;">bool</span> isNewCreated<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000;">System.<span style="color: #0000FF;">Threading</span></span><span style="color: #008000;">.</span><span style="color: #0000FF;">Mutex</span> mutex <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> Mutex<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">true</span>, <span style="color: #666666;">&quot;MUTEX_DEMO&quot;</span>, <span style="color: #0600FF; font-weight: bold;">out</span> isNewCreated<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span> isNewCreated <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Brawo - jesteś pierwszy! ;)&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">else</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Niestety! Nie byłeś pierwszy ;)&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp;Console<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadLine</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #008000;">&#125;</span></div></div>
<p>W sumie jedną linijką kodu załatwiamy sprawdzenie. Być może nie jest to wyjście idealne, ale czasem może uratować trochę czasu.</p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/10/throw-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek/' rel='bookmark' title='Permanent Link: &#8222;throw&#8221; czy &#8222;throw exc&#8221; &#8211; czyli jak najlepiej przerzucić wyjątek wyżej'>&#8222;throw&#8221; czy &#8222;throw exc&#8221; &#8211; czyli jak najlepiej przerzucić wyjątek wyżej</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2010/01/mutex-i-sprawdzanie-czy-aplikacja-jest-jedyna-uruchomiona/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Książki &#8211; co czytam. Certyfikacja &#8211; czy warto?</title>
		<link>http://andrzej.net.pl/index.php/2009/10/ksiazki-co-czytam-certyfikacja-czy-warto/</link>
		<comments>http://andrzej.net.pl/index.php/2009/10/ksiazki-co-czytam-certyfikacja-czy-warto/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 21:52:07 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[nowe]]></category>
		<category><![CDATA[ogólne]]></category>
		<category><![CDATA[certyfikacja MS]]></category>
		<category><![CDATA[CLR VIA C#]]></category>
		<category><![CDATA[książki o C#]]></category>
		<category><![CDATA[MCTS 70-536]]></category>
		<category><![CDATA[THE BASE CLASS LIBRARY]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=627</guid>
		<description><![CDATA[Na wstępie &#8222;krótkie&#8221; wprowadzenie &#8211; opis książki, którą męczyłem przez ostatnie ładnych &#8222;kilka&#8221; dni ;) Co uważniejsi z czytelników zauważyli malutki widget po prawej stronie &#8211; &#8222;Obecnie czytam&#8221;. Właśnie wymieniła się w niej książka. Skończyłem czytać &#8222;CLR VIA C#&#8221; Richtera, zabieram się za &#8222;VISUAL C# 2005: THE BASE CLASS LIBRARY&#8221; Balena. Z tą książką powinno [...]


Nie znaleziono powiązanych wpisów.

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p><a rev="vote-for" href="http://dotnetomaniak.pl/Ksi%C4%85%C5%BCki-co-czytam" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/Ksi_C4_85_C5_BCki-co-czytam?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F10%2Fksiazki-co-czytam-certyfikacja-czy-warto%2F" style="border:0px"/></a></p>
<p>Na wstępie &#8222;krótkie&#8221; wprowadzenie &#8211; opis książki, którą męczyłem przez ostatnie ładnych &#8222;kilka&#8221; dni ;)</p>
<p style="text-align:justify">
Co uważniejsi z czytelników zauważyli malutki widget po prawej stronie &#8211; &#8222;Obecnie czytam&#8221;. Właśnie wymieniła się w niej książka. Skończyłem czytać <a href="http://www.microsoft.com/learning/en/us/book.aspx?ID=6522&#038;locale=en-us" onclick="pageTracker._trackPageview('/outgoing/www.microsoft.com/learning/en/us/book.aspx?ID=6522_038_locale=en-us&amp;referer=');">&#8222;CLR VIA C#&#8221; Richtera</a>, zabieram się za <a href="http://www.amazon.com/Programming-Microsoft-Visual-2005-Pro-Developer/dp/0735623082" onclick="pageTracker._trackPageview('/outgoing/www.amazon.com/Programming-Microsoft-Visual-2005-Pro-Developer/dp/0735623082?referer=');">&#8222;VISUAL C# 2005: THE BASE CLASS LIBRARY&#8221; Balena</a>. Z tą książką powinno pójść łatwiej i szybciej niż z Richterem (takie mam wrażenie).
</p>
<p style="text-align:justify">
CLR VIA C# jest bardzo interesującą pozycją, którą polecam każdemu. Richter w dość swoisty sposób rozebrał na części pierwsze wszystko, z czym spotykamy się na co dzień. Pierwsza część jest mocno teoretyczna &#8211; operacja na otwartym sercu .NET, czyli CLR właśnie. Ciekawostki, ogólny zarys i założenia, które zapadają w pamięć i sporo rozjaśniają. Część &#8222;Working with types&#8221; &#8211; dość ciekawa. Nie zanudza, mimo, iż opisuje rzeczy oczywiste. &#8222;Designing parts&#8221; &#8211; wspaniałe kompendium dla każdego, kto programuje współdzielone komponenty lub po prostu dąży do tego, by jego kod był zgodny ze standardem, skalowalny, bezpieczny i zoptymalizowany. 70 stron czyta się z miłym odczuciem, że nareszcie ktoś uporządkował to nad czym zawsze zastanawiałem się &#8222;czy robię to dobrze?&#8221;.
</p>
<p><span id="more-627"></span></p>
<p style="text-align:justify">
Dział &#8222;Essential types&#8221; również segreguje i porządkuje zagadnienia dotyczące rzeczy, z którymi spotykami się często. Praca z tekstem, typami enumerowanymi, tablicami, interfejsami, typami generycznymi &#8211; po lekturze staje się bardziej przewidywalna i pewna. Same przykłady są naprawdę w porządku. Prezentują często wiele aspektów poruszanego zagadnienia w&nbsp;przystępny sposób. Nie traktują czytelnika jako &#8222;niepełnosprytnego&#8221; wyjaśniając niepotrzebnie każdą linijkę &#8211; oby takie przykłady spotykać w każdej książce.
</p>
<p style="text-align:justify">
Sekcja &#8222;CLR Facilities&#8221; nie jest lekka ale jest niesamowicie przydatna. Świadomość istnienia i sposób działania Garbage Collectora, refleksje i operacje asynchroniczne &#8211; nie taki wilk straszny, jak go malują.
</p>
<p style="text-align:justify">
Książki tej (niemal 650 stron) nie da się przeczytać i zapamiętać wszystkiego. Nie raz jednak wracam do niej podczas codziennej pracy, utrwalając coś, co w danej chwili robię. Sama świadomość, że wiadomo gdzie zajrzeć aby uzyskać pewną podpowiedź czy wskazówkę jest komfortowa. Książka to kompendium, które zwraca uwagę na aspekty często traktowane w innych publikacjach po macoszemu lub wręcz pomijane. &#8222;Important notes&#8221; &#8211; przyciągają uwagę do pułapek, na których można się wyłożyć przy nieumiejętnym używaniu tego, co oferuje C#. Jednocześnie książkę czyta się przyjemnie. Liczne wzmianki o tym, że Microsoft (zdaniem autora) coś schrzanił i ma nadzieję, że naprawią to w następnej wersji przyprawiają o&nbsp;uśmiech i zwracają uwagę na to, że nikt nie jest nieomylny ;) Richter ma co prawda świra na punkcie thread safety, security, wydajności, zasięgu widoczności zmiennych, pieczętowania klas &#8211; i trochę tym zaraża ;) To w sumie jedyny zarzut do książki ;)
</p>
<p style="text-align:justify">
Jeden z przykładów, gdy sedno będzie krótsze niż wstęp ;) Po przeczytaniu &#8222;THE BCL&#8221; zastanawiam się nad połknięciem pozycji stricte &#8222;egzaminowej&#8221; i podejście do MCTS. Propozycja szefostwa i własne obserwacje to <a href="http://www.microsoft.com/learning/en/us/Exam.aspx?ID=70-536&#038;Locale=en-us" onclick="pageTracker._trackPageview('/outgoing/www.microsoft.com/learning/en/us/Exam.aspx?ID=70-536_038_Locale=en-us&amp;referer=');">70-536: Microsoft .NET Framework &#8211; Application Development Foundation</a>. Ktoś z Was miał sposobność zdawać? Jak poszło? Jak się przygotowywaliście? Ile czasu Wam to zajęło? Może ktoś, tak jak ja, dopiero planuje? Czy według Was obecnie takie potwierdzenie umiejętności &#8211; poza własną satysfakcją &#8211; jest przydatne?
</p>
<p style="text-align:justify">
Zapraszam do dyskusji w&nbsp;komentarzach. Myślę, że pomoże to i mi rozwiać niektóre wątpliwości.<br />
Jeśli ktoś chce podzielić się informacją o ciekawej książce (niekoniecznie w tematyce egzaminowej) &#8211; również chętnie zapoznam się z Waszym &#8222;co czytam&#8221;.
</p>
<p><a rev="vote-for" href="http://dotnetomaniak.pl/Ksi%C4%85%C5%BCki-co-czytam" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/Ksi_C4_85_C5_BCki-co-czytam?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F10%2Fksiazki-co-czytam-certyfikacja-czy-warto%2F" style="border:0px"/></a></p>


<p>Nie znaleziono powiązanych wpisów.</p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/10/ksiazki-co-czytam-certyfikacja-czy-warto/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>&#8222;throw&#8221; czy &#8222;throw exc&#8221; &#8211; czyli jak najlepiej przerzucić wyjątek wyżej</title>
		<link>http://andrzej.net.pl/index.php/2009/10/throw-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek/</link>
		<comments>http://andrzej.net.pl/index.php/2009/10/throw-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 22:31:19 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[nowe]]></category>
		<category><![CDATA[pełny stack trace]]></category>
		<category><![CDATA[przerzucenie wyjątku]]></category>
		<category><![CDATA[re-throw]]></category>
		<category><![CDATA[throw]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=613</guid>
		<description><![CDATA[Pewnie nie raz staliście przed sytuacją, w której jakaś z funkcji spowodować może powstanie wyjątku, którego wystąpienie trzeba zalogować i przerzucić go dalej (re-throw), aby aplikacja zajęła się nim jak należy. Jednocześnie idealnie, gdy wyjątek zawierał będzie jak najwięcej informacji. Zalicza się do nich przyjaciel każdego programisty &#8211; StackTrace. Rozpatrzmy poniższy kod: public sealed class [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2010/01/mutex-i-sprawdzanie-czy-aplikacja-jest-jedyna-uruchomiona/' rel='bookmark' title='Permanent Link: Mutex i sprawdzanie czy aplikacja jest jedyną uruchomioną'>Mutex i sprawdzanie czy aplikacja jest jedyną uruchomioną</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p><a rev="vote-for" href="http://dotnetomaniak.pl/throw-czy-throw-exc-czyli-jak-najlepiej-przerzuci%C4%87-wyj%C4%85tek-wy%C5%BCej-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/throw-czy-throw-exc-czyli-jak-najlepiej-przerzuci_C4_87-wyj_C4_85tek-wy_C5_BCej-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F10%2Fthrow-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek%2F" style="border:0px"/></a></p>
<p style="text-align:justify;">
Pewnie nie raz staliście przed sytuacją, w której jakaś z funkcji spowodować może powstanie wyjątku, którego wystąpienie trzeba zalogować i przerzucić go dalej (re-throw), aby aplikacja zajęła się nim jak należy. Jednocześnie idealnie, gdy wyjątek zawierał będzie jak najwięcej informacji. Zalicza się do nich przyjaciel każdego programisty &#8211; <a href="http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx?referer=');">StackTrace</a>.
</p>
<p><span id="more-613"></span></p>
<p style="text-align:justify;">
Rozpatrzmy poniższy kod:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">sealed</span> <span style="color: #6666cc; font-weight: bold;">class</span> SomeClass<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">void</span> SomeTestPublicMethod<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SomeMethod<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">catch</span> <span style="color: #008000;">&#40;</span>ApplicationException exc<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//logujemy blad</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">throw</span> exc<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">void</span> SomeMethod<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> ApplicationException<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Błąd w SomeMethod&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify;">
Czyli testowa klasa, której metodę SomeTestPublicMethod udostępniamy jako publiczną, ona natomiast wywołuje prywatną metodę SomeMethod &#8211; rzucającą wyjątek ApplicationException.<br />
Jak widać wystąpienie wyjątku chcemy zalogować w metodzie SomeTestPublicMethod i rzucić wyjątek dalej. Kod wykonujący nasz &#8222;błędny&#8221; program:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Main<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> args<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SomeClass sc <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> SomeClass<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sc<span style="color: #008000;">.</span><span style="color: #0000FF;">SomeTestPublicMethod</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">catch</span> <span style="color: #008000;">&#40;</span>Exception exc<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>exc<span style="color: #008000;">.</span><span style="color: #0000FF;">Message</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Console<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span>exc<span style="color: #008000;">.</span><span style="color: #0000FF;">StackTrace</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Console<span style="color: #008000;">.</span><span style="color: #0000FF;">ReadLine</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify;">
Czego spodziewacie się w StackTrace? Czy zaprowadzi nas ona do oryginalnej metody SomeMethod, która spowodowała błąd? Otóż niestety nie, StackTrace wygląda tak:
</p>
<div id="attachment_619" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/10/plik024.jpg" rel="lightbox[613]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/10/plik024-300x80.jpg" alt="Niepełny StackTrace" title="Niepełny StackTrace" width="300" height="80" class="size-medium wp-image-619" /></a><p class="wp-caption-text">Niepełny StackTrace</p></div>
<p style="text-align:justify;">
Zauważcie, że Message jest w porządku &#8211; pochodzi z oryginalnie rzuconego wyjątku. Dokładna informacja o&nbsp;linii wskazuje jednak dopiero na miejsce, w&nbsp;którym napisaliśmy &#8222;throw exc;&#8221; &#8211; czyli  SomeTestPublicMethod. Może wydawać się to nieistotne, bez debugowania ciężko byłoby jednak odgadnąć w czym problem i&nbsp;gdzie on tak naprawdę powstaje.<br />
Zamieńmy dosłownie jedną linię &#8211; zamiast &#8222;throw exc&#8221; zróbmy &#8222;throw&#8221;. Efekt?
</p>
<div id="attachment_620" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/10/plik025.jpg" rel="lightbox[613]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/10/plik025-300x97.jpg" alt="Kompletny StackTrace" title="Kompletny StackTrace" width="300" height="97" class="size-medium wp-image-620" /></a><p class="wp-caption-text">Kompletny StackTrace</p></div>
<p style="text-align:justify;">
Różnica? Bogatszy StackTrace wskazujący na oryginalne miejsce powstania błędu &#8211; czyli prywatną metodę SomeMethod. Być może zagadnienie niektórym wydaje się trywialne, ale pamiętajcie &#8211; jeśli chcecie po prostu &#8222;pchnąć&#8221; wyjątek dalej, bez utraty informacji (ani opakowania go we własną klasę wyjątku &#8211; np. przekazując jako InnerException) używajcie samego &#8222;throw&#8221;. Oszczędzić może trochę pracy w przyszłości ;)
</p>
<p><a rev="vote-for" href="http://dotnetomaniak.pl/throw-czy-throw-exc-czyli-jak-najlepiej-przerzuci%C4%87-wyj%C4%85tek-wy%C5%BCej-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/throw-czy-throw-exc-czyli-jak-najlepiej-przerzuci_C4_87-wyj_C4_85tek-wy_C5_BCej-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F10%2Fthrow-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek%2F" style="border:0px"/></a></p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2010/01/mutex-i-sprawdzanie-czy-aplikacja-jest-jedyna-uruchomiona/' rel='bookmark' title='Permanent Link: Mutex i sprawdzanie czy aplikacja jest jedyną uruchomioną'>Mutex i sprawdzanie czy aplikacja jest jedyną uruchomioną</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/10/throw-czy-throw-exc-czyli-jak-najlepiej-przerzucic-wyjatek/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Własny validator w ASP.NET – CheckBoxListValidator</title>
		<link>http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/</link>
		<comments>http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 22:18:58 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[checkboxlistvalidator]]></category>
		<category><![CDATA[custom validator]]></category>
		<category><![CDATA[walidacja checkboxlist]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=589</guid>
		<description><![CDATA[W przedostatnim wpisie, poruszyłem temat napisania własnego walidatora do daty. Dziś napotkałem na podobny problem &#8211; walidacja kontrokli CheckBoxList pod kątem zaznaczenia przynajmniej jednej wartości. Jakieś było moje zaskoczenie ;-) gdy okazało się, że żadna z&#160;domyślnych kontrolek walidatorów nie potrafi tego niezmiernie skomplikowanego zadania wykonać ;-) Oczywiście można to załatwić banalnie: CustomValidator i odpowiednia prosta [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET &#8211; Date Validator'>Własny validator w ASP.NET &#8211; Date Validator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/09/wylaczenie-validatora-w-asp-net-po-stronie-klienta/' rel='bookmark' title='Permanent Link: Wyłączenie validatora w ASP.NET po stronie klienta'>Wyłączenie validatora w ASP.NET po stronie klienta</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p><a rev="vote-for" href="http://dotnetomaniak.pl/W%C5%82asny-validator-w-ASPNET-CheckBoxListValidator-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/W_C5_82asny-validator-w-ASPNET-CheckBoxListValidator-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F09%2Fwlasny-validator-w-asp-net-%25e2%2580%2593-checkboxlistvalidator%2F" style="border:0px"/></a></p>
<p style="text-align:justify">
W przedostatnim wpisie, poruszyłem temat napisania <a href="http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/">własnego walidatora do daty</a>. Dziś napotkałem na podobny problem &#8211; walidacja kontrokli CheckBoxList pod kątem zaznaczenia przynajmniej jednej wartości. Jakieś było moje zaskoczenie ;-) gdy okazało się, że żadna z&nbsp;domyślnych kontrolek walidatorów nie potrafi tego niezmiernie skomplikowanego zadania wykonać ;-) Oczywiście można to załatwić banalnie: CustomValidator i odpowiednia prosta funkcja. Gdzie jednak ponowne wykorzystanie kodu &#8211; tak przecież przez nas wszystkich lubiane :) W kolejnym projekcie, na kolejnej stronie &#8211; nie będziemy przecież kopiować kodu.<br />
<span id="more-589"></span>
</p>
<p>W związku z tym, że większość kodu dla walidatorów jest wspólna (różnią się tylko funkcją EvaluateIsValid oraz kodem JS) nie będę zbyt mocno się rozpisywał. Oto kod:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> CheckBoxListValitator <span style="color: #008000;">:</span> BaseValidator<br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">bool</span> ControlPropertiesValid<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">return</span> FindControl<span style="color: #008000;">&#40;</span>ControlToValidate<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> CheckBoxList <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">bool</span> EvaluateIsValid<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>FindControl<span style="color: #008000;">&#40;</span>ControlToValidate<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> CheckBoxList<span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">SelectedItem</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnPreRender<span style="color: #008000;">&#40;</span>EventArgs e<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">.</span><span style="color: #0000FF;">OnPreRender</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>ControlPropertiesValid<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">EnableClientScript</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterClientScriptResource</span><span style="color: #008000;">&#40;</span>GetType<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #666666;">&quot;WebControls.Resources.checkboxlist_validate.js&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterExpandoAttribute</span><span style="color: #008000;">&#40;</span>ClientID, <span style="color: #666666;">&quot;evaluationfunction&quot;</span>, <span style="color: #666666;">&quot;validate_CBL&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p>Wszystko wygląda standardowo:</p>
<ul>
<li><strong>ControlPropertiesValid</strong> &#8211; sprawdzamy, czy kontrolka, której ID trzyma property ControlToValidate jest rzeczywiście kontrolką typu CheckBoxList</li>
<li><strong>EvaluateIsValid</strong> &#8211; sprawdzamy, czy jakikolwiek element został zaznaczony</li>
<li><strong>OnPreRender</strong> &#8211; podłączamy nasz kod do walidacji po stronie klienta</li>
</ul>
<p style="text-align:justify">
Kod do walidacji CheckBoxLista po stronie klienta również nie jest zbyt skomplikowany. CheckBoxList jest renderowany jako tabelka, w której komórki są zestawem: input typu checkbox + label z atrybutem for. Wystarczy więc pętlą &#8222;przelecieć&#8221; po wszystkich elementach tabelki typu checkbox i sprawdzić, czy którykolwiek z nich jest zaznaczony.</p>
<div id="attachment_594" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/09/plik020.jpg" rel="lightbox[589]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/09/plik020-300x68.jpg" alt="CheckBoxList renderowany jako tabelka" title="CheckBoxList renderowany jako tabelka" width="300" height="68" class="size-medium wp-image-594" /></a><p class="wp-caption-text">CheckBoxList renderowany jako tabelka</p></div>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> validate_CBL<span style="color: #009900;">&#40;</span>sender<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> val <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>sender.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">controltovalidate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> col <span style="color: #339933;">=</span> val.<span style="color: #660066;">getElementsByTagName</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;*&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>col <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> col.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>col.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">tagName</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;INPUT&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>col.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">checked</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align:justify">
Gotowe. Nasz skrypt podłączamy tak jako ostatnio &#8211; w zasobach, rejestrując go w pliku AssemblyInfo.cs, w folderze Properties projektu. Jednocześnie oczywiście nie zapominamy o ustawieniu we właściwościah naszego pliku Build Action na Embedded Resource ;)</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&#91;</span>assembly<span style="color: #008000;">:</span> WebResource<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;WebControls.Resources.checkboxlist_validator.js&quot;</span>, <span style="color: #666666;">&quot;application/x-javascript&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span></div></div>
<p>Demo:<br />
<a href="http://asp.andrzej.net.pl/" onclick="pageTracker._trackPageview('/outgoing/asp.andrzej.net.pl/?referer=');">asp.andrzej.net.pl</a></p>
<p>Kod do pobrania:<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p>
<p><a rev="vote-for" href="http://dotnetomaniak.pl/W%C5%82asny-validator-w-ASPNET-CheckBoxListValidator-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/W_C5_82asny-validator-w-ASPNET-CheckBoxListValidator-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F09%2Fwlasny-validator-w-asp-net-%25e2%2580%2593-checkboxlistvalidator%2F" style="border:0px"/></a></p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET &#8211; Date Validator'>Własny validator w ASP.NET &#8211; Date Validator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/09/wylaczenie-validatora-w-asp-net-po-stronie-klienta/' rel='bookmark' title='Permanent Link: Wyłączenie validatora w ASP.NET po stronie klienta'>Wyłączenie validatora w ASP.NET po stronie klienta</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Własny validator w ASP.NET &#8211; Date Validator</title>
		<link>http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/</link>
		<comments>http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 22:25:11 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[asp.net custom validator]]></category>
		<category><![CDATA[date validator]]></category>
		<category><![CDATA[walidacja daty po stronie klienta]]></category>
		<category><![CDATA[własny validator]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=556</guid>
		<description><![CDATA[Kilka dni temu powstał w mej głowie misterny plan opakowania DatePickera od jQuery we własną kontrolkę ASP.NET. Dość łatwo poszło (postaram się to opisać w kolejnym wpisie), jednak chciałem jednocześnie móc walidować wprowadzone dane po stronie klienta i serwera. Niezbędne więc okazało się napisanie własnego Validatora. Nie jest to zadanie zbyt trudne &#8211; przedstawię dziś [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET – CheckBoxListValidator'>Własny validator w ASP.NET – CheckBoxListValidator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/09/wylaczenie-validatora-w-asp-net-po-stronie-klienta/' rel='bookmark' title='Permanent Link: Wyłączenie validatora w ASP.NET po stronie klienta'>Wyłączenie validatora w ASP.NET po stronie klienta</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/' rel='bookmark' title='Permanent Link: Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#'>Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p><a rev="vote-for" href="http://dotnetomaniak.pl/W%C5%82asny-validator-w-ASPNET-Date-Validator-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/W_C5_82asny-validator-w-ASPNET-Date-Validator-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F09%2Fwlasny-validator-w-asp-net-date-validator%2F" style="border:0px"/></a></p>
<p style="text-align:justify">
<p>Kilka dni temu powstał w mej głowie misterny plan opakowania <a href="http://jqueryui.com/demos/datepicker/" onclick="pageTracker._trackPageview('/outgoing/jqueryui.com/demos/datepicker/?referer=');">DatePickera od jQuery</a> we własną kontrolkę ASP.NET. Dość łatwo poszło (postaram się to opisać w kolejnym wpisie), jednak chciałem jednocześnie móc walidować wprowadzone dane po stronie klienta i serwera. Niezbędne więc okazało się napisanie własnego Validatora. Nie jest to zadanie zbyt trudne &#8211; przedstawię dziś sposób na jego realizację.</p>
<p><span id="more-556"></span></p>
<p style="text-align:justify">
Nasza kontrolka &#8211; nazwijmy ją DateValidator &#8211; nie jest kontrolką wizualną. Nie będzie to więc plik ascx a cs &#8211; zwykła klasa. Ja zdecydowałem się na stworzenie oddzielnego assembly &#8211; dzięki temu nasz validator wykorzystać będzie łatwo w wielu projektach. <strong>Od razu zaznaczę &#8211; całośc jest realizowana dla założenia formatu daty dd-MM-yyyy</strong>.</p>
<p style="text-align:justify">
Pierwszym krokiem, jaki musimy poczynić, jest wydziedziczenie naszej klasy z klasy <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator.aspx?referer=');">BaseValidator</a> (niezbędne jest dodanie do projektu referencji do <a href="http://msdn.microsoft.com/en-us/library/system.web.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.aspx?referer=');">System.Web</a>).</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> DateValidator <span style="color: #008000;">:</span> BaseValidator<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #008000;">...</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
Następnie zaimplementujmy abstrakcyjną metodę <em>EvaluateIsValid</em>. Można to bardzo sprytnie wykonać z&nbsp;menu kontekstowego wywołanego na klasie bazowej:</p>
<div id="attachment_560" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/09/plik018.jpg" rel="lightbox[556]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/09/plik018-300x227.jpg" alt="Implementacja abstrakcyjnych metod z menu kontekstowego" title="Implementacja abstrakcyjnych metod z menu kontekstowego" width="300" height="227" class="size-medium wp-image-560" /></a><p class="wp-caption-text">Implementacja abstrakcyjnych metod z menu kontekstowego</p></div>
<p style="text-align:justify">Porzućmy na chwilę tę metodę &#8211; wrócimy do niej.</p>
<p style="text-align:justify">Z racji tego, że nasza kontrolka do wprowadzania daty będzie dziedziczona z TextBoxa musimy sprawdzić, czy kontrolka, której ID przekaże użytkownik korzystając z property <em>ControlToValidate</em> wskazywać będzie właśnie na kontrolkę tego typu. W tym celu musimy nadpisać metodę klasy bazowej &#8211; <em>ControlPropertiesValid</em>. Wystarczy, że odszukamy naszą kontrolkę i sprawdzimy jej typ:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">bool</span> ControlPropertiesValid<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">return</span> <span style="color: #008000;">&#40;</span>FindControl<span style="color: #008000;">&#40;</span>ControlToValidate<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> TextBox<span style="color: #008000;">&#41;</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
Wróćmy teraz do implementacji metody <em>EvaluateIsValid</em>. Będzie ona odpowiedzialna za walidację wartości naszego TextBoxa do wprowadzania daty po stronie serwera.
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">bool</span> EvaluateIsValid<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">bool</span> ret <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TextBox ctrl <span style="color: #008000;">=</span> FindControl<span style="color: #008000;">&#40;</span>ControlToValidate<span style="color: #008000;">&#41;</span> <span style="color: #0600FF; font-weight: bold;">as</span> TextBox<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">try</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DateTime<span style="color: #008000;">.</span><span style="color: #0000FF;">ParseExact</span><span style="color: #008000;">&#40;</span>ctrl<span style="color: #008000;">.</span><span style="color: #0000FF;">Text</span>, <span style="color: #666666;">&quot;dd-MM-yyyy&quot;</span>, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">catch</span> <span style="color: #008000;">&#40;</span>FormatException exc<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ret <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">return</span> ret<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
Jedyne co nam pozostało to podłączenie JavaScriptu do walidacji po stronie klienta. Jest to bardzo wygodna forma walidacji &#8211; niepotrzebny jest PostBack z cały odsyłaniem zawartości formularza tylko po to, aby sprawdzić, czy użytkownik wprowadził datę poprawnie. Jeden ze sposobów podłączania JS został pokazany we <a href="http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/">wcześniejszym wpisie</a>. Jednak nie uważam go za wygodny &#8211; konserwacja, zmiana czegokolwiek jest dość uciążliwa. Możemy użyć czegoś innego &#8211; Resource&#8217;ów. Pozwoli to na trzymanie kodu JS w odrębnym pliku &#8211; łatwym do ewentualnych poprawek. Utwórzmy więc folder Resources wewnątrz naszego projektu i dodajmy do niego plik date_validate.js. Uwaga &#8211; <strong>bardzo ważne</strong> jest ustawienie we właściwościach dodanego pliku atrybutu <strong>Build Action</strong> na <strong>Embedded Resource</strong>. Bez tego nic nie będzie później działać ;-)</p>
<div id="attachment_568" class="wp-caption aligncenter" style="width: 243px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/09/plik019.jpg" rel="lightbox[556]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/09/plik019-233x300.jpg" alt="Dodanie folderu i pliku zasobów do projektu" title="Dodanie folderu i pliku zasobów do projektu" width="233" height="300" class="size-medium wp-image-568" /></a><p class="wp-caption-text">Dodanie folderu i pliku zasobów do projektu</p></div>
<p style="text-align:justify">
Funkcja JS do walidacji musi przyjmować jeden parametr &#8211; sender, oraz zwracać wartości true / false.
</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> CheckDate<span style="color: #009900;">&#40;</span>sender<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> dateStr <span style="color: #339933;">=</span> document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>sender.<span style="color: #660066;">id</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">controltovalidate</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> reg1 <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>reg1.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>dateStr<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> parts <span style="color: #339933;">=</span> dateStr.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span>RegExp.$<span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> day <span style="color: #339933;">=</span> parts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> month <span style="color: #339933;">=</span> parts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> year <span style="color: #339933;">=</span> parts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
<br />
<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> dt <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span>parseFloat<span style="color: #009900;">&#40;</span>year<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> parseFloat<span style="color: #009900;">&#40;</span>month<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> parseFloat<span style="color: #009900;">&#40;</span>day<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>parseFloat<span style="color: #009900;">&#40;</span>day<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> dt.<span style="color: #660066;">getDate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>parseFloat<span style="color: #009900;">&#40;</span>month<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">!=</span> dt.<span style="color: #660066;">getMonth</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align:justify">
Dość istotna jest pierwsza linia ciała funkcji. Pobieramy tutaj wartość naszego TextBoxa (a właściwie pola input typu text). Jak widać <strong>sender</strong> to nasz walidator. Jego property controltovalidate to id kontrolki, którą walidujemy. Wystarczy więc przez polecenie document.getElementById odnaleźć ją i pobrać jej wartość. Samego kodu do walidacji daty nie będę omawiał. Po krótce: do wstępnej walidacji używane są wyrażenia regularne, następnie sprawdzana jest po kolei poprawność daty, tzn. czy ktoś nie wprowadził 31 dnia lutego itp.</p>
<p style="text-align:justify">
Teraz zajmiemy się podłączeniem kodu JS do strony. Najlepiej wykonywać to podczas fazy <strong>PreRender</strong>. Nie ma zupełnego sensu wcześniej podłączać JS, gdyż np. w fazie Load Visible kontrolki może zostać wyłączona. Wywołanie PreRender zapewnia, że kontrolka będzie widoczna i podłączenie samego kodu ma sens.<br />
Zanim zajmiemy się samym podłączeniem kodu, musimy nasz plik zarejestrować w Assembly jako osadzony zasób. Ogranicza się to do jednego wpisu, którego dokonujemy w pliku <strong>AssemblyInfo.cs</strong> w katalogu specjalnym <strong>Properties</strong> naszego projektu:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&#91;</span>assembly<span style="color: #008000;">:</span> WebResource<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;WebControls.Resources.date_validate.js&quot;</span>, <span style="color: #666666;">&quot;application/x-javascript&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#93;</span></div></div>
<p style="text-align:justify">
Czas na ostatni krok. Nadpisujemy metodę <strong>OnPreRender</strong>:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #0600FF; font-weight: bold;">override</span> <span style="color: #6666cc; font-weight: bold;">void</span> OnPreRender<span style="color: #008000;">&#40;</span>EventArgs e<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">base</span><span style="color: #008000;">.</span><span style="color: #0000FF;">OnPreRender</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span>ControlPropertiesValid<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&amp;&amp;</span> <span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span><span style="color: #0000FF;">EnableClientScript</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterClientScriptResource</span><span style="color: #008000;">&#40;</span>GetType<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #666666;">&quot;WebControls.Resources.date_validate.js&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterExpandoAttribute</span><span style="color: #008000;">&#40;</span>ClientID, <span style="color: #666666;">&quot;evaluationfunction&quot;</span>, <span style="color: #666666;">&quot;CheckDate&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
Zwróćcie uwagę na dwa aspekty &#8211; upewniamy się przed podłączeniem, że kontrolka jest odpowiedniego typu (pierwszy warunek) i czy włączona jest walidacja po stronie klienta. Dopiero wtedy korzystając z ClientScriptManagera podłączamy nasz skrypt z zasobów i rejestrujemy naszego delegata evaluationfunction. Gotowe!<br />
Przykład użycia:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&lt;</span>asp<span style="color: #008000;">:</span>ValidationSummary runat<span style="color: #008000;">=</span><span style="color: #666666;">&quot;server&quot;</span> ID<span style="color: #008000;">=</span><span style="color: #666666;">&quot;vSummary&quot;</span> <span style="color: #008000;">/&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;</span>asp<span style="color: #008000;">:</span>TextBox runat<span style="color: #008000;">=</span><span style="color: #666666;">&quot;server&quot;</span> ID<span style="color: #008000;">=</span><span style="color: #666666;">&quot;Date&quot;</span><span style="color: #008000;">&gt;&lt;/</span>asp<span style="color: #008000;">:</span>TextBox<span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;</span>uc<span style="color: #008000;">:</span>DateValidator runat<span style="color: #008000;">=</span><span style="color: #666666;">&quot;server&quot;</span> ID<span style="color: #008000;">=</span><span style="color: #666666;">&quot;dvDate&quot;</span> ControlToValidate<span style="color: #008000;">=</span><span style="color: #666666;">&quot;Date&quot;</span> Text<span style="color: #008000;">=</span><span style="color: #666666;">&quot;*&quot;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ErrorMessage<span style="color: #008000;">=</span><span style="color: #666666;">&quot;Wprowadzona data nie jest poprawna&quot;</span><span style="color: #008000;">&gt;&lt;/</span>uc<span style="color: #008000;">:</span>DateValidator<span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;</span>asp<span style="color: #008000;">:</span>Button runat<span style="color: #008000;">=</span><span style="color: #666666;">&quot;server&quot;</span> ID<span style="color: #008000;">=</span><span style="color: #666666;">&quot;PostBack&quot;</span> Text<span style="color: #008000;">=</span><span style="color: #666666;">&quot;Go!&quot;</span> <span style="color: #008000;">/&gt;</span></div></div>
<p style="text-align:justify">
Oczywiście wpisywanie daty do takiego prostego pola input jest uciążliwe. Dlatego w jednym z kolejnych wpisów przedstawię sposób na zbudowanie interesującego DatePickera z&nbsp;wykorzystaniem jQuery.</p>
<p><strong>DEMO:</strong><br />
<a href="http://asp.andrzej.net.pl/" onclick="pageTracker._trackPageview('/outgoing/asp.andrzej.net.pl/?referer=');">http://asp.andrzej.net.pl/</a></p>
<p><strong>Plik do pobrania:</strong><br />
Note: There is a file embedded within this post, please visit this post to download the file.
</p>
<p><a rev="vote-for" href="http://dotnetomaniak.pl/W%C5%82asny-validator-w-ASPNET-Date-Validator-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/W_C5_82asny-validator-w-ASPNET-Date-Validator-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F09%2Fwlasny-validator-w-asp-net-date-validator%2F" style="border:0px"/></a></p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET – CheckBoxListValidator'>Własny validator w ASP.NET – CheckBoxListValidator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/09/wylaczenie-validatora-w-asp-net-po-stronie-klienta/' rel='bookmark' title='Permanent Link: Wyłączenie validatora w ASP.NET po stronie klienta'>Wyłączenie validatora w ASP.NET po stronie klienta</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/' rel='bookmark' title='Permanent Link: Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#'>Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Show-hide JavaScript &#8211; proste podłączenie przy użyciu C#</title>
		<link>http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/</link>
		<comments>http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/#comments</comments>
		<pubDate>Sun, 16 Aug 2009 17:25:50 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[javascript C# ukrywanie]]></category>
		<category><![CDATA[show hide script]]></category>
		<category><![CDATA[ukrywanie DIV]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=410</guid>
		<description><![CDATA[Przedstawiam prosty sposób na automatyczne podłączanie kodu javascript do ukrywania elementów na stronie, przy uzyciu prostego skryptu C#. Rozwiązanie dla każdego, kto chce sobie uprzyjemnić pisanie stron w ASP.NET.


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET &#8211; Date Validator'>Własny validator w ASP.NET &#8211; Date Validator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET – CheckBoxListValidator'>Własny validator w ASP.NET – CheckBoxListValidator</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p><a rev="vote-for" href="http://dotnetomaniak.pl/Show-hide-JavaScript-proste-pod%C5%82%C4%85czenie-przy-u%C5%BCyciu-C-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/Show-hide-JavaScript-proste-pod_C5_82_C4_85czenie-przy-u_C5_BCyciu-C-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F08%2Fshow-hide-javascript-proste-podlaczenie-przy-uzyciu-c%2F" style="border:0px"/></a><br />
Sponsorem dzisiejszego odcinka są:</p>
<ul>
<li>JavaScript</li>
<li>Panel</li>
<li>anchor, czyli tag &#60;a href=&#8221;"&#62;</li>
</ul>
<p><strong>Cel: podłączanie JS typu &#8222;pokaż &#8211; ukryj div po kliknięciu w link&#8221; jedną linijką kodu w&nbsp;C#</strong></p>
<p style="text-align: justify;">Nie wiem czy to rozwiązanie się Wam spodoba, nie wiem czy jest zgodne z arkanami sztuki JS. Jednak mam to gdzieś ;-) Pracuję nad małym projektem, w&nbsp;którym na stronie znajduje się sporo danych. Są one pogrupowane panelami ASP  (czyli po wyrenderowaniu &#8211; DIV-ami), którym zapewnić trzeba możliwość ukrywania / pokazywania za pomocą prostego linku (anchor).</p>
<p><span id="more-410"></span></p>
<p style="text-align: justify;">Jako, że nie stanowi problemu nadanie atrybutu runat=&#8221;server&#8221;  odpowiedniemu linkowi, postanowiłem zastosować pewien trick celem ułatwienia sobie życia. Prześledźmy to na podstawie &#8222;modułu&#8221; komentarzy. Do ukrycia mamy całą sekcję, która jest generowana przy użyciu kontrolki repeater.</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;asp:Panel runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">ID</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;pComments&quot;</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;asp:UpdatePanel runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">ID</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;upPanel&quot;</span> UpdateMode<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Conditional&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;ContentTemplate&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;asp:<span style="color: #000066;">Label</span> runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">ID</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;lblInfo&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span>asp:Label&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;asp:Repeater runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">ID</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;repComments&quot;</span> EnableViewState<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;false&quot;</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;ItemTemplate&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;......<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>ItemTemplate&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>asp:Repeater&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>ContentTemplate&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>asp:UpdatePanel&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>asp:Panel&gt;</span></div></div>
<p style="text-align: justify;">Ukrywaniem ma zająć się link:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h3</span>&gt;</span>Komentarze:<br />
<br />
(<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;aComments&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>)<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h3</span>&gt;</span></div></div>
<p style="text-align: justify;">Oczywiście tekst wyświetlany w innerHTML anchora, powinien zmieniać się w zależności od tego, czy blok jest widoczny czy nie. Wyszperałem prosty skrypt js do ukrywania i&nbsp;pokazywania elementów i&nbsp;zmodyfikowałem go na własne potrzeby. Przetestowałem &#8211; działa w przeglądarkach: IE (v. 6,7,8) FF&nbsp;(&nbsp;v.&nbsp;1.0&nbsp;-&nbsp;3.5) oraz Opera (do v. 10):</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> jchange<span style="color: #009900;">&#40;</span>elemToHideId<span style="color: #339933;">,</span> showHideElemId<span style="color: #339933;">,</span> textWhenVisible<span style="color: #339933;">,</span> textWhenHide<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>elemToHideId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'none'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>elemToHideId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'block'</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>showHideElemId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> textWhenVisible<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>elemToHideId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">style</span>.<span style="color: #660066;">display</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'none'</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">getElementById</span><span style="color: #009900;">&#40;</span>showHideElemId<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> textWhenHide<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p style="text-align: justify;">Jak widać, funkcja JS powinna dostać ID kontrolki do ukrycia, ID kontrolki ukrywającej oraz dwa teksty: jeden dla schowanego i jeden dla pokazanego DIVa. Teraz pozostaje nam napisać funkcję w C#, która za nas zajmie się podłączaniem JS i renderowaniem go na stronie. Dzięki temu nie trzeba będzie pamiętać o&nbsp;dołączaniu zewnętrznego pliku JS lub &#8211; co gorsze &#8211; w pisaniu go samemu za każdym razem ;-)</p>
<p style="text-align: justify;">Nasza statyczna funkcja w C# powinna otrzymać:</p>
<ul>
<li>referencję do strony (w celu podłączenia do niej bloku kodu js)</li>
<li>referencję do kontrolki &#8222;do ukrycia&#8221; &#8211; czyli naszego Panelu</li>
<li>referencję do kontrolki &#8222;ukrywającej&#8221; &#8211; czyli naszego anchora</li>
<li>dwóch tekstów, które pokaże anchor w zależności od stanu</li>
<li>parametru typu bool &#8211; decydującego o tym, czy domyślnie dany DIV ma być ukryty czy nie</li>
</ul>
<p style="text-align: justify;">
Dzięki temu, że każda strona w property <strong>ClientScript</strong> posiada instancję <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.clientscriptmanager.aspx?referer=');">ClientScriptManager&#8217;a</a>, możemy bardzo łatwo podłączyć do niej wygenerowany kod js. Kod identyfikowany jest wewnętrznie przez klucz typu string. Pamiętajmy, aby najpierw wykonać sprawdzenie (żeby wielokrotnie nie dołączyć tego samego bloku js do strony):
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6666cc; font-weight: bold;">string</span> key <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;ShowHideScript&quot;</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> AttachShowHideScript<span style="color: #008000;">&#40;</span>Page page, Panel controlToHide, HtmlAnchor switchControl, <span style="color: #6666cc; font-weight: bold;">string</span> textWhenHide, <span style="color: #6666cc; font-weight: bold;">string</span> textWhenVisible, <span style="color: #6666cc; font-weight: bold;">bool</span> initiallyVisible<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsClientScriptBlockRegistered</span><span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">//tutaj podłączamy skrypt</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align: justify;">W celu uniknięcia efektu <a href="http://pl.wikipedia.org/wiki/Spaghetti_code" onclick="pageTracker._trackPageview('/outgoing/pl.wikipedia.org/wiki/Spaghetti_code?referer=');">spaghetti code</a> do renderowania samego kodu JS najlepiej posłyżyć się obiektem klasy <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.htmltextwriter.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.htmltextwriter.aspx?referer=');">HtmlTextWriter</a>.<br />
W naszym przypadku wygenerowanie JS będzie banalne, wystarczy stworzyć instancję klasy <a href="http://msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx?referer=');">StringWriter</a>, następnie instancję wspomnianego HtmlTextWriter, przekazując mu w konstruktorze referencję do StringWritera.
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">StringWriter sw <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StringWriter<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
HtmlTextWriter writer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> HtmlTextWriter<span style="color: #008000;">&#40;</span>sw<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p style="text-align: justify;">
Sterując ładnie wcięciami, opakowujemy nasz JS przekazując go linia po linii do metody WriteLine:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;function jchange(elemToHideId, showHideElemId, textWhenVisible, textWhenHide) {&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;if (document.getElementById(elemToHideId).style.display == 'none') {&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(elemToHideId).style.display = 'block';&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(showHideElemId).innerHTML = textWhenVisible;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;} else {&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(elemToHideId).style.display = 'none';&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(showHideElemId).innerHTML = textWhenHide;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;}&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span><br />
writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;}&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p style="text-align:justify">
Następnie rejestrujemy kod na stronie, której referencja została nam przekazana:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterClientScriptBlock</span><span style="color: #008000;">&#40;</span>page<span style="color: #008000;">.</span><span style="color: #0000FF;">GetType</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, key, sw<span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p style="text-align: justify;">
Kolejnym krokiem jest podłączenie do zdarzenia onClick kontrolki anchor, wywołania funkcji javascript. Dostęp do tego zdarzenia w CodeBehind mamy przez property <strong>Attributes</strong>. Używając String.Format konstruujemy blok wywołania:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">Attributes</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;onClick&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Format</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;jchange('{0}', '{1}', '{2}', '{3}')&quot;</span>, controlToHide<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientID</span>, switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientID</span>, textWhenVisible, textWhenHide<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p style="text-align: justify;">
Ostatni krok &#8211; ustawiamy tekst wyświetlany przez anchor oraz &#8222;widzialność&#8221; samego DIVa, zgodnie z&nbsp;wartością przekazaną przez parametr initiallyVisble:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>initiallyVisible<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; controlToHide<span style="color: #008000;">.</span><span style="color: #0000FF;">Style</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;display&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;block&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">InnerHtml</span> <span style="color: #008000;">=</span> textWhenVisible<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; controlToHide<span style="color: #008000;">.</span><span style="color: #0000FF;">Style</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;display&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;none&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">InnerHtml</span> <span style="color: #008000;">=</span> textWhenHide<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
To wszystko. Teraz wystarczy (<strong>nie zapominając o nadaniu anchorowi atrybutu runat=&#8221;server&#8221;</strong>) wywołać naszą funkcję, najlepiej na zdarzeniu PreRender strony:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #6666cc; font-weight: bold;">void</span> Page_PreRender<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, EventArgs e<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; AttachShowHideScript<span style="color: #008000;">&#40;</span>Page, pComments, aComments, <span style="color: #666666;">&quot;pokaż&quot;</span>, <span style="color: #666666;">&quot;ukryj&quot;</span>, <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">
Jeszcze raz kompletny kod funkcji:
</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> AttachShowHideScript<span style="color: #008000;">&#40;</span>Page page, Panel controlToHide, HtmlAnchor switchControl, <span style="color: #6666cc; font-weight: bold;">string</span> textWhenHide, <span style="color: #6666cc; font-weight: bold;">string</span> textWhenVisible, <span style="color: #6666cc; font-weight: bold;">bool</span> initiallyVisible<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">string</span> key <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;ShowHideScript&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">IsClientScriptBlockRegistered</span><span style="color: #008000;">&#40;</span>key<span style="color: #008000;">&#41;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">false</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; StringWriter sw <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StringWriter<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; HtmlTextWriter writer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> HtmlTextWriter<span style="color: #008000;">&#40;</span>sw<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;function jchange(elemToHideId, showHideElemId, textWhenVisible, textWhenHide) {&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;if (document.getElementById(elemToHideId).style.display == 'none') {&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(elemToHideId).style.display = 'block';&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(showHideElemId).innerHTML = textWhenVisible;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;} else {&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">3</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(elemToHideId).style.display = 'none';&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;document.getElementById(showHideElemId).innerHTML = textWhenHide;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">2</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;}&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">Indent</span> <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; writer<span style="color: #008000;">.</span><span style="color: #0000FF;">WriteLine</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;}&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; page<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientScript</span><span style="color: #008000;">.</span><span style="color: #0000FF;">RegisterClientScriptBlock</span><span style="color: #008000;">&#40;</span>page<span style="color: #008000;">.</span><span style="color: #0000FF;">GetType</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, key, sw<span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">Attributes</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;onClick&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Format</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;jchange('{0}', '{1}', '{2}', '{3}')&quot;</span>, controlToHide<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientID</span>, switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">ClientID</span>, textWhenVisible, textWhenHide<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>initiallyVisible<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; controlToHide<span style="color: #008000;">.</span><span style="color: #0000FF;">Style</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;display&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;block&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">InnerHtml</span> <span style="color: #008000;">=</span> textWhenVisible<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">else</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; controlToHide<span style="color: #008000;">.</span><span style="color: #0000FF;">Style</span><span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;display&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;none&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; switchControl<span style="color: #008000;">.</span><span style="color: #0000FF;">InnerHtml</span> <span style="color: #008000;">=</span> textWhenHide<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Oraz kompletny kod HTML.</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h3</span>&gt;</span><br />
&nbsp; &nbsp; Komentarze:<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;asp:<span style="color: #000066;">Label</span> runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">ID</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;lblCommentsCount&quot;</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>asp:Label&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span> runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;aComments&quot;</span>&gt;</span>tutaj będzie tekst &quot;pokaż&quot; / &quot;ukryj&quot;<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h3</span>&gt;</span><br />
<span style="color: #009900;">&lt;asp:Panel runat<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;server&quot;</span> <span style="color: #000066;">ID</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;pComments&quot;</span>&gt;</span><br />
Wszystko tutaj będzie ukrywane<br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>asp:Panel&gt;</span></div></div>
<p><br/></p>
<p>Oto efekt w kodzie wygenerowanej strony:</p>
<div id="attachment_439" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik0011.jpg" rel="lightbox[410]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik0011-300x92.jpg" alt="Wygenerowany JS" title="Wygenerowany JS" width="300" height="92" class="size-medium wp-image-439" /></a><p class="wp-caption-text">Wygenerowany JS</p></div><br />
<br/><br />
<div id="attachment_440" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik0021.jpg" rel="lightbox[410]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik0021-300x33.jpg" alt="... oraz automatycznie podpięty pod kontrolki" title="... oraz automatycznie podpięty pod kontrolki" width="300" height="33" class="size-medium wp-image-440" /></a><p class="wp-caption-text">... oraz automatycznie podpięty pod kontrolki</p></div>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-date-validator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET &#8211; Date Validator'>Własny validator w ASP.NET &#8211; Date Validator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET – CheckBoxListValidator'>Własny validator w ASP.NET – CheckBoxListValidator</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/08/show-hide-javascript-proste-podlaczenie-przy-uzyciu-c/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Przewodnik po polskich blogach poświęconych C#&#160;i&#160;.NET</title>
		<link>http://andrzej.net.pl/index.php/2009/08/przewodnik-po-polskich-blogach-poswieconych-c-i-net/</link>
		<comments>http://andrzej.net.pl/index.php/2009/08/przewodnik-po-polskich-blogach-poswieconych-c-i-net/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 14:53:04 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[wyszperane]]></category>
		<category><![CDATA[blog C#]]></category>
		<category><![CDATA[blogi o programowaniu]]></category>
		<category><![CDATA[katalog blogów]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=382</guid>
		<description><![CDATA[Na blogu Macieja Zbrzeznego pojawił się mały przewodnik po polskich blogach poświęconych C# i .NET. Zachęcam do lektury. Kilka blogów wartych jest miejsca w RSS każdego, kto programuje &#8211; czy to zawodowo czy dla przyjemności. Chociaż chwilka, czy pierwsza opcja wyklucza drugą ;-) ? Jak sam autor napisał lista i opisy mają charakter dość subiektywny, [...]


Nie znaleziono powiązanych wpisów.

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Na <a href="http://maciej-progtech.blogspot.com/" onclick="pageTracker._trackPageview('/outgoing/maciej-progtech.blogspot.com/?referer=');">blogu Macieja Zbrzeznego</a> pojawił się mały przewodnik <a href="http://maciej-progtech.blogspot.com/2009/07/blog-c-net-czyli-moj-mini-przewodnik-po.html" onclick="pageTracker._trackPageview('/outgoing/maciej-progtech.blogspot.com/2009/07/blog-c-net-czyli-moj-mini-przewodnik-po.html?referer=');">po polskich blogach poświęconych C# i .NET</a>. Zachęcam do lektury. Kilka blogów wartych jest miejsca w RSS każdego, kto programuje &#8211; czy to zawodowo czy dla przyjemności. Chociaż chwilka, czy pierwsza opcja wyklucza drugą ;-) ?</p>
<p>Jak sam autor napisał</p>
<blockquote><p>lista i opisy mają charakter dość subiektywny, nie mam zamiaru oceniać, czy wskazywać najlepszego. Kolejność została ustalona w sposób nie zamierzony</p></blockquote>
<p style="text-align: justify;">Taka (krótka) lista aktualnych blogów (czyli takich, na których pojawiały się wpisy w ostatnich miesiącach) jest moim zdaniem bardziej przydatną niż tasiemiec zawierający blogi-zombi.</p>
<address>ps: albo mi się wydaje, albo na blogspocie nie znalazłem opcji trackback&#8230; </address>


<p>Nie znaleziono powiązanych wpisów.</p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/08/przewodnik-po-polskich-blogach-poswieconych-c-i-net/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Web Application is configured to use IIS. The IIS Web server is not installed on this computer.</title>
		<link>http://andrzej.net.pl/index.php/2009/08/the-web-application-is-configured-to-use-iis-the-iis-web-server-is-not-installed-on-this-computer/</link>
		<comments>http://andrzej.net.pl/index.php/2009/08/the-web-application-is-configured-to-use-iis-the-iis-web-server-is-not-installed-on-this-computer/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 08:27:20 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[ogólne]]></category>
		<category><![CDATA[visual studio tricks]]></category>
		<category><![CDATA[IIS is not installed]]></category>
		<category><![CDATA[not configured to use IIS]]></category>
		<category><![CDATA[problem z IIS VisualStudio]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=365</guid>
		<description><![CDATA[Nie spotkał Was dotychczas taki komunikat? Ja miałem wątpliwą przyjemność być zaskoczony nim wczoraj ;-) O co chodzi? Pracując na jednym z komputerów ustawiłem w Properties projektu typu Web Application, aby podczas debugowania nie używała wbudowanego serwera deweloperskiego z VisualStudio, a właśnie lokalnego IIS. Ustawienia były więc jak niżej: Nieopatrznie wysłałem projekt na SVN z [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2010/01/visual-studio-jednoczesne-debugowanie-kilku-projektow-w-solution/' rel='bookmark' title='Permanent Link: Visual Studio &#8211; jednoczesne debugowanie kilku projektów w solution'>Visual Studio &#8211; jednoczesne debugowanie kilku projektów w solution</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p>Nie spotkał Was dotychczas taki komunikat? Ja miałem wątpliwą przyjemność być zaskoczony nim wczoraj ;-)</p>
<p>O co chodzi? Pracując na jednym z komputerów ustawiłem w Properties projektu typu Web Application, aby podczas debugowania nie używała wbudowanego serwera deweloperskiego z VisualStudio, a właśnie lokalnego IIS. Ustawienia były więc jak niżej:<br />
<span id="more-365"></span><br />
<div id="attachment_367" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/ScreenShot0011.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/ScreenShot0011-300x178.jpg" alt="Ustawienia WebApplication" title="Ustawienia WebApplication" width="300" height="178" class="size-medium wp-image-367" /></a><p class="wp-caption-text">Ustawienia WebApplication</p></div></p>
<p>Nieopatrznie wysłałem projekt na SVN z takimi ustawieniami.<br/><br />
&#8222;Dzięki&#8221; temu nie mogłem później otworzyć projektu na komputerze bez IIS ;-) Powitał mnie komunikat:<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik003.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik003-300x62.jpg" alt="Błąd" title="Błąd" width="300" height="62" class="aligncenter size-medium wp-image-368" /></a><br/></p>
<p>Oraz solution, w którym mój projekt został przez przezorne VS wyłączony ;-)<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik004.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik004.jpg" alt="Wyłączony projekt" title="Wyłączony projekt" width="277" height="167" class="aligncenter size-full wp-image-369" /></a><br/><br />
Próba zrobienia reload z menu kontekstowego, kończyła się błędem:<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik005.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik005-300x63.jpg" alt="Błąd" title="Błąd" width="300" height="63" class="aligncenter size-medium wp-image-370" /></a><br />
<strong>Rozwiązanie</strong> jest trywialne, ale może komuś oszczędzi rwania włosów z głowy ;-) Z menu kontekstowego wybieramy &#8222;Edit nazwa_projektu.csproj&#8221;:<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik006.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik006.jpg" alt="Edit .csproj" title="Edit .csproj" width="280" height="281" class="aligncenter size-full wp-image-371" /></a><br/><br />
Następnie na końcu pliku, szukamy linii z wpisem:</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;UseIIS<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>True<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/UseIIS<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>i zmieniamy ją na wartość <strong>false</strong><br />
<div id="attachment_376" class="wp-caption aligncenter" style="width: 357px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik009.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik009.jpg" alt="Nasze nowe ustawienie" title="UseIIS" width="347" height="52" class="size-full wp-image-376" /></a><p class="wp-caption-text">Nasze nowe ustawienie</p></div><br />
<br/><br />
Zapisujemy, ponownie robimy <strong>Reload</strong> z menu kontekstowego &#8211; i gotowe! ;-)<br />
<a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik010.jpg" rel="lightbox[365]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik010.jpg" alt="Reload" title="Reload" width="278" height="291" class="aligncenter size-full wp-image-373" /></a></p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2010/01/visual-studio-jednoczesne-debugowanie-kilku-projektow-w-solution/' rel='bookmark' title='Permanent Link: Visual Studio &#8211; jednoczesne debugowanie kilku projektów w solution'>Visual Studio &#8211; jednoczesne debugowanie kilku projektów w solution</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/08/the-web-application-is-configured-to-use-iis-the-iis-web-server-is-not-installed-on-this-computer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ViewState &#8211; z czym to się je</title>
		<link>http://andrzej.net.pl/index.php/2009/08/viewstate/</link>
		<comments>http://andrzej.net.pl/index.php/2009/08/viewstate/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 17:18:16 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[EnableViewState]]></category>
		<category><![CDATA[konstrukcja viewstate]]></category>
		<category><![CDATA[rozmiar ViewState]]></category>
		<category><![CDATA[viewstate]]></category>
		<category><![CDATA[własne wartości w ViewState]]></category>
		<category><![CDATA[zabezpieczenie ViewState]]></category>
		<category><![CDATA[zapis i odczyt viewstate]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=182</guid>
		<description><![CDATA[Postaram się przeprowadzić małą analizę jednego z mechanizmów przechowywania stanów, jakie dostarcza ASP.NET. Mam nadzieję, że poniższy opis ViewState &#8211; jego konstrukcji, sposobu przechowywania i zadań jakie spełnia &#8211; pozwoli uniknąć kilku problemów podczas programowania. Starałem się wybrać rzeczy najbardziej istotne, zbudować zwarty &#8222;przekrój przez ViewState&#8221;. Oczywiście wyczerpanie tematu jest niemożliwe, jednak opis ten stanowić [...]


Nie znaleziono powiązanych wpisów.

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p><a rev="vote-for" href="http://dotnetomaniak.pl/ViewState-z-czym-to-si%C4%99-je-Blog-o-programowaniu-C-ASPNET" onclick="pageTracker._trackPageview('/outgoing/dotnetomaniak.pl/ViewState-z-czym-to-si_C4_99-je-Blog-o-programowaniu-C-ASPNET?referer=');"><img alt="Promuj" src="http://dotnetomaniak.pl/image.axd?url=http%3A%2F%2Fandrzej.net.pl%2Findex.php%2F2009%2F08%2Fviewstate%2F" style="border:0px"/></a></p>
<p style="text-align:justify">
Postaram się przeprowadzić małą analizę jednego z mechanizmów przechowywania stanów, jakie dostarcza ASP.NET. Mam nadzieję, że poniższy opis ViewState &#8211; jego konstrukcji, sposobu przechowywania i zadań jakie spełnia &#8211; pozwoli uniknąć kilku problemów podczas programowania. Starałem się wybrać rzeczy najbardziej istotne, zbudować zwarty &#8222;przekrój przez ViewState&#8221;. Oczywiście wyczerpanie tematu jest niemożliwe, jednak opis ten stanowić może punkt zaczepienia do dalszych rozważań czy poszukiwań.<br />
<br/>ASP.NET udostępnia trzy mechanizmy zapamiętywania stanu. Należą do nich:<br/>
</p>
<h3>Application State</h3>
<p style="text-align: justify;">Wspólny dla całej aplikacji obiekt typu <a href="http://msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.httpapplication.aspx?referer=');">HttpApplication</a>, dostępny w każdej chwili przez zmienną Application. Stanowi zbiór obiektów definiowanych przez użytkownika, których czas życia jest taki jak czas życia całej aplikacji. Kolekcja Application dostępna jest od czasu wykonania zdarzenia <a href="http://msdn.microsoft.com/en-us/library/ms526658(EXCHG.10).aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/ms526658_EXCHG.10_.aspx?referer=');">Application_OnStart</a> &#8211; czyli wtedy, gdy po uruchomieniu aplikacji na serwerze pierwszy użytkownik wykona do niej żądanie. [1]</p>
<h3>Session State</h3>
<p style="text-align: justify;">Wspólny dla danej sesji użytkownika. Jest to instancja klasy <a href="http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.aspx?referer=');">HttpSessionState</a>, unikalna dla każdej sesji użytkownika i wspólna dla wszystkich jego żądań. Jest to również kolekcja obiektów, niszczona automatycznie po określonym w Web.config czasie braku aktywności użytkownika. Gdu użytkownik inicjuje żądanie po raz pierwszy, serwer tworzy obiekt Session i&nbsp;wysyła do użytkownika jego unikalny identyfikator. Domyślnie identyfikator ten jest zapisywany w cookies, a gdy te nie są dostępne &#8211; doklejany do URL każdej strony. Oczywiście można przełączać aplikację między tymi trybami ustawieniami parametru cookieless w&nbsp;web.config. ASP.NET oferuje trzy metody przechowywania sesji, nie to jest jednak przedmiotem wpisu, dlatego polecam doczytać o trybie InProc, StateServer oraz SqlServer.[2]</p>
<h3>View State</h3>
<p style="text-align: justify;">Czyli nasz dzisiejszy bohater. ViewState to jedna z wyjątkowych cech ASP.NET. To swoista &#8222;umiejętność&#8221; zapamiętywania stanu kontrolek na konkretnej stronie. Ten &#8222;stan widoku&#8221; jest generowany przy pierwszym wczytaniu strony aspx i wysyłany do klienta (przeglądarki) w&nbsp;postaci ukrytego pola o nazwie &#8222;__VIEWSTATE&#8221;. Pole to można znaleźć na każdej stronie stworzonej w ASP.NET (w różnej formie, ale o tym później).</p>
<p style="text-align: justify;">ViewState jest atrybutem typu <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.statebag.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.statebag.aspx?referer=');">StateBag</a> klasy <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.control.aspx?referer=');">System.Web.UI.Control</a>, z której dziedziczą wszystkie kontrolki (w tym strony &#8211; czyli instancje klasy <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.aspx" target="_blank" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.page.aspx?referer=');">System.Web.UI.Page</a>).</p>
<p><span id="more-182"></span></p>
<h4>Do czego właściwie służy ViewState?</h4>
<p style="text-align: justify;">Zastanawiacie się pewnie dlaczego cała ta zabawa z ukrywanym polem, do czego jest to w&nbsp;ogóle potrzebne? Otóż w ASP.NET każde odwołanie do strony powoduje utworzenie jej nowej instancji. Dzieje się tak dlatego, że protokół HTTP jest bezstanowy Siłą rzeczy więc, cykl życia zmiennych zadeklarowanych w kodzie kończy się z chwilą przekazania strony do klienta. Jak w takim razie przechowywać informacje o stanie kontrolek &#8211; danych w nich wyświetlanych czy ich właściwościach? Właśnie od tego jest ViewState &#8211; zdejmuje z programisty obowiązek zarządzania stanem każdej kontrolki na stronie.</p>
<h4>Jakby to było, gdyby go nie było? ;-)</h4>
<p style="text-align: justify;">Wyobraźmy sobie sytuację, w której ViewState nie istnieje. Ściągamy z bazy danych informacje, których zażądał użytkownik &#8211; np. listę jednostek organizacyjnych &#8211; i wyświetlamy ją przy użyciu kontrolki Repeater. Gdyby nie ViewState, przy każdym ponownym odświeżeniu tej samej strony &#8211; czyli postbacku &#8211; wywołanym przez użytkownika choćby naciśnięciem przycisku, dane musiałyby być ponownie ściągane. Przyznacie, że nie jest to sytuacja komfortowa. ViewState pozwala na zapamiętanie ściągniętych danych i ich odtworzenie przy każdym kolejnym postbacku. Nadmienić należy, iż każda strona posiada property <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.page.ispostback.aspx?referer=');">IsPostback</a>, które mówi o tym, czy została ona pokazana po raz pierwszy, czy jest to kolejne odwołanie do niej samej.</p>
<p>Każda kontrolka posiada również property <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.enableviewstate.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.control.enableviewstate.aspx?referer=');">EnableViewState</a>, które pozwala na włączanie lub wyłączanie ViewState&#8217;u na niej. Domyślnie ViewState zawsze jest włączony.</p>
<p>W celu zobrazowania przytoczonej powyżej sytuacji (czyli braku ViewState), rozpatrzmy przykład:<br />
umieszczamy na stronie kontrolkę Label z property <strong>EnableViewState</strong> ustawionym na <strong>false</strong> oraz Button, który nie wykonuje żadnego konkretnego zadania poza wywołaniem postbacku.</p>
<p>Przy pierwszym załadowaniu strony wpisujemy do kontrolki <em>lblDate</em> aktualną datę &#8211; datę pierwszego wyświetlenia tej właśnie strony przez użytkownika:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #6666cc; font-weight: bold;">void</span> Page_Load<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">object</span> sender, EventArgs e<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">!</span>IsPostBack<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lblDate<span style="color: #008000;">.</span><span style="color: #0000FF;">Text</span> <span style="color: #008000;">=</span> DateTime<span style="color: #008000;">.</span><span style="color: #0000FF;">Now</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToShortDateString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p>Efekt po pierwszym wywołaniu strony:</p>
<div id="attachment_222" class="wp-caption aligncenter" style="width: 220px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik001.jpg" rel="lightbox[182]"><img class="size-full wp-image-222" title="Pierwsze odwołanie do strony" src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik001.jpg" alt="Pierwsze odwołanie do strony" width="210" height="102" /></a><p class="wp-caption-text">Pierwsze odwołanie do strony</p></div>
<p>Jak widać, wykonał się kod w warunku if(!IsPostback), czyli &#8222;gdy jest to pierwsze odwołanie do strony&#8221;. Jeśli jednak wywołamy postback strony przyciskiem &#8222;Akcja&#8221;, efekt będzie taki:</p>
<div id="attachment_225" class="wp-caption aligncenter" style="width: 213px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/plik002.jpg" rel="lightbox[182]"><img class="size-full wp-image-225" title="Widok strony po postbacku" src="http://andrzej.net.pl/wp-content/uploads/2009/08/plik002.jpg" alt="Widok strony po postbacku" width="203" height="92" /></a><p class="wp-caption-text">Widok strony po postbacku</p></div>
<p style="text-align: justify;">Co się stało? Ponowne odwołanie do tej samej strony powoduje, że property <strong>IsPostback</strong> ma wartość <strong>true</strong>, więc kod wpisania daty się nie wykonuje. Jednocześnie pozbawiliśmy kontrolkę Label jej wewnętrznej pamięci &#8211; poprzednia wartość więc się resetuje i property Text kontrolki jest puste. Gdybyśmy chcieli utrzymać wartość wyświetlaną w kontrolce, najlepszym wyjściem byłoby zachowanie jej wartości w ukrytym polu formularza i odtworzenie przy odwołaniu do strony &#8211; czy nie kojarzy się to wam z PHP ;-) ? Właśnie &#8211; Microsoft zadbał, by w ASP.NET nie trzeba było martwić się o stan kontrolek i podarował nam ViewState.</p>
<p>Gdybyśmy w powyższym przykładzie zmienili tylko jedną rzecz &#8211; property <strong>EnableViewState</strong> kontrolki Label na wartość <strong>true</strong> &#8211; wielokrotne wywoływanie postbacku przyciskiem &#8222;Akcja&#8221; nie spowodowałoby zniknięcia/zresetowania raz ustawionej daty. Oczywiście do czasu, gdybyśmy jawnie sami nie zmienili jej wartości. Prawda, że wygodne?</p>
<h4>Jak przechowywany jest ViewState?</h4>
<p style="text-align:justify">Jak wspomniałem wczesniej, ViewState domyślnie przechowywany jest na stronie w ukrytym polu. Wysyłany jest więc do przeglądarki z&nbsp;każdym odwołaniem. Jego przykładowy wygląd:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;__VIEWSTATE&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;__VIEWSTATE&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/wEPDwUKMTIzNjIzMDUzNg9kFgICCA9kFgJmD2QWBAIBD2QWAmYPZBYCZg9kFgQCLQ88KwALAQAPFgIeB1Zpc2libGVoZGQCLw8PFgIfAGdkZAICD2QWAmYPZBYCZg9kFgICAQ8PFgIeC05hdmlnYXRlVXJsBTpjb250YWN0dXMuYXNweD9UaXRsZT1WaWV3U3RhdGUgaW4gQVNQLk5FVCAtIEV4dHJlbWVFeHBlcnRzZGRkkXmsupXUX8fv/P1Yt35ufqmaLNA=&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span></div></div>
<p style="text-align:justify">Jak widać nie jest to czysty tekst. Wartość pola kodowana jest alorytmem <a href="http://pl.wikipedia.org/wiki/Base64" target="_blank" onclick="pageTracker._trackPageview('/outgoing/pl.wikipedia.org/wiki/Base64?referer=');">base64</a>, czyli kodowaniem określanym mianem transportowego. Jest to kodowanie, nie szyfrowanie dlatego należy być ostrożnym w umieszczaniu istotnych, prywatnych danych w kolekcji ViewState. ViewState może być bardzo prosto odkodowany choćby przy użyciu <a href="http://www.opinionatedgeek.com/dotnet/tools/Base64Decode/Default.aspx" onclick="pageTracker._trackPageview('/outgoing/www.opinionatedgeek.com/dotnet/tools/Base64Decode/Default.aspx?referer=');">tego dekodera online</a>. Microsoft w&nbsp;<a href="http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic12" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/ms972976.aspx_viewstate_topic12?referer=');">oficjalnym artykule</a> prezentuje sposób na parsowanie ViewState&#8217;u, na CodeProject natomiast znaleźć możemy <a href="http://www.codeproject.com/KB/viewstate/viewstate_viewer.aspx" onclick="pageTracker._trackPageview('/outgoing/www.codeproject.com/KB/viewstate/viewstate_viewer.aspx?referer=');">artykuł</a>, w którym prezentowana jest realizacja prostej przeglądarki ViewState&#8217;u. O&nbsp;zabezpieczeniach, szyfrowaniu ViewState czytaj niżej.</p>
<p style="text-align:justify">ViewState posiada jeszcze jedną <strong>nie do końca dogodną cechę</strong>. Tak jak za każdym żądaniem jest wysyłany do klienta, tak przy każdym wywołaniu postbacku musi być odesłany z&nbsp;powrotem na serwer.  O ile nie stwarza to problemów przy małych stronach (z niewielką ilością danych) o tyle staje się istotne, gdy ViewState zaczyna ważyć kilka dziesiątek lub setek kilobajtów. Staje się to dodatkowym narzutem do przetransportowania. Na końcu artykułu poruszana jest kwestia wielkości ViewState, prezentowane są także alternatywne metody jego przechowywania.</p>
<h4>Jak przechowywać własne obiekty w ViewState</h4>
<p>Odpowiedź jest dość prosta &#8211; zapewnijmy możliwość serializacji i dodajmy do kolekcji.</p>
<p>Przypuśćmy, że chcemy przechować w ViewState instancję klasy Person:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&#91;</span>Serializable<span style="color: #008000;">&#93;</span><br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Person<br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> Person<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> id, <span style="color: #6666cc; font-weight: bold;">string</span> name, <span style="color: #6666cc; font-weight: bold;">int</span> age<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span>_id <span style="color: #008000;">=</span> id<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span>_name <span style="color: #008000;">=</span> name<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">this</span><span style="color: #008000;">.</span>_age <span style="color: #008000;">=</span> age<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">int</span> _id<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _id<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _id <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">string</span> _name<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _name<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _name <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">int</span> _age<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Age<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _age<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _age <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p class="text-align:justify"><strong>O czym trzeba pamiętać?</strong></p>
<ul>
<li>Kolekcja ViewState przechowuje obiekty &#8211; niezbędne jest więc jawne rzutowanie</li>
<li>Przed &#8222;wyciągnięciem&#8221; obiektu i zrzutowaniem go należy sprawdzić, czy napewno istnieje w kolekcji &#8211; czyli czy dla danego klucza typu string wartość jest różna od null (patrz przykład poniżej)</li>
<li>Oznaczenie klasy atrybutem <a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.serializableattribute.aspx?referer=');">[Serializable]</a></li>
</ul>
<p>Wykonanie tych trzech rzeczy gwarantuje wolną od błędów obsługę przechowywania własnych obiektów w ViewState. Poniżej poprawny przykład:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">private</span> Person MyPerson<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> ViewState<span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;MyPerson&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">==</span> <span style="color: #0600FF; font-weight: bold;">null</span> <span style="color: #008000;">?</span> <span style="color: #0600FF; font-weight: bold;">null</span> <span style="color: #008000;">:</span> <span style="color: #008000;">&#40;</span>Person<span style="color: #008000;">&#41;</span>ViewState<span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;MyPerson&quot;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> ViewState<span style="color: #008000;">&#91;</span><span style="color: #666666;">&quot;MyPerson&quot;</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p class="text-align:justify" style="text-align: justify;">Gdybyśmy jawnie nie wykonali sprawdzenia, czy wartość w kolekcji dla klucza &#8222;MyPerson&#8221; nie jest równa null i od razu przeprowadzili rzutowanie &#8211; jeden z &#8222;ulubionych&#8221; wyjątków typu <strong>NullReference</strong> miałby dużą szansę nas zaskoczyć (np. odwołanie przed wpisaniem danych). Z&nbsp;kolei nie oznaczenie klasy jako serializowalnej spowoduje wystąpienie wyjątku <strong>HttpException</strong>.<br/><br />
Dodatkowo ViewState oferuje kilka metod:</p>
<ul>
<li><strong>Clear</strong> &#8211; czyści cały ViewState</li>
<li><strong>Add</strong> &#8211; dodaje lub (jeśli wpis o takim kluczu istnieje) aktualizuje dane w kolekcji</li>
<li><strong>Remove</strong> &#8211; pozwala na usunięcie elementu o danym kluczu z kolekcji</li>
<li><strong>IsItemDirty</strong> &#8211; pozwala na pobranie informacji, czy element o zadanym kluczu został zmieniony podczas przetwarzania ostatniego żądania</li>
<li></li>
</ul>
<h4>Kiedy ViewState jest zapisywany, a kiedy odtwarzany</h4>
<p style="text-align:justify">
ViewState <strong>zapisywany jest zawsze po zdarzeniu Page_Load</strong> (i ewentualnym wykonaniu wszystkich zdarzeń postbacku), <strong>przed fazą Render</strong>. Oznacza to, że <strong>ostatnim miejscem, w&nbsp;którym możemy dokonać zmiany wartości zapisywanych w ViewState jest zdarzenie Page_PreRender</strong>. Przed zrenderowaniem strony rekurencyjnie zapisywany jest stan wszystkich kontrolek na stronie, tak aby mógł zostać przesłany jako ukryte pole.<br/><br />
<strong>Odtwarzanie ViewState&#8217;u występuje tylko przy postbacku, zaraz po inicjalizacji (Page_Init)</strong> &#8211; dzięki temu w Page_Load mamy już zawsze odtworzony stan strony z&nbsp;ostatniego żądania. Należy pamiętać, że <strong>w&nbsp;zdarzeniu Page_Init nie można odczytywać ani wpisywać niczego do ViewState&#8217;u</strong> &#8211; nie jest on jeszcze odtworzony.
</p>
<h4>Kilka (ważnych) słów o bezpieczeństwie</h4>
<p>Na ViewState składają się trzy części (określane jako Triplet):</p>
<ul>
<li><strong>Hash strony &#8211; używa tzw. <em>machine authentication check</em></strong> (MAC). Dołączany dodatkowy hasha na końcu ViewState&#8217;u, ograniczający możliwość jego modyfikacji. Jest to dodatkowa suma kontrolna, obliczana z wartości dwóch niżej wymienionych wartości.</li>
<li><strong>Zserializowane stany kontrolek</strong> &#8211; czyli &#8222;rdzeń&#8221; ViewState&#8217;u, surowe dane</li>
<li><strong>Tablica kontrolek</strong> &#8211; zawiera listę kontrolek, z których zbudowano ViewState. Strona musi dostarczyć przy postbacku dokładnie tą samą kolekcję kontrolek, w&nbsp;przeciwnym przypadku wystąpi błąd.</li>
</ul>
<p style="text-align:justify">
Złączenie tych trzech elementów jest kodowane base64 i wysyłane na stronę.<br/><br />
Domyślnie dołączanie MAC jest włączone (przez property <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.enableviewstatemac.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.page.enableviewstatemac.aspx?referer=');">EnableViewStateMac</a>). Jak jednak dowiedzieć można się z&nbsp;dokumentacji Microsoftu, czasem może powodować to dziwne zachowanie przy korzystaniu z metody <a href="http://msdn.microsoft.com/en-us/library/ms525800.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/ms525800.aspx?referer=');">Server.Transfer()</a>. Ustawienie wskazanego property na false rozwiązuje problem, powoduje jednak powstanie dziury bezpieczeństwa &#8211; ViewState może zostać odkodowany, zmieniony i&nbsp;odesłany spowrotem do serwera.<br/><br />
Domyślnie do obliczania hasha z użyciem MAC używany jest algorytm <a href="http://pl.wikipedia.org/wiki/SHA-1" onclick="pageTracker._trackPageview('/outgoing/pl.wikipedia.org/wiki/SHA-1?referer=');">SHA1</a>, jednak można zmienić go za pomocą wpisu w web.config.<br/><br />
Przy postbacku następuje odkodowanie ViewState&#8217;u i porównanie hasha z właściwymi danymi. Wykrycie modyfikacji spowoduje błąd <strong>FormatException</strong> lub <strong>HttpException</strong>.<br/><br />
<strong>Szyfrowanie &#8211; czy to możliwe?</strong><br/><br />
Tak &#8211; możliwe. Jednak należy zadać sobie pytanie, czy skoro myślimy już o szyfrowaniu, to czy na pewno umieszczamy w ViewState dane, które znaleźć się tam powinny? W żadnym razie nie należy w ViewState przechowywać danych, których modyfikacja lub pozyskanie może spowodować niepożądane konsekwencje.<br/><br />
Włączenie szyfrowania polega na odpowiednim ustawieniu wartości elementu <strong>machineKey w&nbsp;web.config</strong>, w sekcji <system.web>:
</p>
<div class="codecolorer-container xml default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;machineKey</span> <span style="color: #000066;">validation</span>=<span style="color: #ff0000;">&quot;3DES&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></div></div>
<p style="text-align:justify">
<strong>Uwaga</strong> &#8211; szyfrowana oczywiście nie jest zawartość ViewState a jedynie sam klucz, służący do weryfikacji.<br/><br />
Możliwe jest dołączenie dodatkowego klucza &#8211; przy użyciu property strony &#8211; <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.page.viewstateuserkey.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.page.viewstateuserkey.aspx?referer=');">ViewStateUserKey</a>. Najlepiej ustawiać wartość (string) tego klucza w zdarzeniu Page_Init. ASP.NET używa go jako parametru wejściowego do algorytmu hashującego, który generuje <em>machine authentication check</em>.
</p>
<h4>Wielkość ViewState</h4>
<p style="text-align:justify">
Nie należy zapominać o tym, że ViewState wprowadza dodatkowy narzut transportowy. Serwer musi wysłać do użytkownika całą stronę i dodatkowo ViewState, natomiast użytkownik odsyła na serwer wartość ukrytego pola przy każdym postbacku. Rozważmy prosty przykład. Na stronie umieścimy kontrolkę Repeater, stworzymy sztuczną listę instancji obiektów typu <em>Person</em> (kod klasy dostępny wyżej). Następnie podłączymy listę jako źródło danych do repeatera i wyświetlimy na stronie.<br/></p>
<p>Kod w pliku aspx:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&lt;</span>asp<span style="color: #008000;">:</span>Repeater runat<span style="color: #008000;">=</span><span style="color: #666666;">&quot;server&quot;</span> ID<span style="color: #008000;">=</span><span style="color: #666666;">&quot;repPersons&quot;</span><span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;</span>ItemTemplate<span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;%</span><span style="color: #008080;"># DataBinder.Eval(Container.DataItem, &quot;Id&quot;) %&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;%</span><span style="color: #008080;"># DataBinder.Eval(Container.DataItem, &quot;Name&quot;) %&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;%</span><span style="color: #008080;"># DataBinder.Eval(Container.DataItem, &quot;City&quot;) %&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;%</span><span style="color: #008080;"># DataBinder.Eval(Container.DataItem, &quot;Age&quot;) %&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;/</span>ItemTemplate<span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;</span>SeparatorTemplate<span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;</span>br <span style="color: #008000;">/&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;/</span>SeparatorTemplate<span style="color: #008000;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&lt;/</span>asp<span style="color: #008000;">:</span>Repeater<span style="color: #008000;">&gt;</span></div></div>
<p>Kod w pliku aspx.cs:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">protected</span> <span style="color: #6666cc; font-weight: bold;">void</span> Page_Load<span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">object</span> sender, EventArgs e <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span> <span style="color: #008000;">!</span>IsPostBack <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; List<span style="color: #008000;">&lt;</span>Person<span style="color: #008000;">&gt;</span> list <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>Person<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">for</span> <span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span> i <span style="color: #008000;">&lt;</span> <span style="color: #FF0000;">50</span><span style="color: #008000;">;</span> i<span style="color: #008000;">++</span> <span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span> <span style="color: #008000;">new</span> Person<span style="color: #008000;">&#40;</span> i <span style="color: #008000;">+</span> <span style="color: #FF0000;">1</span>, <span style="color: #666666;">&quot;Name MyName&quot;</span>, i <span style="color: #008000;">+</span> <span style="color: #FF0000;">20</span> <span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repPersons<span style="color: #008000;">.</span><span style="color: #0000FF;">DataSource</span> <span style="color: #008000;">=</span> list<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repPersons<span style="color: #008000;">.</span><span style="color: #0000FF;">DataBind</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p style="text-align:justify">Jak widać kolekcja liczy 50 osób i przy pierwszym pokazaniu strony podpinana jest do repeatera. Najprostszym sposobem na sprawdzenie wielkości ViewState&#8217;u jest wyświetlenie długości ukrytego pola przy użyciu JavaScriptu. To proste zadanie realizuje poniższy kod:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> GetViewStateSize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> field <span style="color: #339933;">=</span> document.<span style="color: #660066;">forms</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;__VIEWSTATE&quot;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">value</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">alert</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Rozmiar ViewState (kb): &quot;</span> <span style="color: #339933;">+</span> field.<span style="color: #660066;">length</span> <span style="color: #339933;">/</span> <span style="color: #CC0000;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>Który podłączamy do przycisku na stronie:<br/></p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008000;">&lt;</span>input type<span style="color: #008000;">=</span><span style="color: #666666;">&quot;button&quot;</span> value<span style="color: #008000;">=</span><span style="color: #666666;">&quot;Pokaż rozmiar ViewState&quot;</span> onclick<span style="color: #008000;">=</span><span style="color: #666666;">&quot;GetViewStateSize()&quot;</span> <span style="color: #008000;">/&gt;</span></div></div>
<p>W moim przypadku wynik wygląda następująco:<br/><br />
<div id="attachment_299" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/08/viewstate.JPG" rel="lightbox[182]"><img src="http://andrzej.net.pl/wp-content/uploads/2009/08/viewstate-300x189.jpg" alt="Wielkość pola ViewState na stronie" title="Wielkość pola ViewState na stronie" width="300" height="189" class="size-medium wp-image-299" /></a><p class="wp-caption-text">Wielkość pola ViewState na stronie</p></div><br />
Cała strona waży 5,6kB, ViewState &#8211; 2,9kB. Daje to aż 51% wagi całej strony!<br/></p>
<p style="text-align:justify">Jak pokazuje powyższy bardzo prosty przykład, należy być ostrożnym przy używaniu ViewState&#8217;u z kontrolkami, które są pojemnikami na dane, wyświetlają ich znaczną ilość. W literaturze spotyka się zdania, że jeśli waga ViewState&#8217;u przekracza 30% wagi całej strony, trzeba pomyśleć o zmianie sposobu przechowywania jego wartości lub inaczej obsłużyć kontrolki, które powodują tak duży jego przyrost. Oczywiście należy podchodzić do tego zagadnienia racjonalnie &#8211; jeśli są to takie wielkości jak w przytoczonym przykładzie, nie należy sobie zawracać tym głowy. Jeśli jednak strona waży 200kB-300kB, z czego waga ViewState&#8217;u to 50-60% &#8211; najwyższy czas pomyśleć o optymalizacji.</p>
<hr/>
<br/><br />
Mam nadzieję, że udało mi się przybliżyć temat ViewState&#8217;u. Oczywiście poruszone są najważniejsze kwestie, z którymi spotkamy się w codziennym programowaniu. O&nbsp; ViewState można by napisać porządny rozdział w książce, przyznacie jednak, że nie do końca o to chodzi.</br><br />
Postaram się w kolejnym wpisie poruszyć kwestię <strong>przechowywania ViewState&#8217;u w postaci innej niż ukryte pole formularza</strong>. Możliwości jest kilka &#8211; od sesji, przez bazę danych aż po pliki.<br/><br />
Po uporządkowaniu i skomentowaniu kodu źródłowego dołączę go do tego artykułu.
</p>
<p><br/><br />
Źródła:</p>
<p>http://www.extremeexperts.com/Net/Articles/ViewState.aspx</p>
<p>http://msdn.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic3</p>
<p>http://www.codeproject.com/KB/viewstate/viewstate_viewer.aspx</p>
<p>http://blog.sb2.fr/post/2008/12/25/Storing-ViewState-On-Server-Instead-Of-Client-With-ASPNET.aspx</p>
<p>http://aspalliance.com/72</p>
<p>http://msdn.microsoft.com/pl-pl/magazine/cc188774(en-us).aspx</p>
<br/>Przypisy<ol class="footnotes"><li id="footnote_0_182" class="footnote">http://msdn.microsoft.com/en-us/library/bf9xhdz4(VS.71).aspx</li><li id="footnote_1_182" class="footnote">http://msdn.microsoft.com/en-us/library/87069683(VS.71).aspx</li></ol><br/>

<p>Nie znaleziono powiązanych wpisów.</p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/08/viewstate/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Hierarchiczne TreeView z listy obiektów</title>
		<link>http://andrzej.net.pl/index.php/2009/07/hierarchiczne-treeview-z-listy-obiektow/</link>
		<comments>http://andrzej.net.pl/index.php/2009/07/hierarchiczne-treeview-z-listy-obiektow/#comments</comments>
		<pubDate>Sat, 25 Jul 2009 19:21:06 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[hierarchical treeview]]></category>
		<category><![CDATA[hierarchiczne drzewo]]></category>
		<category><![CDATA[lista obiektów na TreeView]]></category>
		<category><![CDATA[parented treeview]]></category>
		<category><![CDATA[treeview]]></category>
		<category><![CDATA[treeview parentId]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=151</guid>
		<description><![CDATA[Wielokrotnie stawałem przed problemem zbudowania hierarchicznego TreeView z listy obiektów. Pisanie odpowiednich foreach, budowanie całej hierarchii TreeNode&#8217;ów stało się za którymś razem męczące. Parę dni temu doczytałem o TreeNodeBindings i postanowiłem chociaż w części zautomatyzować to zadanie. Najpierw przyszło mi na myśl bezpośrednie podpięcie listy do DataSource całego TreeView, jednak jak szybko się okazało kolekcja [...]


Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET – CheckBoxListValidator'>Własny validator w ASP.NET – CheckBoxListValidator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/04/tablice-parametrow/' rel='bookmark' title='Permanent Link: C# params &#8211; tablice parametrów'>C# params &#8211; tablice parametrów</a></li>
</ol>

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p>Wielokrotnie stawałem przed problemem zbudowania hierarchicznego TreeView z listy obiektów.<br />
Pisanie odpowiednich foreach, budowanie całej hierarchii TreeNode&#8217;ów stało się za którymś razem męczące.</p>
<p>Parę dni temu doczytałem o <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.treenodebinding(VS.80).aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.treenodebinding_VS.80_.aspx?referer=');">TreeNodeBindings</a> i postanowiłem chociaż w części zautomatyzować to zadanie. Najpierw przyszło mi na myśl bezpośrednie podpięcie listy do DataSource całego TreeView, jednak jak szybko się okazało kolekcja taka wymaga implementacji interfejsu <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.ihierarchicalenumerable.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.ihierarchicalenumerable.aspx?referer=');">IHierarchicalEnumerable</a> a jej elementy dodatkowo <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.ihierarchicalenumerable.aspx" onclick="pageTracker._trackPageview('/outgoing/msdn.microsoft.com/en-us/library/system.web.ui.ihierarchicalenumerable.aspx?referer=');">IHierarchyData</a>.</p>
<p>Bardzo szybko zapadła więc decyzja &#8211; nie tędy droga ;-) Chciałem rozwiązania dość uniwersalnego, które nie będzie wymagało dodatkowych działań w klasach.<br />
Jak więc &#8222;oszukać&#8221; i podłączyć jako DataSource obiekt, który automatycznie odwali za nas częśc pracy? Więc odpowiedź okazała się dość banalna &#8211; XML.</p>
<p>Wystarczy zbudować w pamieci obiekt XML, składający się wyłącznie z tych danych, które chcemy pokazywać na drzewie i właśnie jego podłączyć jako DataSource, używając odpowiednio ustawionego TreeNodeBindings.<br />
<span id="more-151"></span><br />
Pokażę więc poniżej jak to zrealizować.</p>
<p>Na początek prosta klasa, która posłuży do dalszych demonstracji:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp;<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> OrgUnit<br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">int</span> _id<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> Id<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _id<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _id <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">int</span> _parentId<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">int</span> ParentId<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _parentId<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _parentId <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">string</span> _name<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Name<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _name<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _name <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">private</span> <span style="color: #6666cc; font-weight: bold;">string</span> _description<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">string</span> Description<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #008000;">&#123;</span> <span style="color: #0600FF; font-weight: bold;">return</span> _description<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #008000;">&#123;</span> _description <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Jak widać, posiada ona property ParentId &#8211; właśnie ono będzie odpowiedzialne za budowanie hierarchii.</p>
<p>Na potrzeby tego przykładu zbudujmy sztuczną listę, którą załadujemy nasze drzewo:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">List<span style="color: #008000;">&lt;</span>OrgUnit<span style="color: #008000;">&gt;</span> list <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> List<span style="color: #008000;">&lt;</span>OrgUnit<span style="color: #008000;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">11</span>, <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span>, <span style="color: #666666;">&quot;Firma X&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">1</span>, <span style="color: #FF0000;">0</span>, <span style="color: #666666;">&quot;Dział produkcji&quot;</span>, <span style="color: #666666;">&quot;Dział produkcji zajmuje się...&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">9</span>, <span style="color: #FF0000;">0</span>, <span style="color: #666666;">&quot;Dział handlowy&quot;</span>, <span style="color: #666666;">&quot;Dział handlowy zajmuje się...&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">4</span>, <span style="color: #FF0000;">9</span>, <span style="color: #666666;">&quot;Dział zamówień&quot;</span>, <span style="color: #666666;">&quot;Dział zamówień zajmuje się...&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">2</span>, <span style="color: #FF0000;">1</span>, <span style="color: #666666;">&quot;Dział logistyki&quot;</span>, <span style="color: #666666;">&quot;Dział logistyki zajmuje się...&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">3</span>, <span style="color: #FF0000;">0</span>, <span style="color: #666666;">&quot;Dział księgowości&quot;</span>, <span style="color: #666666;">&quot;Dział księgowości zajmuje się...&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">new</span> XmlTest<span style="color: #008000;">.</span><span style="color: #0000FF;">OrgUnit</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">6</span>, <span style="color: #FF0000;">1</span>, <span style="color: #666666;">&quot;Dział wysyłki&quot;</span>, <span style="color: #666666;">&quot;Dział wysyłki zajmuje się...&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
list<span style="color: #008000;">.</span><span style="color: #0000FF;">Sort</span><span style="color: #008000;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">delegate</span><span style="color: #008000;">&#40;</span>OrgUnit o1, OrgUnit o2<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">return</span> o1<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span><span style="color: #008000;">.</span><span style="color: #0000FF;">CompareTo</span><span style="color: #008000;">&#40;</span>o2<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p><strong>Bardzo ważne</strong> jest, aby lista była <strong>posortowana malejąco</strong> według property, któe tworzy hierarchię. Tutaj zrealizowane jest to przy użyciu delegata, ale ładując dane z bazy można po prostu posortować je w procedurze SQL.</p>
<p>Zwróćcie również uwagę, że na początku dodany jest sztuczny element z id równym -1. Ten zabieg jest niestety niezbędny, gdyż <strong>dokument XML może zawierać tylko jeden główny element</strong>. Najpierw więc dodamy element &#8222;Firma X&#8221;, który będzie wewnętrz zawierał wszystkie pozostałe. Żaden z pozostałych elementów listy nie wskazuje jako parentId tego głównego (-1). Jest to swoisty sztuczny element, który zdecydowanie ułatwi robotę.</p>
<p>Pierwszym krokiem będzie więc zbudowanie dokumentu XML w pamięci:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">XmlDocument xmlDoc <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> XmlDocument<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
XmlDeclaration xmlDeclaration <span style="color: #008000;">=</span> xmlDoc<span style="color: #008000;">.</span><span style="color: #0000FF;">CreateXmlDeclaration</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;1.0&quot;</span>, <span style="color: #0600FF; font-weight: bold;">null</span>, <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
xmlDoc<span style="color: #008000;">.</span><span style="color: #0000FF;">AppendChild</span><span style="color: #008000;">&#40;</span>xmlDeclaration<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p>Następnie w pętli iterujemy po wszyskich obiektach listy, tworząc odpowiednie elementy xml.</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span>OrgUnit item <span style="color: #0600FF; font-weight: bold;">in</span> list<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; XmlElement node <span style="color: #008000;">=</span> xmlDoc<span style="color: #008000;">.</span><span style="color: #0000FF;">CreateElement</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;_&quot;</span> <span style="color: #008000;">+</span> item<span style="color: #008000;">.</span><span style="color: #0000FF;">Id</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; node<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAttribute</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Id&quot;</span>, item<span style="color: #008000;">.</span><span style="color: #0000FF;">Id</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; node<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAttribute</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;ParentId&quot;</span>, item<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; node<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAttribute</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Name&quot;</span>, item<span style="color: #008000;">.</span><span style="color: #0000FF;">Name</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; node<span style="color: #008000;">.</span><span style="color: #0000FF;">SetAttribute</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Description&quot;</span>, item<span style="color: #008000;">.</span><span style="color: #0000FF;">Description</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">...</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Teraz najważniejszy element, od którego zależy poprawne wyświetlanie ostatecznych danych.<br />
&#8222;Algorytm&#8221; dodawania wygląda następująco:</p>
<ul>
<li>Jeśli element ma Id == -1 dodajemy go jako główny do dokumentu</li>
<li>Jeśli element ma Id == 0 dodajemy go jako drugi w hierarchii element, czyli do elementu z pkt. 1</li>
<li>Jeśli element ma Id > 0 odnajdujemy element, którego Id == ParentId obecnego i wstawiamy do niego</li>
</ul>
<p>Kod:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>item<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span> <span style="color: #008000;">==</span> <span style="color: #008000;">-</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; xmlDoc<span style="color: #008000;">.</span><span style="color: #0000FF;">AppendChild</span><span style="color: #008000;">&#40;</span>node<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">else</span> <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>item<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span> <span style="color: #008000;">==</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; xmlDoc<span style="color: #008000;">.</span><span style="color: #0000FF;">ChildNodes</span><span style="color: #008000;">&#91;</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">AppendChild</span><span style="color: #008000;">&#40;</span>node<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF; font-weight: bold;">else</span><br />
&nbsp; &nbsp;<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #6666cc; font-weight: bold;">string</span> searchExpression <span style="color: #008000;">=</span> <span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Format</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;//*[@Id=<span style="color: #008080; font-weight: bold;">\&quot;</span>{0}<span style="color: #008080; font-weight: bold;">\&quot;</span>] &quot;</span>, item<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; XmlNode parent <span style="color: #008000;">=</span> xmlDoc<span style="color: #008000;">.</span><span style="color: #0000FF;">SelectSingleNode</span><span style="color: #008000;">&#40;</span>searchExpression<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">if</span> <span style="color: #008000;">&#40;</span>parent <span style="color: #008000;">!=</span> <span style="color: #0600FF; font-weight: bold;">null</span><span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;parent<span style="color: #008000;">.</span><span style="color: #0000FF;">AppendChild</span><span style="color: #008000;">&#40;</span>node<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">throw</span> <span style="color: #008000;">new</span> Exception<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;Parent node not found - invalid data&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #008000;">&#125;</span></div></div>
<p>Dość istotne jest odpowiednie użycie xpath do wyszukiwania, w postaci:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6666cc; font-weight: bold;">String</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Format</span><span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;//*[@Id=<span style="color: #008080; font-weight: bold;">\&quot;</span>{0}<span style="color: #008080; font-weight: bold;">\&quot;</span>] &quot;</span>, item<span style="color: #008000;">.</span><span style="color: #0000FF;">ParentId</span><span style="color: #008000;">&#41;</span></div></div>
<p>Pozwala to na łatwe odszukanie rodzica dla obecnie rozpatrywanego elementu. Oczywiście niezbędne jest sprawdzenie, czy udało się odnaleźć rodzica (!= null). W przeciwnym przypadku ja zdecydowałem się na rzucenie wyjąktu.</p>
<p>Mamy teraz w pamięci dokument XML, zbudujmy więc z niego XmlDataSource, które jest akceptowalne przez TreeView.</p>
<p>W tym celu tworzymy nową instancję klasy XmlDataSource, nadajemy jej unikalne ID i jako property Data wpisujemy nasz stworzony dokument XML:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XmlDataSource dataSource <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> XmlDataSource<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataSource<span style="color: #008000;">.</span><span style="color: #0000FF;">ID</span> <span style="color: #008000;">=</span> Guid<span style="color: #008000;">.</span><span style="color: #0000FF;">NewGuid</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">.</span><span style="color: #0000FF;">ToString</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataSource<span style="color: #008000;">.</span><span style="color: #0000FF;">Data</span> <span style="color: #008000;">=</span> doc<span style="color: #008000;">.</span><span style="color: #0000FF;">OuterXml</span><span style="color: #008000;">;</span></div></div>
<p>Teraz wystarczy już tylko poinformować nasze TreeView, których atrybutów XML ma używać do generowania pojedynczego TreeNode&#8217;a. W tym celu stworzyć należy obiekt TreeNodeBinding:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TreeNodeBinding binding <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> TreeNodeBinding<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; binding<span style="color: #008000;">.</span><span style="color: #0000FF;">TextField</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Name&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; binding<span style="color: #008000;">.</span><span style="color: #0000FF;">ToolTipField</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Description&quot;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; binding<span style="color: #008000;">.</span><span style="color: #0000FF;">ValueField</span> <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Id&quot;</span><span style="color: #008000;">;</span></div></div>
<p>Na samym końcu podpinamy wszystko do naszej instancji TreeView i cieszymy się hierarchiczną strukturą ;-)</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">treeView1<span style="color: #008000;">.</span><span style="color: #0000FF;">DataBindings</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Add</span><span style="color: #008000;">&#40;</span>binding<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
treeView<span style="color: #008000;">.</span><span style="color: #0000FF;">DataSource</span> <span style="color: #008000;">=</span> dataSource<span style="color: #008000;">;</span><br />
treeView<span style="color: #008000;">.</span><span style="color: #0000FF;">DataBind</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span></div></div>
<p>Jeśli po przeczytaniu masz wrażenie, że jest tutaj więcej pracy niż przy zwykłym budowaniu pojedynczych TreeNode&#8217;ów i dodawaniu ich ręcznie do kolekcji, to zastanów się, czy przy takim ręcznym generowaniu struktury użyjesz gdzieś drugi raz tego samego kodu?</p>
<p>Rozwązanie, które przedstawiam powyżej śmiało można po niewielkich modyfikacjach dołączyć do prywatnych klas pomocniczych / frameworka i używać go z listami bardzo różnych obiektów. Wystarczy, aby miały one Id oraz ParentId (nawet niekoniecznie tak się nazywające).</p>
<p>Wystarczyłoby stworzyć uniwersalną metodę budującą XML z podanych properties klasy, pobierając ich wartości przy użyciu Reflection. Mam zamiar to zrobić jak tylko znajdę chwilkę &#8211; wtedy zamieszczę odpowiedni kod w oddzielnym wpisie.</p>
<p>Tymaczem poniżej możecie pobrać w pełni działające źródło do tego artykułu:<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p>


<p>Powiązane wpisy:<ol><li><a href='http://andrzej.net.pl/index.php/2009/09/wlasny-validator-w-asp-net-%e2%80%93-checkboxlistvalidator/' rel='bookmark' title='Permanent Link: Własny validator w ASP.NET – CheckBoxListValidator'>Własny validator w ASP.NET – CheckBoxListValidator</a></li>
<li><a href='http://andrzej.net.pl/index.php/2009/04/tablice-parametrow/' rel='bookmark' title='Permanent Link: C# params &#8211; tablice parametrów'>C# params &#8211; tablice parametrów</a></li>
</ol></p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/07/hierarchiczne-treeview-z-listy-obiektow/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>&#8222;Go to top&#8221; po asynchronicznym postbacku w UpdatePanelu</title>
		<link>http://andrzej.net.pl/index.php/2009/07/go-to-top-po-asynchronicznym-postbacku-w-updatepanelu/</link>
		<comments>http://andrzej.net.pl/index.php/2009/07/go-to-top-po-asynchronicznym-postbacku-w-updatepanelu/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 12:39:29 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[go to top]]></category>
		<category><![CDATA[na górę strony]]></category>
		<category><![CDATA[przewinięcie]]></category>
		<category><![CDATA[updatepanel]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=135</guid>
		<description><![CDATA[Dziś napotkałem banalny wydawać by się mogło problem, ale może komuś oszczędzi grzebania. Miałem na stronie dwie listy &#8211; po lewej długą, po prawej krótką. Wykonanie akcji na lewej liście miało przeładowywać prawą. Realizacja &#8222;problemu&#8221; oparta o UpdatePanele, ustawione jako conditional. Nie wykonywał się więc postback całej strony a tylko asynchroniczne postbacki wybranych elementów. Problem [...]


Nie znaleziono powiązanych wpisów.

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p>Dziś napotkałem banalny wydawać by się mogło problem, ale może komuś oszczędzi grzebania.</p>
<p>Miałem na stronie dwie listy &#8211; po lewej długą, po prawej krótką. Wykonanie akcji na lewej liście miało przeładowywać prawą. Realizacja &#8222;problemu&#8221; oparta o UpdatePanele, ustawione jako conditional. Nie wykonywał się więc postback całej strony a tylko asynchroniczne postbacki wybranych elementów.</p>
<p>Problem polegał na tym, że użytkownik będąc na końcu długiej listy i wywołując akcję nie widział krótkiej listy i nie widział, czy cokolwiek się działo. Najlepszym sposobem byłoby więc JavaScriptowe przewinięcie strony na górę po wykonaniu akcji&#8230;</p>
<p><span id="more-135"></span></p>
<p>Realizuje to poniższy kod:</p>
<div class="codecolorer-container javascript default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> pageLoad<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> manager <span style="color: #339933;">=</span> Sys.<span style="color: #660066;">WebForms</span>.<span style="color: #660066;">PageRequestManager</span>.<span style="color: #660066;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; manager.<span style="color: #660066;">add_endRequest</span><span style="color: #009900;">&#40;</span>endRequest<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #003366; font-weight: bold;">function</span> endRequest<span style="color: #009900;">&#40;</span>sender<span style="color: #339933;">,</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
window.<span style="color: #660066;">scrollTo</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Jak widać pobierana jest referencja na RequestManager, do której dodajemy &#8222;delegata&#8221; naszej funkcji JS.<br />
Proste i szybkie ;-) Co ciekawe, w VS2008 Intellisense ujawnia jeszcze kilka ciekawych możliwości:</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 310px"><a href="http://andrzej.net.pl/wp-content/uploads/2009/07/manager_js.png" rel="lightbox[135]"><img class="size-medium wp-image-143" style="border: black 1px solid;" title="Intellisense VS2008 - PageRequestManager" src="http://andrzej.net.pl/wp-content/uploads/2009/07/manager_js-300x162.png" border="1" alt="Intellisense VS2008 - PageRequestManager" width="300" height="162" /></a><p class="wp-caption-text">Intellisense VS2008 - PageRequestManager</p></div>
<p>Generalnie pierwszy raz miałem do czynienia z UpdatePanelami. Interesująca sprawa dla kogoś, kto (jak ja) ma dwie lewe ręce do JS, jednak, żeby cokolwiek zrobić i mieć pewność, że działa tak jak chcemy&#8230; Przygotujcie się na długie lektury internetowych tutoriali. Może skrobnę coś w najbliższym czasie o UpdatePanelu &#8211; po tym jak sam się podszkolę ;-)</p>


<p>Nie znaleziono powiązanych wpisów.</p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/07/go-to-top-po-asynchronicznym-postbacku-w-updatepanelu/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C# params &#8211; tablice parametrów</title>
		<link>http://andrzej.net.pl/index.php/2009/04/tablice-parametrow/</link>
		<comments>http://andrzej.net.pl/index.php/2009/04/tablice-parametrow/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 19:56:43 +0000</pubDate>
		<dc:creator>andrzej</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[c# params]]></category>
		<category><![CDATA[params]]></category>
		<category><![CDATA[tablice parametrów]]></category>
		<category><![CDATA[zamiast przeciążania]]></category>

		<guid isPermaLink="false">http://andrzej.net.pl/?p=93</guid>
		<description><![CDATA[Dotychczas, gdy potrzebowałem metod wykonujących te same zadania ale używających innych parametrów (czy choćby innej liczby parametrów), tworzyłem metody przeciążone. Wydawało mi się to naturalne i logiczne rozwiązanie. Do czasu, gdy przeczytałem o tablicach parametrów właśnie. Metody, zawierające deklarację parametrów ze słowem kluczowym params, pozwalają na pobranie dowolnej liczby argumentów określonego typu. Wspomniane przeciążanie jest [...]


Nie znaleziono powiązanych wpisów.

Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.]]></description>
			<content:encoded><![CDATA[<p>Dotychczas, gdy potrzebowałem metod wykonujących te same zadania ale używających innych parametrów (czy choćby innej liczby parametrów), tworzyłem metody przeciążone. Wydawało mi się to naturalne i logiczne rozwiązanie. Do czasu, gdy przeczytałem o <strong>tablicach parametrów</strong> właśnie.</p>
<p>Metody, zawierające deklarację parametrów ze słowem kluczowym <em>params</em>, pozwalają na pobranie dowolnej liczby argumentów określonego typu.</p>
<p>Wspomniane <a href="http://pl.wikipedia.org/wiki/Przeci%C4%85%C5%BCanie_funkcji" onclick="pageTracker._trackPageview('/outgoing/pl.wikipedia.org/wiki/Przeci_C4_85_C5_BCanie_funkcji?referer=');">przeciążanie</a> jest bardzo przydatne, jednak nie sprawdza się we wszystkich przypadkach, na jakie możemy być &#8222;narażeni&#8221; ;-) Jednym z owych przypadków jest sytuacja, gdy nie zmienia się typ parametrów a jedynie ich liczba, której nie jesteśmy w stanie przewidzieć.<br />
<span id="more-93"></span><br />
Książkowym przykładem jest systemowa funkcja WriteLine. Mamy kilka jej odmian:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> WriteLine<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">int</span> parameter<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">...</span><br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> WriteLine<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">double</span> parameter<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">...</span><br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> WriteLine<span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">decimal</span> parameter<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">...</span></div></div>
<p>Jak widać, każda pozwala na wypisanie na ekran zmiennej innego typu. Co w sytuacji, gdy mamy do wypisania dwie zmienne typu int? A trzy? Czy tworzyć w tym celu przeciążone metody, przyjmujące odpowiednią ich ilość? Trochę mija się to z celem i jest po prostu &#8230; nieładne ;)</p>
<p>W takich sytuacjach z pomocą przychodzą właśnie metody ze zmienną liczbą argumentów &#8211; pobierające tablicę parametrów zadeklarowane przy użyciu słowa kluczowego <em>params</em>.</p>
<p><strong>Przykład</strong><br />
Jak to zwykle bywa na blogach, posłużę się przypadkiem nie wziętym z życia, bardzo prostym ale skutecznie (mam nadzieję) obrazującym zagadnienie ;-)</p>
<p><strong>Cel:</strong> metoda wyliczająca sumę n-zmiennych typu int.</p>
<p>Wiadomo, że możemy rozwiązać nasz problem przy użyciu metody pobierającej tablicę typu int. Wyglądałoby to następująco:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #6666cc; font-weight: bold;">class</span> Test<br />
<span style="color: #008000;">&#123;</span><br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">int</span> Sum <span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> list <span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> x <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">foreach</span> <span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #0600FF; font-weight: bold;">in</span> list <span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
x <span style="color: #008000;">+=</span> i<span style="color: #008000;">;</span><br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #0600FF; font-weight: bold;">return</span> x<span style="color: #008000;">;</span><br />
<br />
<span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Wszystko pozornie wygląda ok. Jaki jest jednak mankament tego rozwiązania? Musimy wcześniej utworzyć tablicę ze zmiennych, które chcemy porównać:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Main <span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> args <span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">5</span><span style="color: #008000;">;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> j <span style="color: #008000;">=</span> <span style="color: #FF0000;">15</span><span style="color: #008000;">;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> k <span style="color: #008000;">=</span> <span style="color: #FF0000;">23</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> array <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#91;</span><span style="color: #FF0000;">3</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">;</span><br />
array<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">0</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> i<span style="color: #008000;">;</span><br />
array<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">1</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> j<span style="color: #008000;">;</span><br />
array<span style="color: #008000;">&#91;</span><span style="color: #FF0000;">2</span><span style="color: #008000;">&#93;</span> <span style="color: #008000;">=</span> k<span style="color: #008000;">;</span><br />
<br />
<span style="color: #6666cc; font-weight: bold;">int</span> sum <span style="color: #008000;">=</span> Test<span style="color: #008000;">.</span><span style="color: #0000FF;">Sum</span><span style="color: #008000;">&#40;</span> array <span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Jak widać, wszystko wygląda zgrabnie. Czy aby na pewno? Musimy przecież za każdym razem tworzyć array tylko po to, by zrealizować sumowanie. Czemu nie przerzucić części roboty na kompilator? Zmieńmy więc deklarację metody sumowania na nową:</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">int</span> Sum<span style="color: #008000;">&#40;</span><span style="color: #0600FF; font-weight: bold;">params</span> <span style="color: #6666cc; font-weight: bold;">int</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> list<span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">.....</span></div></div>
<p>W samym wykonaniu nie zmieniamy niczego. Jak teraz wywołamy metodę sumowania?</p>
<div class="codecolorer-container csharp default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> Main <span style="color: #008000;">&#40;</span> <span style="color: #6666cc; font-weight: bold;">string</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> args <span style="color: #008000;">&#41;</span><br />
<span style="color: #008000;">&#123;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> i <span style="color: #008000;">=</span> <span style="color: #FF0000;">5</span><span style="color: #008000;">;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> j <span style="color: #008000;">=</span> <span style="color: #FF0000;">15</span><span style="color: #008000;">;</span><br />
<span style="color: #6666cc; font-weight: bold;">int</span> k <span style="color: #008000;">=</span> <span style="color: #FF0000;">23</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #6666cc; font-weight: bold;">int</span> sum <span style="color: #008000;">=</span> Test<span style="color: #008000;">.</span><span style="color: #0000FF;">Sum</span><span style="color: #008000;">&#40;</span> i, j, k <span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<span style="color: #008000;">&#125;</span></div></div>
<p>Prawda, że mniej kodu? Tablica i tak zostanie zadeklarowana i zainicjowana naszymi zmiennymi, jednak zrobi to za nas kompilator.</p>
<p>Jak wszystkie rozwiązania, użycie <em>params</em> niesie za sobą kilka dość istotnych ograniczeń. Oto one:</p>
<ul>
<li>słowa <em>params</em> możemy używać tylko z tablicami jednowymiarowymi</li>
<li>nie możemy przeciążać metody, która używa tylko tablicy z <em>params</em></li>
<li>nie możemy używać z <em>params</em> słów kluczowych <em>ref</em> i <em>out</em></li>
<li>jeśli metoda ma inne parametry, ten oznaczony jako <em>params</em> musi być ostatni</li>
<li>w jednej metodzie można użyć tylko jednego artumentu oznaczonego <em>params</em></li>
<li>metody bez argumentu oznaczonego <em>params</em> mają zawsze wyższy priorytet niż te nim oznaczone</li>
</ul>
Note: There is a file embedded within this post, please visit this post to download the file.


<p>Nie znaleziono powiązanych wpisów.</p>
<p>Powiązane wpisy wygenerowane przez <a href='http://mitcho.com/code/yarpp/' onclick="pageTracker._trackPageview('/outgoing/mitcho.com/code/yarpp/?referer=');">wtyczkę Yet Another Related Posts</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://andrzej.net.pl/index.php/2009/04/tablice-parametrow/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
