<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Desarrollo en .NET</title><link>http://blogs.clearscreen.com/edu/category/117.aspx</link><description>Posts sobre cuestiones de desarrollo en .NET</description><managingEditor>Eduard Tomàs</managingEditor><dc:language>es-ES</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Eduard Tomàs</dc:creator><title>Estoy en Geeks.ms!</title><link>http://blogs.clearscreen.com/edu/archive/2010/01/21/28784.aspx</link><pubDate>Thu, 21 Jan 2010 01:12:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2010/01/21/28784.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/28784.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2010/01/21/28784.aspx#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/28784.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/28784.aspx</trackback:ping><description>&lt;p&gt;Hola! ¿Has llegado por aquí buscando mi blog de tecnología .NET?&lt;/p&gt;
&lt;p&gt;Ya no lo tengo en clearscreen, mi blog ahora está en geek.ms:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/blogs/etomas"&gt;http://geeks.ms/blogs/etomas&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos en geeks!!! ;-)&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/28784.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Hola! ¿Has llegado por aquí buscando mi blog de tecnología .NET?</p>
<p>Ya no lo tengo en clearscreen, mi blog ahora está en geek.ms:</p>
<p><a href="http://geeks.ms/blogs/etomas">http://geeks.ms/blogs/etomas</a></p>
<p>Nos leemos en geeks!!! ;-)</p>
<p> </p><img src ="http://blogs.clearscreen.com/edu/aggbug/28784.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>Serializar IDictionary a XML</title><link>http://blogs.clearscreen.com/edu/archive/2006/10/02/3770.aspx</link><pubDate>Mon, 02 Oct 2006 18:00:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2006/10/02/3770.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/3770.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2006/10/02/3770.aspx#Feedback</comments><slash:comments>42</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/3770.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/3770.aspx</trackback:ping><description>&lt;p&gt;Si habéis probado de serializar un objeto que implemente IDictionary os habréis dado cuenta de que el sistema genera una excepción, indicando que no sabe como serializar dichos objetos.&lt;/p&gt;
&lt;p&gt;Por suerte existe una solución bastante fácil (explicada tanto &lt;a href="http://msdn.microsoft.com/msdnmag/issues/03/06/XMLFiles/"&gt;aquí&lt;/a&gt; como &lt;a href="http://aspzone.com/blogs/john/articles/167.aspx"&gt;aquí&lt;/a&gt;): implementar la interfaz IXmlSerializable. En los métodos ReadXml ponemos el código para deserializar y en WriteXml el código de serializar.&lt;/p&gt;
&lt;p&gt;A continuación un ejemplo (el mérito no es mío, si no de los que han hecho los enlaces anteriores, yo lo único que he hecho ha sido adaptarlo para que use genéricos). Los objetos de la clase SerializableDictionary se pueden serializar a Xml de la manera &lt;em&gt;tradicional&lt;/em&gt;. Para más información pasaros por los enlaces anteriores ;-)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;

&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;class&lt;/span&gt; SerializableDictionary : Dictionary, IXmlSerializable 
{
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;const&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;string&lt;/span&gt; NS &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &amp;lt;A HREF=&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;""&lt;/span&gt;&amp;gt;http:&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;//blogs.clearscreen.com&amp;lt;/A&amp;gt;; &lt;/span&gt;
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;#region&lt;/span&gt; IXmlSerializable Members 
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; System.Xml.Schema.XmlSchema GetSchema() 
{
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;return&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;null&lt;/span&gt;; 
}

&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; ReadXml(System.Xml.XmlReader r) 
{
XmlSerializer keySer &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;typeof&lt;/span&gt;(K));
XmlSerializer valueSer &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;typeof&lt;/span&gt;(V)); 
r.Read();
r.ReadStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"dictionary"&lt;/span&gt;, NS); &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;while&lt;/span&gt; (r.NodeType !&lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; System.Xml.XmlNodeType.EndElement) 
{
r.ReadStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"item"&lt;/span&gt;, NS); 
r.ReadStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"key"&lt;/span&gt;, NS); 
K key &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; (K)keySer.Deserialize(r);
r.ReadEndElement();
r.ReadStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"value"&lt;/span&gt;, NS); 
V value &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; (V)valueSer.Deserialize(r);
r.ReadEndElement();
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;.Add(key, value); 
r.ReadEndElement();
r.MoveToContent();
}
r.ReadEndElement();
}
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; WriteXml(System.Xml.XmlWriter w) 
{
XmlSerializer keySer &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;typeof&lt;/span&gt;(K));
XmlSerializer valueSer &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;typeof&lt;/span&gt;(V)); 
w.WriteStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"dictionary"&lt;/span&gt;, NS); &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;foreach&lt;/span&gt; (K key &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;in&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;.Keys) 
{
w.WriteStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"item"&lt;/span&gt;, NS); 
w.WriteStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"key"&lt;/span&gt;, NS); 
keySer.Serialize(w, key);
w.WriteEndElement();
w.WriteStartElement(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"value"&lt;/span&gt;, NS); 
V value &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;this&lt;/span&gt;[key]; 
valueSer.Serialize(w, value);
w.WriteEndElement();
w.WriteEndElement();
}
w.WriteEndElement();
}
&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;#endregion&lt;/span&gt;
}

&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Editado @ 04/10:&lt;/strong&gt; Eliminados unos molestos saltos de línea que impedían leer bien el código fuente... ^_^&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/3770.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Si habéis probado de serializar un objeto que implemente IDictionary os habréis dado cuenta de que el sistema genera una excepción, indicando que no sabe como serializar dichos objetos.</p>
<p>Por suerte existe una solución bastante fácil (explicada tanto <a href="http://msdn.microsoft.com/msdnmag/issues/03/06/XMLFiles/">aquí</a> como <a href="http://aspzone.com/blogs/john/articles/167.aspx">aquí</a>): implementar la interfaz IXmlSerializable. En los métodos ReadXml ponemos el código para deserializar y en WriteXml el código de serializar.</p>
<p>A continuación un ejemplo (el mérito no es mío, si no de los que han hecho los enlaces anteriores, yo lo único que he hecho ha sido adaptarlo para que use genéricos). Los objetos de la clase SerializableDictionary se pueden serializar a Xml de la manera <em>tradicional</em>. Para más información pasaros por los enlaces anteriores ;-)</p>
<p></p><pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">

<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">class</span> SerializableDictionary : Dictionary, IXmlSerializable 
{
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">const</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> NS <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> &lt;A HREF=<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">""</span>&gt;http:<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">//blogs.clearscreen.com&lt;/A&gt;; </span>
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">#region</span> IXmlSerializable Members 
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> System.Xml.Schema.XmlSchema GetSchema() 
{
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">return</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">null</span>; 
}

<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> ReadXml(System.Xml.XmlReader r) 
{
XmlSerializer keySer <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">new</span> XmlSerializer(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">typeof</span>(K));
XmlSerializer valueSer <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">new</span> XmlSerializer(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">typeof</span>(V)); 
r.Read();
r.ReadStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"dictionary"</span>, NS); <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">while</span> (r.NodeType !<span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> System.Xml.XmlNodeType.EndElement) 
{
r.ReadStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"item"</span>, NS); 
r.ReadStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"key"</span>, NS); 
K key <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> (K)keySer.Deserialize(r);
r.ReadEndElement();
r.ReadStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"value"</span>, NS); 
V value <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> (V)valueSer.Deserialize(r);
r.ReadEndElement();
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">this</span>.Add(key, value); 
r.ReadEndElement();
r.MoveToContent();
}
r.ReadEndElement();
}
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> WriteXml(System.Xml.XmlWriter w) 
{
XmlSerializer keySer <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">new</span> XmlSerializer(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">typeof</span>(K));
XmlSerializer valueSer <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">new</span> XmlSerializer(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">typeof</span>(V)); 
w.WriteStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"dictionary"</span>, NS); <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">foreach</span> (K key <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">in</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">this</span>.Keys) 
{
w.WriteStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"item"</span>, NS); 
w.WriteStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"key"</span>, NS); 
keySer.Serialize(w, key);
w.WriteEndElement();
w.WriteStartElement(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"value"</span>, NS); 
V value <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">this</span>[key]; 
valueSer.Serialize(w, value);
w.WriteEndElement();
w.WriteEndElement();
}
w.WriteEndElement();
}
<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">#endregion</span>
}

</span></pre>
<p><strong>Editado @ 04/10:</strong> Eliminados unos molestos saltos de línea que impedían leer bien el código fuente... ^_^</p>
<p><font size="2"> </font></p><img src ="http://blogs.clearscreen.com/edu/aggbug/3770.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>DataGridView vinculada a objetos propios... pesadillas varias.</title><link>http://blogs.clearscreen.com/edu/archive/2006/09/28/3752.aspx</link><pubDate>Thu, 28 Sep 2006 16:58:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2006/09/28/3752.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/3752.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2006/09/28/3752.aspx#Feedback</comments><slash:comments>42</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/3752.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/3752.aspx</trackback:ping><description>&lt;p&gt;Pues eso... hay varias cosas que no me terminan de cuadrar sobre el como funciona el DataGridView cuando se vincula (mmm... ata?), cuando se hace data-binding para entendernos contra un objeto de negocio propio.&lt;/p&gt;
&lt;p&gt;Supongamos que tengo la siguiente clase:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;class&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Activity&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;{&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;private&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Action&lt;/font&gt;&lt;font size="2"&gt; _exitAction; 
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;private&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;bool&lt;/font&gt;&lt;font size="2"&gt; _endStateActivity; 
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;private&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; _name;&lt;/font&gt;&lt;font size="2"&gt; 
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; Name 
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;get&lt;/font&gt;&lt;font size="2"&gt; { &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;return&lt;/font&gt;&lt;font size="2"&gt; _name; } 
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;set&lt;/font&gt;&lt;font size="2"&gt; { _name = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;value&lt;/font&gt;&lt;font size="2"&gt;; } 
&lt;p&gt;}&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;bool&lt;/font&gt;&lt;font size="2"&gt; EndActivity 
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;get&lt;/font&gt;&lt;font size="2"&gt; { &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;return&lt;/font&gt;&lt;font size="2"&gt; _endStateActivity; } 
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;set&lt;/font&gt;&lt;font size="2"&gt; { _endStateActivity = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;value&lt;/font&gt;&lt;font size="2"&gt;; } 
&lt;p&gt;}&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;&lt;font color="#008000" size="2"&gt;&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;[&lt;/font&gt;&lt;font color="#008080" size="2"&gt;TypeConverter&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;typeof&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#008080" size="2"&gt;ActionTypeConverter&lt;/font&gt;&lt;font size="2"&gt;))] 
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Action&lt;/font&gt;&lt;font size="2"&gt; EntryAction 
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;get&lt;/font&gt;&lt;font size="2"&gt; { &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;return&lt;/font&gt;&lt;font size="2"&gt; _enterAction; } 
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;set&lt;/font&gt;&lt;font size="2"&gt; { _enterAction = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;value&lt;/font&gt;&lt;font size="2"&gt;; } 
&lt;p&gt;}&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;
&lt;p&gt;}&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;La clase Action no importa para lo que quiero contar, imaginaosla como querais... podemos suponer que tiene una propiedad Name de tipo String.&lt;/p&gt;
&lt;p&gt;Tengo también otra clase llamada State que entre otras cosas tiene una propiedad de tipo List&lt;activity&gt;, llamada Activities.&lt;/activity&gt;&lt;/p&gt;
&lt;p&gt;Creo un object data binding: Data -&amp;gt; Add New DataSource -&amp;gt; Object y selecciono la clase State.&lt;/p&gt;
&lt;p&gt;Eso me crea un object data binding parecido a ese:&lt;/p&gt;
&lt;div align="center"&gt;&lt;img src="/edu/files/diag1.GIF" /&gt;&lt;/div&gt;
&lt;p&gt;(&lt;strong&gt;Nota:&lt;/strong&gt; En mi caso la clase Activity tiene también propiedades DoAction y ExitAction que son de tipo Action)&lt;/p&gt;
&lt;p&gt;Luego, arrastro la propiedad Activities en un form, y me aparece automáticamente un dataviewgrid vinculado. Hasta ahí todo perfecto.&lt;/p&gt;
&lt;p&gt;Ahora empieza la pesadilla... &lt;strong&gt;Cual es mi idea?&lt;/strong&gt; Tengo varios tipos de Acciones que se pueden asignar a la propiedad EntryAction. Desde la grid vinculada me gustaría que se desplegara una combo con los distintos tipos de acciones que admito (p.ej. &lt;em&gt;PlaySound&lt;/em&gt; y &lt;em&gt;PlaySequence&lt;/em&gt;). Cuando el usuario escoja un valor de la combo, el datagridview debería crear un objeto Action, concreto (bueno, de hecho me gustaría que creara un objeto de una cierta clase derivada de Action. Si el usuario escoje PlaySound en la combo quiero que se cree un objeto de la clase PlaySound).&lt;/p&gt;
&lt;p&gt;El primer paso es sencill En la DataGridView indico que quiero modificar las columnas y indico que la columna EntryAction es de tipo DropDownList. La cosa queda més o menos así:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="/edu/files/diag2.gif" /&gt;&lt;/p&gt;
&lt;p&gt;Luego añado dos items a la columna &lt;em&gt;EntryAction&lt;/em&gt; (dos cadenas) con los valores "PlaySound" y "PlaySequence" para que el usuario pueda escojer.&lt;/p&gt;
&lt;p&gt;Finalmente creo la clase ActionTypeConverter que deriva de TypeConverter cuya finalidad es convertir una cadena a un objeto Action y viceversa. Defino los métodos:&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;public&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;override&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;bool&lt;/font&gt;&lt;font size="2"&gt; CanConvertFrom(&lt;/font&gt;&lt;font color="#008080" size="2"&gt;ITypeDescriptorContext&lt;/font&gt;&lt;font size="2"&gt; context, &lt;/font&gt;&lt;font color="#008080" size="2"&gt;Type&lt;/font&gt;&lt;font size="2"&gt; sourceType)&lt;/font&gt;&lt;font color="#0000ff"&gt; 
&lt;p&gt;&lt;font size="2"&gt;public&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt; &lt;font color="#0000ff"&gt;bool&lt;/font&gt; CanConvertTo(&lt;font color="#008080"&gt;ITypeDescriptorContext&lt;/font&gt; context, &lt;font color="#008080"&gt;Type&lt;/font&gt; destinationType)&lt;/font&gt;&lt;font color="#0000ff"&gt; 
&lt;p&gt;&lt;font size="2"&gt;public&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt; &lt;font color="#0000ff"&gt;object&lt;/font&gt; ConvertFrom(&lt;font color="#008080"&gt;ITypeDescriptorContext&lt;/font&gt; context, System.Globalization.&lt;font color="#008080"&gt;CultureInfo&lt;/font&gt; culture, &lt;font color="#0000ff"&gt;object&lt;/font&gt; value)&lt;/font&gt;&lt;font color="#0000ff"&gt; 
&lt;p&gt;&lt;font size="2"&gt;public&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;override&lt;/font&gt; &lt;font color="#0000ff"&gt;object&lt;/font&gt; ConvertTo(&lt;font color="#008080"&gt;ITypeDescriptorContext&lt;/font&gt; context, System.Globalization.&lt;font color="#008080"&gt;CultureInfo&lt;/font&gt; culture, &lt;font color="#0000ff"&gt;object&lt;/font&gt; value, &lt;font color="#008080"&gt;Type&lt;/font&gt; destinationType)&lt;/font&gt; 
&lt;p&gt;Lo hago para que el CanConvertFrom y el CanConverTo indiquen true sólo si se desea convertir desde/a cadena e implemento el ConvertFrom para que devuelva una instancia de PlaySound o PlaySequence en función de si la cadena pasada es "PlaySound" o "PlaySequence". Finalmente el método ConvertTo hace lo contrario (devuelve una cadena "PlaySound" o "PlaySequence".&lt;/p&gt;
&lt;p&gt;Ejecuto el programa y cuando escojo un valor de la combo:&lt;/p&gt;
&lt;p align="center"&gt;&lt;img src="/edu/files/diag3.gif" /&gt;&lt;/p&gt;
&lt;p&gt;Además ese error se repite &lt;em&gt;ad-eternum&lt;/em&gt; cada vez que la DataViewGrid necesita refrescarse.&lt;/p&gt;
&lt;p&gt;Tras unas cuantas lecturas por foros y demás, viendo que ese error se da un muchos casos, observo depurando que los métodos CanConvertFrom y ConvertFrom del ActionTypeConverter, pero los que convierten de Action a string no. Eso me extraña puesto que yo daba por supuesto que:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;La Grid llamaría a ConvertTo para pasar el objeto Action a una cadena y mostrar ese valor en la combo 
&lt;/li&gt;&lt;li&gt;La Grid llamaría a ConvertFrom cuando se hubiese seleccionado un valor de la combo, para obtener un objeto Action (o en mi caso un objeto derivado de Action).&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Pero, por alguna razón el punto (1)  no se lleva a cabo... :(&lt;/p&gt;
&lt;p&gt;Luego también me llamó la atención el hecho de que en unos foros se mencionaba que una celda de tipo combo en la grid sólo podía mostrar valores que contuviera la propia combo, y me asaltó la duda... no estará comparando por &lt;em&gt;Equals&lt;/em&gt;? En este caso el mensaje de error, tendría sentido puesto que en la combo había cadenas (String) que nunca serían iguales a objetos Action (aunque yo proporcionase un ConvertTo que por alguna oscura razón no se llamaba). Así que hice dos cosas: poblar la combo (&lt;em&gt;myColumn.Items.AddRange(...)&lt;/em&gt;) con dos objetos Action (un PlaySound y un PlaySequence) y redefnir los métodos Equals de forma que todos los PlaySound sean iguales entre ellos y todos los PlaySequence sean iguales entre ellos.&lt;/p&gt;
&lt;p&gt;Cuando ejecuté el programa en la combo no aparecía el nombre "PlaySound" o "PlaySequence" sinó el nombre completo de la clase... tal y como lo hace el ToString(), así que ya puestos lo redefiní también (total... me hacía falta un método para pasar de Action a cadena, no?).&lt;/p&gt;
&lt;p&gt;Y al ejecutar... funcionó! En la combo se mostraba "PlaySound" y "PlaySequence" y al seleccionar un valor, se ejecutaba el ConvertFrom del TypeConverter.&lt;/p&gt;
&lt;p&gt;Mis dudas principales son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Por qué la Grid es capaz de ejecutar el ConvertFrom del TypeConverter para obtener un objeto a partir de la cadena y no es capaz de ejecutar el ConvertTo para obtener una cadena a partir del objeto (será porque todos los objetos tienen ToString() ?) 
&lt;/li&gt;&lt;li&gt;Por qué me obliga a poblar la columna usando objetos Action en lugar de cadenas? (Aunque bueno, esto segundo lo puedo llegar a entender pienso que debería ser posible poblar la combo con cadenas que fuesen representaciones válidas de objetos de negocio y que la grid fuera lo suficientemente lista como para espavilarse).&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;En fin, tu... que líos...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Editado @28/09:&lt;/strong&gt; Vale... creo que ya se cuando llama al ConvertTo y cuando llama al ToString(): Para poblar la combo necesita cadenas, así que llama al ToString(). Si tengo eso:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#008080" size="2"&gt;Action&lt;/font&gt;&lt;font size="2"&gt; a1 = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;PlaySound&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"foo"&lt;/font&gt;&lt;font size="2"&gt;);
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#008080" size="2"&gt;Action&lt;/font&gt;&lt;font size="2"&gt; a2 = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;PlaySequence&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"bar"&lt;/font&gt;&lt;font size="2"&gt;);
&lt;p&gt;col.Items.AddRange(a1, a2);&lt;/p&gt;&lt;/font&gt;
&lt;p&gt;Para poblar la combo llamará a a1.ToString() y a2.ToString().&lt;/p&gt;
&lt;p&gt;Luego el ConvertTo lo llama cuando &lt;em&gt;lee&lt;/em&gt; de la fuente de datos, y la cadena resultante es la que intenta mostrar en la combo.&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/3752.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Pues eso... hay varias cosas que no me terminan de cuadrar sobre el como funciona el DataGridView cuando se vincula (mmm... ata?), cuando se hace data-binding para entendernos contra un objeto de negocio propio.</p>
<p>Supongamos que tengo la siguiente clase:</p><font size="2">
<p></p></font><font color="#0000ff" size="2">public</font><font size="2"> </font><font color="#0000ff" size="2">class</font><font size="2"> </font><font color="#008080" size="2">Activity</font><font size="2"> 
<p>{</p></font><font size="2">
<p></p></font><font color="#0000ff" size="2">private</font><font size="2"> </font><font color="#008080" size="2">Action</font><font size="2"> _exitAction; 
<p></p></font><font color="#0000ff" size="2">private</font><font size="2"> </font><font color="#0000ff" size="2">bool</font><font size="2"> _endStateActivity; 
<p></p></font><font color="#0000ff" size="2">private</font><font size="2"> </font><font color="#0000ff" size="2">string</font><font size="2"> _name;</font><font size="2"> 
<p></p></font><font color="#0000ff" size="2">public</font><font size="2"> </font><font color="#0000ff" size="2">string</font><font size="2"> Name 
<p>{</p>
<p></p></font><font color="#0000ff" size="2">get</font><font size="2"> { </font><font color="#0000ff" size="2">return</font><font size="2"> _name; } 
<p></p></font><font color="#0000ff" size="2">set</font><font size="2"> { _name = </font><font color="#0000ff" size="2">value</font><font size="2">; } 
<p>}</p></font><font size="2">
<p></p></font><font color="#0000ff" size="2">public</font><font size="2"> </font><font color="#0000ff" size="2">bool</font><font size="2"> EndActivity 
<p>{</p>
<p></p></font><font color="#0000ff" size="2">get</font><font size="2"> { </font><font color="#0000ff" size="2">return</font><font size="2"> _endStateActivity; } 
<p></p></font><font color="#0000ff" size="2">set</font><font size="2"> { _endStateActivity = </font><font color="#0000ff" size="2">value</font><font size="2">; } 
<p>}</p></font><font size="2">
<p></p></font>
<p><font color="#008000" size="2"></font></p><font size="2">[</font><font color="#008080" size="2">TypeConverter</font><font size="2">(</font><font color="#0000ff" size="2">typeof</font><font size="2">(</font><font color="#008080" size="2">ActionTypeConverter</font><font size="2">))] 
<p></p>
<p></p></font><font color="#0000ff" size="2">public</font><font size="2"> </font><font color="#008080" size="2">Action</font><font size="2"> EntryAction 
<p>{</p>
<p></p></font><font color="#0000ff" size="2">get</font><font size="2"> { </font><font color="#0000ff" size="2">return</font><font size="2"> _enterAction; } 
<p></p></font><font color="#0000ff" size="2">set</font><font size="2"> { _enterAction = </font><font color="#0000ff" size="2">value</font><font size="2">; } 
<p>}</p></font><font size="2">
<p>}</p></font>
<p>La clase Action no importa para lo que quiero contar, imaginaosla como querais... podemos suponer que tiene una propiedad Name de tipo String.</p>
<p>Tengo también otra clase llamada State que entre otras cosas tiene una propiedad de tipo List<activity>, llamada Activities.</activity></p>
<p>Creo un object data binding: Data -&gt; Add New DataSource -&gt; Object y selecciono la clase State.</p>
<p>Eso me crea un object data binding parecido a ese:</p>
<div align="center"><img src="/edu/files/diag1.GIF" /></div>
<p>(<strong>Nota:</strong> En mi caso la clase Activity tiene también propiedades DoAction y ExitAction que son de tipo Action)</p>
<p>Luego, arrastro la propiedad Activities en un form, y me aparece automáticamente un dataviewgrid vinculado. Hasta ahí todo perfecto.</p>
<p>Ahora empieza la pesadilla... <strong>Cual es mi idea?</strong> Tengo varios tipos de Acciones que se pueden asignar a la propiedad EntryAction. Desde la grid vinculada me gustaría que se desplegara una combo con los distintos tipos de acciones que admito (p.ej. <em>PlaySound</em> y <em>PlaySequence</em>). Cuando el usuario escoja un valor de la combo, el datagridview debería crear un objeto Action, concreto (bueno, de hecho me gustaría que creara un objeto de una cierta clase derivada de Action. Si el usuario escoje PlaySound en la combo quiero que se cree un objeto de la clase PlaySound).</p>
<p>El primer paso es sencill En la DataGridView indico que quiero modificar las columnas y indico que la columna EntryAction es de tipo DropDownList. La cosa queda més o menos así:</p>
<p align="center"><img src="/edu/files/diag2.gif" /></p>
<p>Luego añado dos items a la columna <em>EntryAction</em> (dos cadenas) con los valores "PlaySound" y "PlaySequence" para que el usuario pueda escojer.</p>
<p>Finalmente creo la clase ActionTypeConverter que deriva de TypeConverter cuya finalidad es convertir una cadena a un objeto Action y viceversa. Defino los métodos:</p><font color="#0000ff" size="2">
<p>public</p></font><font size="2"></font><font color="#0000ff" size="2">override</font><font size="2"> </font><font color="#0000ff" size="2">bool</font><font size="2"> CanConvertFrom(</font><font color="#008080" size="2">ITypeDescriptorContext</font><font size="2"> context, </font><font color="#008080" size="2">Type</font><font size="2"> sourceType)</font><font color="#0000ff"> 
<p><font size="2">public</font></p></font><font size="2"><font color="#0000ff">override</font> <font color="#0000ff">bool</font> CanConvertTo(<font color="#008080">ITypeDescriptorContext</font> context, <font color="#008080">Type</font> destinationType)</font><font color="#0000ff"> 
<p><font size="2">public</font></p></font><font size="2"><font color="#0000ff">override</font> <font color="#0000ff">object</font> ConvertFrom(<font color="#008080">ITypeDescriptorContext</font> context, System.Globalization.<font color="#008080">CultureInfo</font> culture, <font color="#0000ff">object</font> value)</font><font color="#0000ff"> 
<p><font size="2">public</font></p></font><font size="2"><font color="#0000ff">override</font> <font color="#0000ff">object</font> ConvertTo(<font color="#008080">ITypeDescriptorContext</font> context, System.Globalization.<font color="#008080">CultureInfo</font> culture, <font color="#0000ff">object</font> value, <font color="#008080">Type</font> destinationType)</font> 
<p>Lo hago para que el CanConvertFrom y el CanConverTo indiquen true sólo si se desea convertir desde/a cadena e implemento el ConvertFrom para que devuelva una instancia de PlaySound o PlaySequence en función de si la cadena pasada es "PlaySound" o "PlaySequence". Finalmente el método ConvertTo hace lo contrario (devuelve una cadena "PlaySound" o "PlaySequence".</p>
<p>Ejecuto el programa y cuando escojo un valor de la combo:</p>
<p align="center"><img src="/edu/files/diag3.gif" /></p>
<p>Además ese error se repite <em>ad-eternum</em> cada vez que la DataViewGrid necesita refrescarse.</p>
<p>Tras unas cuantas lecturas por foros y demás, viendo que ese error se da un muchos casos, observo depurando que los métodos CanConvertFrom y ConvertFrom del ActionTypeConverter, pero los que convierten de Action a string no. Eso me extraña puesto que yo daba por supuesto que:</p>
<ol>
<li>La Grid llamaría a ConvertTo para pasar el objeto Action a una cadena y mostrar ese valor en la combo 
</li><li>La Grid llamaría a ConvertFrom cuando se hubiese seleccionado un valor de la combo, para obtener un objeto Action (o en mi caso un objeto derivado de Action).</li></ol>
<p>Pero, por alguna razón el punto (1)  no se lleva a cabo... :(</p>
<p>Luego también me llamó la atención el hecho de que en unos foros se mencionaba que una celda de tipo combo en la grid sólo podía mostrar valores que contuviera la propia combo, y me asaltó la duda... no estará comparando por <em>Equals</em>? En este caso el mensaje de error, tendría sentido puesto que en la combo había cadenas (String) que nunca serían iguales a objetos Action (aunque yo proporcionase un ConvertTo que por alguna oscura razón no se llamaba). Así que hice dos cosas: poblar la combo (<em>myColumn.Items.AddRange(...)</em>) con dos objetos Action (un PlaySound y un PlaySequence) y redefnir los métodos Equals de forma que todos los PlaySound sean iguales entre ellos y todos los PlaySequence sean iguales entre ellos.</p>
<p>Cuando ejecuté el programa en la combo no aparecía el nombre "PlaySound" o "PlaySequence" sinó el nombre completo de la clase... tal y como lo hace el ToString(), así que ya puestos lo redefiní también (total... me hacía falta un método para pasar de Action a cadena, no?).</p>
<p>Y al ejecutar... funcionó! En la combo se mostraba "PlaySound" y "PlaySequence" y al seleccionar un valor, se ejecutaba el ConvertFrom del TypeConverter.</p>
<p>Mis dudas principales son:</p>
<ol>
<li>Por qué la Grid es capaz de ejecutar el ConvertFrom del TypeConverter para obtener un objeto a partir de la cadena y no es capaz de ejecutar el ConvertTo para obtener una cadena a partir del objeto (será porque todos los objetos tienen ToString() ?) 
</li><li>Por qué me obliga a poblar la columna usando objetos Action en lugar de cadenas? (Aunque bueno, esto segundo lo puedo llegar a entender pienso que debería ser posible poblar la combo con cadenas que fuesen representaciones válidas de objetos de negocio y que la grid fuera lo suficientemente lista como para espavilarse).</li></ol>
<p>En fin, tu... que líos...</p>
<p><strong>Editado @28/09:</strong> Vale... creo que ya se cuando llama al ConvertTo y cuando llama al ToString(): Para poblar la combo necesita cadenas, así que llama al ToString(). Si tengo eso:</p><font size="2">
<p></p></font><font color="#008080" size="2">Action</font><font size="2"> a1 = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">PlaySound</font><font size="2">(</font><font color="#800000" size="2">"foo"</font><font size="2">);
<p></p></font><font color="#008080" size="2">Action</font><font size="2"> a2 = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><font color="#008080" size="2">PlaySequence</font><font size="2">(</font><font color="#800000" size="2">"bar"</font><font size="2">);
<p>col.Items.AddRange(a1, a2);</p></font>
<p>Para poblar la combo llamará a a1.ToString() y a2.ToString().</p>
<p>Luego el ConvertTo lo llama cuando <em>lee</em> de la fuente de datos, y la cadena resultante es la que intenta mostrar en la combo.</p><img src ="http://blogs.clearscreen.com/edu/aggbug/3752.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>Obtener el esquema XSD de una clase</title><link>http://blogs.clearscreen.com/edu/archive/2005/11/09/2556.aspx</link><pubDate>Wed, 09 Nov 2005 21:51:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2005/11/09/2556.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/2556.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2005/11/09/2556.aspx#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/2556.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/2556.aspx</trackback:ping><description>&lt;p&gt;Buenas!&lt;/p&gt;
&lt;p&gt;Para un desarrollo que estoy preparando me ha surgido la necesidad de obtener el esquema XSD, de una clase en .NET, de forma &lt;strong&gt;programática &lt;/strong&gt;(sin usar la herramienta &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconXMLSchemaDefinitionToolXsdexe.asp"&gt;xsd.exe&lt;/a&gt;, vamos). La idea es poder generar dinámicament y de forma automática el esquema XSD de cualquier clase.&lt;/p&gt;
&lt;p&gt;La verdad es que la clase &lt;em&gt;XmlSerializer&lt;/em&gt;, permite serializar a XML cualquier clase .NET, pero no hay manera aparente de obtener el esquema XSD. Después de estar bastante rato buscando por internet y surfeando por la MSDN no he encontrado ningún ejemplo, ni nada parecido o que me pudiera ayudar. Así que al final, he optado por una solución drástica: decompilar la herramienta xsd.exe (vale, reconozco que quizá no es muy ético, pero necesidad obliga ;))...&lt;/p&gt;
&lt;p&gt;Gracias a &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector for .NET&lt;/a&gt;, he podido obtener una aproximación al código fuente de xsd.exe y sólo ha sido cuestión de tiempo el averiguar como obtener el XSD asociado a una clase .NET. La clave está en la clases &lt;em&gt;System.Xml.Serialization.XmlReflectionImporter &lt;/em&gt;y &lt;em&gt;System.Xml.Serialization.XmlSchemaExporter&lt;/em&gt;, que no están documentadas en la msdn (vamos, que aparecen pero con el típico comentario "&lt;!--StartFragment --&gt; &lt;em&gt;This type supports the .NET Framework infrastructure and is not intended to be used directly from your code.&lt;/em&gt;").&lt;/p&gt;
&lt;p&gt;La primera permite importar la información de toda una clase en un objeto &lt;em&gt;System.Xml.Serialization.XmlTypeMapping&lt;/em&gt;, mientras que rellena un &lt;em&gt;System.Xml.Serialization.XmlSchemas&lt;/em&gt; con la información del &lt;em&gt;XmlTypeMapping&lt;/em&gt; indicado.&lt;/p&gt;
&lt;p&gt;En resumidas cuentas el código quedaria (básicamente) así:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlReflectionImporter&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; importer = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlReflectionImporter&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt;();&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlSchemas&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; schemas = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlSchemas&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt;();&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlSchemaExporter&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; exporter = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlSchemaExporter&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt;(schemas);&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlTypeMapping&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; mapping = importer.ImportTypeMapping(type);      &lt;font color="#008000" size="2"&gt;// type1 es el System.Type del que queremos obtener el XSD&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font size="3"&gt;&lt;font size="2"&gt;exporter.ExportTypeMapping(mapping);&lt;br /&gt;&lt;font size="2"&gt;schemas.Compile(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;ValidationEventHandler&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;Program&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;&lt;font size="2"&gt;.ValidationCallbackWithErrorCode), &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;false&lt;/font&gt;&lt;font size="2"&gt;);&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font size="3"&gt;&lt;font color="#008000" size="2"&gt;// En este punto tenemos en schemas un conjunto de objetos XmlSchema que podemos&lt;/font&gt;&lt;font color="#008000" size="2"&gt; guardar a disco con el método Write.&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;XmlSchema&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; schema = schemas[idx];&lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;FileStream&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; fs = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;FileStream&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt;(outputdir + "foo.xsd", &lt;/font&gt;&lt;b&gt;&lt;font color="#008080" size="2"&gt;FileMode&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt;.CreateNew); &lt;br /&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;StreamWriter&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; sw = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;StreamWriter&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt;(fs);&lt;br /&gt;schemas.Write(sw);&lt;br /&gt;sw.Close();&lt;/font&gt;
&lt;p&gt;&lt;font size="2"&gt;...&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;&lt;/p&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;internal void&lt;/font&gt;&lt;font size="2"&gt; ValidationCallbackWithErrorCode(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;object&lt;/font&gt;&lt;font size="2"&gt; sender, &lt;/font&gt;&lt;b&gt;&lt;font color="#000080" size="2"&gt;ValidationEventArgs&lt;/font&gt;&lt;/b&gt;&lt;font size="2"&gt; args) { ... }&lt;/font&gt;
&lt;p&gt;En fin, digo yo que que les costaría a los de microsoft documentar un poquillo más las cosas, no???&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/2556.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Buenas!</p>
<p>Para un desarrollo que estoy preparando me ha surgido la necesidad de obtener el esquema XSD, de una clase en .NET, de forma <strong>programática </strong>(sin usar la herramienta <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cptools/html/cpconXMLSchemaDefinitionToolXsdexe.asp">xsd.exe</a>, vamos). La idea es poder generar dinámicament y de forma automática el esquema XSD de cualquier clase.</p>
<p>La verdad es que la clase <em>XmlSerializer</em>, permite serializar a XML cualquier clase .NET, pero no hay manera aparente de obtener el esquema XSD. Después de estar bastante rato buscando por internet y surfeando por la MSDN no he encontrado ningún ejemplo, ni nada parecido o que me pudiera ayudar. Así que al final, he optado por una solución drástica: decompilar la herramienta xsd.exe (vale, reconozco que quizá no es muy ético, pero necesidad obliga ;))...</p>
<p>Gracias a <a href="http://www.aisto.com/roeder/dotnet/">Reflector for .NET</a>, he podido obtener una aproximación al código fuente de xsd.exe y sólo ha sido cuestión de tiempo el averiguar como obtener el XSD asociado a una clase .NET. La clave está en la clases <em>System.Xml.Serialization.XmlReflectionImporter </em>y <em>System.Xml.Serialization.XmlSchemaExporter</em>, que no están documentadas en la msdn (vamos, que aparecen pero con el típico comentario "<!--StartFragment --> <em>This type supports the .NET Framework infrastructure and is not intended to be used directly from your code.</em>").</p>
<p>La primera permite importar la información de toda una clase en un objeto <em>System.Xml.Serialization.XmlTypeMapping</em>, mientras que rellena un <em>System.Xml.Serialization.XmlSchemas</em> con la información del <em>XmlTypeMapping</em> indicado.</p>
<p>En resumidas cuentas el código quedaria (básicamente) así:</p><font size="2">
<p></p></font><b><font color="#000080" size="2">XmlReflectionImporter</font></b><font size="2"> importer = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><b><font color="#000080" size="2">XmlReflectionImporter</font></b><font size="2">();<br /></font><b><font color="#000080" size="2">XmlSchemas</font></b><font size="2"> schemas = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><b><font color="#000080" size="2">XmlSchemas</font></b><font size="2">();<br /></font><b><font color="#000080" size="2">XmlSchemaExporter</font></b><font size="2"> exporter = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><b><font color="#000080" size="2">XmlSchemaExporter</font></b><font size="2">(schemas);<br /></font><b><font color="#000080" size="2">XmlTypeMapping</font></b><font size="2"> mapping = importer.ImportTypeMapping(type);      <font color="#008000" size="2">// type1 es el System.Type del que queremos obtener el XSD<br /></font></font><font size="2"><font size="3"><font size="2">exporter.ExportTypeMapping(mapping);<br /><font size="2">schemas.Compile(</font><font color="#0000ff" size="2">new</font><font size="2"> </font><b><font color="#000080" size="2">ValidationEventHandler</font></b></font><font size="2">(</font><b><font color="#000080" size="2">Program</font></b></font><font size="2">.ValidationCallbackWithErrorCode), </font><font color="#0000ff" size="2">false</font><font size="2">);<br /></font></font><font size="2"><font size="3"><font color="#008000" size="2">// En este punto tenemos en schemas un conjunto de objetos XmlSchema que podemos</font><font color="#008000" size="2"> guardar a disco con el método Write.<br /></font></font></font><b><font color="#000080" size="2">XmlSchema</font></b><font size="2"> schema = schemas[idx];<br /></font><b><font color="#000080" size="2">FileStream</font></b><font size="2"> fs = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><b><font color="#000080" size="2">FileStream</font></b><font size="2">(outputdir + "foo.xsd", </font><b><font color="#008080" size="2">FileMode</font></b><font size="2">.CreateNew); <br /></font><b><font color="#000080" size="2">StreamWriter</font></b><font size="2"> sw = </font><font color="#0000ff" size="2">new</font><font size="2"> </font><b><font color="#000080" size="2">StreamWriter</font></b><font size="2">(fs);<br />schemas.Write(sw);<br />sw.Close();</font>
<p><font size="2">...</font></p><font size="2">
<p></p></font><font color="#0000ff" size="2">internal void</font><font size="2"> ValidationCallbackWithErrorCode(</font><font color="#0000ff" size="2">object</font><font size="2"> sender, </font><b><font color="#000080" size="2">ValidationEventArgs</font></b><font size="2"> args) { ... }</font>
<p>En fin, digo yo que que les costaría a los de microsoft documentar un poquillo más las cosas, no???</p>
<p>Un saludo!</p><img src ="http://blogs.clearscreen.com/edu/aggbug/2556.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>Web Services: desarrollo Contract-first</title><link>http://blogs.clearscreen.com/edu/archive/2005/10/14/2492.aspx</link><pubDate>Fri, 14 Oct 2005 12:46:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2005/10/14/2492.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/2492.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2005/10/14/2492.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/2492.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/2492.aspx</trackback:ping><description>&lt;p&gt;El otro día un compañero mío de &lt;a href="http://www.raona.com"&gt;raona&lt;/a&gt;, envió un correo que creo que es intersante, así que me he permitido la licencia de resumirlo y publicarlo aquí.&lt;/p&gt;
&lt;p&gt;En concreto hablaba del desarrollo de web services haciendo especial énfasis en el contrato (contract-first vs code-first, podeis leer mucha más información en &lt;a href="http://msdn.microsoft.com/msdnmag/issues/05/05/ServiceStation/" target="_blank"&gt;&lt;font face="Arial" size="2"&gt;http://msdn.microsoft.com/msdnmag/issues/05/05/ServiceStation/&lt;/font&gt;&lt;/a&gt;), aún no siendo la solución definitiva a algunos de los problemas que quieren resolver los servicios web, plantea algunos aspectos que van en la dirección correcta, especialmente aquellos que nos hacen pensar que mensajes debemos enviar o recibir.&lt;/p&gt;
&lt;p&gt;Obviamente la situación ideal es cuando tenemos un esquema concreto al que nos tenemos que ajustar, y en este caso lo cierto es que VS.NET (por su tendencia a ocultar el WSDL generado) no nos ayuda demasiado. En este punto es donde mi compañero mencionaba que han estado usando una herramienta gratuita (que yo personalmente no he tenido ocasión de probar), pero que facilita bastante el trabajo: &lt;a href="https://intranet.raona.net/exchweb/bin/redir.asp?URL=http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html" target="_blank"&gt;&lt;font face="Arial" size="2"&gt;http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html&lt;/font&gt;&lt;/a&gt;&lt;font face="Arial" size="2"&gt;.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial" size="2"&gt;Dicha herramienta permite garantizar que los mensajes enviados/recibidos por un servicio web se ajusta a un esquema indicado y permite generar también el código del servicio web como del cliente asociado.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial" size="2"&gt;Un saludo!&lt;/font&gt;&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/2492.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>El otro día un compañero mío de <a href="http://www.raona.com">raona</a>, envió un correo que creo que es intersante, así que me he permitido la licencia de resumirlo y publicarlo aquí.</p>
<p>En concreto hablaba del desarrollo de web services haciendo especial énfasis en el contrato (contract-first vs code-first, podeis leer mucha más información en <a href="http://msdn.microsoft.com/msdnmag/issues/05/05/ServiceStation/" target="_blank"><font face="Arial" size="2">http://msdn.microsoft.com/msdnmag/issues/05/05/ServiceStation/</font></a>), aún no siendo la solución definitiva a algunos de los problemas que quieren resolver los servicios web, plantea algunos aspectos que van en la dirección correcta, especialmente aquellos que nos hacen pensar que mensajes debemos enviar o recibir.</p>
<p>Obviamente la situación ideal es cuando tenemos un esquema concreto al que nos tenemos que ajustar, y en este caso lo cierto es que VS.NET (por su tendencia a ocultar el WSDL generado) no nos ayuda demasiado. En este punto es donde mi compañero mencionaba que han estado usando una herramienta gratuita (que yo personalmente no he tenido ocasión de probar), pero que facilita bastante el trabajo: <a href="https://intranet.raona.net/exchweb/bin/redir.asp?URL=http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html" target="_blank"><font face="Arial" size="2">http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html</font></a><font face="Arial" size="2">.</font></p>
<p><font face="Arial" size="2">Dicha herramienta permite garantizar que los mensajes enviados/recibidos por un servicio web se ajusta a un esquema indicado y permite generar también el código del servicio web como del cliente asociado.</font></p>
<p><font face="Arial" size="2">Un saludo!</font></p><img src ="http://blogs.clearscreen.com/edu/aggbug/2492.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>referencias constantes</title><link>http://blogs.clearscreen.com/edu/archive/2005/06/21/1944.aspx</link><pubDate>Tue, 21 Jun 2005 11:59:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2005/06/21/1944.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/1944.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2005/06/21/1944.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/1944.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/1944.aspx</trackback:ping><description>&lt;p&gt;Muy buenas...&lt;/p&gt;
&lt;p&gt;Me pregunto de nuevo, y esta vez por escrito, por que microsoft no ha incorporado el concepto de referencia constante al CLR y así de paso a todos los lenguajes .NET.&lt;/p&gt;
&lt;p&gt;Personalmente el uso de const en C++ me parece una autentica maravilla y me sorprende que ni Sun en su dia con Java, ni Microsoft hayan incorporado dicho concepto a sus lenguajes.&lt;/p&gt;
&lt;p&gt;Los que sepais C++ sabeis como funciona el tema: se puede indicar que una función recibe como parámetro o devuelve una referencia constante, eso es, que el estado del objeto apuntado por dicha referencia (y/o puntero en el caso de C++) no se puede modificar:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;

&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; foo (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;const&lt;/span&gt; MyClass* pMc) {...}

&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;La función foo no puede modificar el estado del objeto apuntado por pMc, es decir no puede llamar a ningún método que modifique alguna variable miembro de la clase. De hecho, al desarrollar la clase, tiene que marcarse explicitamente que funciones son accesibles a través de una referencia/puntero const:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;

&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;class&lt;/span&gt; MyClass

{

&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt;:

&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; func1();

&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; func2() &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;const&lt;/span&gt;;      &lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;// El código de MyClass::func2 no puede modificar ninguna variable miembro de MyClass&lt;/span&gt;

}

&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;En este caso, una llamada a pMc-&amp;gt;func1() desde la función foo daría un error de compilación, mientras que una llamada a pMc-&amp;gt;func2() compilaría correctamente.&lt;/p&gt;
&lt;p&gt;Personalmente encuentro esta característica muy interesante... por ejemplo al devolver colecciones. Algunas veces tengo classes parecidas a estas:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;

&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; UXLContainer

{

    &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; UXLItemCollection _items; 

    &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; UXLItemCollection Items { get { &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;return&lt;/span&gt; _items; } }

}

&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Me encuentro en que es perfectamente legal que alguien coja un objeto UXLContainer, y haga algo como:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;

UXLContainer c &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; UXLContainer();

c.Items.Add (...);

&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;Pero a mi, p.ej. me interesaba que dicha colección fuera de solo lectura (es decir que se pudiera acceder a un UXLItem, pero no añadir ni quitar UXLItems de la colección).&lt;/p&gt;
&lt;p&gt;Se que hay soluciones alternativas, pero considero que en este caso una referencia constante sería ideal.&lt;/p&gt;
&lt;p&gt;No he entendido jamás porque ni Java en su día, ni .NET más tarde incorporaron esta característica de C++ a sus plataformas...&lt;/p&gt;
&lt;p&gt;Nos vemos!&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/1944.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Muy buenas...</p>
<p>Me pregunto de nuevo, y esta vez por escrito, por que microsoft no ha incorporado el concepto de referencia constante al CLR y así de paso a todos los lenguajes .NET.</p>
<p>Personalmente el uso de const en C++ me parece una autentica maravilla y me sorprende que ni Sun en su dia con Java, ni Microsoft hayan incorporado dicho concepto a sus lenguajes.</p>
<p>Los que sepais C++ sabeis como funciona el tema: se puede indicar que una función recibe como parámetro o devuelve una referencia constante, eso es, que el estado del objeto apuntado por dicha referencia (y/o puntero en el caso de C++) no se puede modificar:</p>
<p></p><pre><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">

<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> foo (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">const</span> MyClass* pMc) {...}

</span></pre>
<p>La función foo no puede modificar el estado del objeto apuntado por pMc, es decir no puede llamar a ningún método que modifique alguna variable miembro de la clase. De hecho, al desarrollar la clase, tiene que marcarse explicitamente que funciones son accesibles a través de una referencia/puntero const:</p>
<p></p><pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">

<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">class</span> MyClass

{

<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span>:

<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> func1();

<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> func2() <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">const</span>;      <span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">// El código de MyClass::func2 no puede modificar ninguna variable miembro de MyClass</span>

}

</span></pre>
<p>En este caso, una llamada a pMc-&gt;func1() desde la función foo daría un error de compilación, mientras que una llamada a pMc-&gt;func2() compilaría correctamente.</p>
<p>Personalmente encuentro esta característica muy interesante... por ejemplo al devolver colecciones. Algunas veces tengo classes parecidas a estas:</p>
<p></p><pre><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">

<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> UXLContainer

{

    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span> UXLItemCollection _items; 

    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span> UXLItemCollection Items { get { <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">return</span> _items; } }

}

</span></pre>
<p>Me encuentro en que es perfectamente legal que alguien coja un objeto UXLContainer, y haga algo como:</p>
<p></p><pre><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">

UXLContainer c <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> UXLContainer();

c.Items.Add (...);

</span></pre>
<p>Pero a mi, p.ej. me interesaba que dicha colección fuera de solo lectura (es decir que se pudiera acceder a un UXLItem, pero no añadir ni quitar UXLItems de la colección).</p>
<p>Se que hay soluciones alternativas, pero considero que en este caso una referencia constante sería ideal.</p>
<p>No he entendido jamás porque ni Java en su día, ni .NET más tarde incorporaron esta característica de C++ a sus plataformas...</p>
<p>Nos vemos!</p><img src ="http://blogs.clearscreen.com/edu/aggbug/1944.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>Ajax en .NET??</title><link>http://blogs.clearscreen.com/edu/archive/2005/06/14/1912.aspx</link><pubDate>Tue, 14 Jun 2005 15:20:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2005/06/14/1912.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/1912.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2005/06/14/1912.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/1912.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/1912.aspx</trackback:ping><description>&lt;p&gt;Buenas!&lt;/p&gt;
&lt;p&gt;Conoceis el paradigma de programación web, que se conoce como Ajax?? Bueno... básicamente consiste en utilizar XmlHttpRequest + javascript para lanzar peticiones asíncronas al servidor web y así romper el flujo tradicional de una aplicación web.&lt;/p&gt;
&lt;p&gt;No es un invento relativamente nuevo, pero está ganando mucho auge ahora, especialmente desde que XmlHttpRequest está disponible en todos los navegadores. Un muy buen ejemplo del potencial de ajax es &lt;a href="http://www.gmail.com"&gt;gmail&lt;/a&gt;. Bueno... una explicación mejor de Ajax que ésta la encontrareis &lt;a href="http://www.adaptivepath.com/publications/essays/archives/000385.php"&gt;aquí&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En ASP.NET 2.0 habrá soporte para Ajax (&lt;a href="http://www.dotnetjunkies.com/Tutorial/E80EC96F-1C32-4855-85AE-9E30EECF13D7.dcik"&gt;Client Callbacks&lt;/a&gt;), pero este soporte desde mi punto de vista deja un poco que desear, porque está orientado &lt;em&gt;por control&lt;/em&gt;, mientras que yo pienso que este paradigma es lo suficientemente importante para que el soporte de Ajax esté orientado &lt;em&gt;por el framework entero&lt;/em&gt;. Y esto implica que el framework debe dar mucho más soporte de cliente que el que proporciona en la actualidad (para empezar el desarrollador debería despreocuparse del código Javascript asociado. Un ejemplo de a lo que me refiero es la librería &lt;a href="http://ajax.schwarz-interactive.de/csharpsample/default.aspx"&gt;ajax.net&lt;/a&gt;). Una buena cantidad de características que no existen en ASP.NET 2.0 las podeis leer en &lt;a href="http://west-wind.com/weblog/posts/2302.aspx"&gt;este blog&lt;/a&gt; (mirad el apartado "&lt;em&gt;It works but...&lt;/em&gt;")&lt;/p&gt;
&lt;p&gt;En ASP.NET 2.0 no veremos nada nuevo al respecto, pero las buenas noticias son que al menos parece que Microsoft se está preocupando por Ajax (o eso se deduce de &lt;a href="http://lab.msdn.microsoft.com/ProductFeedback/viewFeedback.aspx?feedbackId=FDBK28434&amp;amp;lc=1033"&gt;esta petición al feeback center&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Veremos como evoluciona todo esto... ;)&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/1912.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml"><p>Buenas!</p>
<p>Conoceis el paradigma de programación web, que se conoce como Ajax?? Bueno... básicamente consiste en utilizar XmlHttpRequest + javascript para lanzar peticiones asíncronas al servidor web y así romper el flujo tradicional de una aplicación web.</p>
<p>No es un invento relativamente nuevo, pero está ganando mucho auge ahora, especialmente desde que XmlHttpRequest está disponible en todos los navegadores. Un muy buen ejemplo del potencial de ajax es <a href="http://www.gmail.com">gmail</a>. Bueno... una explicación mejor de Ajax que ésta la encontrareis <a href="http://www.adaptivepath.com/publications/essays/archives/000385.php">aquí</a>.</p>
<p>En ASP.NET 2.0 habrá soporte para Ajax (<a href="http://www.dotnetjunkies.com/Tutorial/E80EC96F-1C32-4855-85AE-9E30EECF13D7.dcik">Client Callbacks</a>), pero este soporte desde mi punto de vista deja un poco que desear, porque está orientado <em>por control</em>, mientras que yo pienso que este paradigma es lo suficientemente importante para que el soporte de Ajax esté orientado <em>por el framework entero</em>. Y esto implica que el framework debe dar mucho más soporte de cliente que el que proporciona en la actualidad (para empezar el desarrollador debería despreocuparse del código Javascript asociado. Un ejemplo de a lo que me refiero es la librería <a href="http://ajax.schwarz-interactive.de/csharpsample/default.aspx">ajax.net</a>). Una buena cantidad de características que no existen en ASP.NET 2.0 las podeis leer en <a href="http://west-wind.com/weblog/posts/2302.aspx">este blog</a> (mirad el apartado "<em>It works but...</em>")</p>
<p>En ASP.NET 2.0 no veremos nada nuevo al respecto, pero las buenas noticias son que al menos parece que Microsoft se está preocupando por Ajax (o eso se deduce de <a href="http://lab.msdn.microsoft.com/ProductFeedback/viewFeedback.aspx?feedbackId=FDBK28434&amp;lc=1033">esta petición al feeback center</a>).</p>
<p>Veremos como evoluciona todo esto... ;)</p><img src ="http://blogs.clearscreen.com/edu/aggbug/1912.aspx" width = "1" height = "1" /></body></item><item><dc:creator>Eduard Tomàs</dc:creator><title>Coldfusioneando que es gerundio (y II)</title><link>http://blogs.clearscreen.com/edu/archive/2005/05/04/1455.aspx</link><pubDate>Wed, 04 May 2005 22:46:00 GMT</pubDate><guid>http://blogs.clearscreen.com/edu/archive/2005/05/04/1455.aspx</guid><wfw:comment>http://blogs.clearscreen.com/edu/comments/1455.aspx</wfw:comment><comments>http://blogs.clearscreen.com/edu/archive/2005/05/04/1455.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://blogs.clearscreen.com/edu/comments/commentRss/1455.aspx</wfw:commentRss><trackback:ping>http://blogs.clearscreen.com/edu/services/trackbacks/1455.aspx</trackback:ping><description>Comentaba algunos días que intentaría a ver si era posible hacer algún control en ASP.NET que permitiera hacer programación tag-based, es decir algo así como:

&lt;cfif expression="expresion_a_evaluar"&gt;
// Código asp.net + HTML a  ejecutar en caso de que se cumpla la expresión
&lt;cfelse&gt;
// Código asp.net + HTML a ejecutar en caso de que no se cumpla la expresión
&lt;/cfelse&gt;&lt;/cfif&gt;

Bueno... Pues la verdad es que ya tengo un esqueleto que más o menos hace esto, y no es muy complicado: La clave está en el interfaz ITemplate. Si declaramos propiedades de tipo ITemplate se puede colocar etiquetas HTML y ASP.NET dentro del webcontrol y luego dinámicamente transformar dichas etiquetas en los controles de servidor reales...

&lt;pre&gt;&lt;span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;
	[ToolboxData(&lt;span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px"&gt;"&amp;lt;{0}:TagIf runat=server&amp;gt;&amp;lt;/{0}:TagIf&amp;gt;"&lt;/span&gt;)]
	[ParseChildren(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;true&lt;/span&gt;)]
	&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;class&lt;/span&gt; TagIf : Control, INamingContainer
	{

		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; ITemplate _doAction &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;null&lt;/span&gt;;
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; ITemplate _elseAction &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;null&lt;/span&gt;;
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;string&lt;/span&gt; _expression &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;null&lt;/span&gt;;

		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// Expresión a evaluar para decidir si mostrar el contenido del DoAction o del ElseAction&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;value&amp;gt;En esta versión... un número (constante) ;)&amp;lt;/value&amp;gt;		&lt;/span&gt;
                &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;string&lt;/span&gt; Expression
		{
			get { &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;return&lt;/span&gt; _expression; }
			set { _expression &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; value; }
		}

		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;// override to prevent literal controls from being added as children&lt;/span&gt;
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;override&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; AddParsedSubObject(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;object&lt;/span&gt; o)
		{
		}

		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// Las propiedades ITemplate son las que permiten tener texto HTML + ASP.NET como parte de una propiedad de un control&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;value&amp;gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
		[TemplateContainer(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;typeof&lt;/span&gt;(TagItem))]
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; ITemplate DoAction
		{
			get { &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;return&lt;/span&gt; _doAction; }
			set { _doAction &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; value; }
		}

		[TemplateContainer(&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;typeof&lt;/span&gt;(TagItem))]
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; ITemplate ElseAction
		{
			get { &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;return&lt;/span&gt; _elseAction; }
			set { _elseAction &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; value; }
		}  

		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// Creamos los controles hijos.&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// En función de la evaluación de la expresión (en este caso un simple número) creamos los controles hijos&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// a partir del template DoAction o ElseAction (según sea el número != 0 o ==0).&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;protected&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;override&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; CreateChildControls()
		{

			&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;int&lt;/span&gt; bi &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; 0;
			&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;try&lt;/span&gt;
			{
				bi &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; Convert.ToInt32(_expression);
			}
			&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;catch&lt;/span&gt; (Exception) { }


			&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;if&lt;/span&gt; (bi &amp;gt; 0)
			{
				FillActionTemplate(DoAction);
			}
			&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;else&lt;/span&gt;
			{
				&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;if&lt;/span&gt; (ElseAction !&lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;null&lt;/span&gt;)
				{
					FillActionTemplate(ElseAction);
				}
			}
		}

		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// Rellena un ITemplate con los controles hijos que se crean a partir del código HTML + ASP.NET que está&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// dentro de este template&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
		&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;/// &amp;lt;param name="action"&amp;gt;ITemplate a rellenar&amp;lt;/param&amp;gt;&lt;/span&gt;
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;private&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;void&lt;/span&gt; FillActionTemplate(ITemplate action)
		{
			&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;// clear any existing child controls&lt;/span&gt;
			Controls.Clear();
			&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;// create item&lt;/span&gt;
			TagItem item &lt;span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;=&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;new&lt;/span&gt; TagItem();
			&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;// initialize item from template&lt;/span&gt;
			action.InstantiateIn(item);
			&lt;span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;// add item to the child controls collection&lt;/span&gt;
			Controls.Add(item);

		}
	}

	&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; &lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;class&lt;/span&gt; TagItem : Control, INamingContainer
	{
		&lt;span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px"&gt;public&lt;/span&gt; TagItem()
		{

		}
	}

&lt;/span&gt;&lt;/pre&gt;

El código de la página ASPX seria algo así como:&lt;br /&gt;&lt;br /&gt;

&lt;pre&gt;
&lt;span style="font-family: courier new; font-size: 11px"&gt;
        &amp;lt;ufo:tagif id="TagIf1" runat="server" expression="0"&amp;gt;&lt;br /&gt;
            &amp;lt;doaction&amp;gt;&lt;br /&gt;
                &amp;lt;h1&amp;gt;Pues sí&amp;lt;/h1&amp;gt;&lt;br /&gt;
            &amp;lt;/doaction&amp;gt;&lt;br /&gt;
            &amp;lt;elseaction&amp;gt;&lt;br /&gt;
               &amp;lt;h1&amp;gt;Pues no!&amp;lt;/h1&amp;gt;&lt;br /&gt;
               &amp;lt;hr /&amp;gt;&lt;br /&gt;
               &amp;lt;asp:textbox id="TextBox1" runat="server"&amp;gt;&amp;lt;/asp:textbox&amp;gt;&lt;br /&gt;
            &amp;lt;/elseaction&amp;gt;&lt;br /&gt;
        &amp;lt;/ufo:tagif&amp;gt;&lt;br /&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;
Según el contenido de Expression sea "0" o cualquier otro número distinto de 0, se ejecuta el código HTML (y ASP.NET) que esté contenido en DoAction o en ElseAction.&lt;/p&gt;&lt;p&gt;

Un saludo!&lt;/p&gt;&lt;img src ="http://blogs.clearscreen.com/edu/aggbug/1455.aspx" width = "1" height = "1" /&gt;</description><body xmlns="http://www.w3.org/1999/xhtml">Comentaba algunos días que intentaría a ver si era posible hacer algún control en ASP.NET que permitiera hacer programación tag-based, es decir algo así como:

<cfif expression="expresion_a_evaluar">
// Código asp.net + HTML a  ejecutar en caso de que se cumpla la expresión
<cfelse>
// Código asp.net + HTML a ejecutar en caso de que no se cumpla la expresión
</cfelse></cfif>

Bueno... Pues la verdad es que ya tengo un esqueleto que más o menos hace esto, y no es muy complicado: La clave está en el interfaz ITemplate. Si declaramos propiedades de tipo ITemplate se puede colocar etiquetas HTML y ASP.NET dentro del webcontrol y luego dinámicamente transformar dichas etiquetas en los controles de servidor reales...

<pre><span style="color: Black; background-color: Transparent; font-family: Courier New; font-size: 11px">
	[ToolboxData(<span style="color: #666666; background-color: #e4e4e4; font-family: Courier New; font-size: 11px">"&lt;{0}:TagIf runat=server&gt;&lt;/{0}:TagIf&gt;"</span>)]
	[ParseChildren(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">true</span>)]
	<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">class</span> TagIf : Control, INamingContainer
	{

		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> ITemplate _doAction <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">null</span>;
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> ITemplate _elseAction <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">null</span>;
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> _expression <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">null</span>;

		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// Expresión a evaluar para decidir si mostrar el contenido del DoAction o del ElseAction</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;/summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;value&gt;En esta versión... un número (constante) ;)&lt;/value&gt;		</span>
                <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">string</span> Expression
		{
			get { <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">return</span> _expression; }
			set { _expression <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> value; }
		}

		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">// override to prevent literal controls from being added as children</span>
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">override</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> AddParsedSubObject(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">object</span> o)
		{
		}

		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// Las propiedades ITemplate son las que permiten tener texto HTML + ASP.NET como parte de una propiedad de un control</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;/summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;value&gt;&lt;/value&gt;</span>
		[TemplateContainer(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">typeof</span>(TagItem))]
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> ITemplate DoAction
		{
			get { <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">return</span> _doAction; }
			set { _doAction <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> value; }
		}

		[TemplateContainer(<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">typeof</span>(TagItem))]
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> ITemplate ElseAction
		{
			get { <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">return</span> _elseAction; }
			set { _elseAction <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> value; }
		}  

		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// Creamos los controles hijos.</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// En función de la evaluación de la expresión (en este caso un simple número) creamos los controles hijos</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// a partir del template DoAction o ElseAction (según sea el número != 0 o ==0).</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;/summary&gt;</span>
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">protected</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">override</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> CreateChildControls()
		{

			<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">int</span> bi <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> 0;
			<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">try</span>
			{
				bi <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> Convert.ToInt32(_expression);
			}
			<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">catch</span> (Exception) { }


			<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">if</span> (bi &gt; 0)
			{
				FillActionTemplate(DoAction);
			}
			<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">else</span>
			{
				<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">if</span> (ElseAction !<span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">null</span>)
				{
					FillActionTemplate(ElseAction);
				}
			}
		}

		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// Rellena un ITemplate con los controles hijos que se crean a partir del código HTML + ASP.NET que está</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// dentro de este template</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;/summary&gt;</span>
		<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">/// &lt;param name="action"&gt;ITemplate a rellenar&lt;/param&gt;</span>
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">private</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">void</span> FillActionTemplate(ITemplate action)
		{
			<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">// clear any existing child controls</span>
			Controls.Clear();
			<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">// create item</span>
			TagItem item <span style="color: Red; background-color: Transparent; font-family: Courier New; font-size: 11px">=</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">new</span> TagItem();
			<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">// initialize item from template</span>
			action.InstantiateIn(item);
			<span style="color: Green; background-color: Transparent; font-family: Courier New; font-size: 11px">// add item to the child controls collection</span>
			Controls.Add(item);

		}
	}

	<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> <span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">class</span> TagItem : Control, INamingContainer
	{
		<span style="color: Blue; background-color: Transparent; font-family: Courier New; font-size: 11px">public</span> TagItem()
		{

		}
	}

</span></pre>

El código de la página ASPX seria algo así como:<br /><br />

<pre>
<span style="font-family: courier new; font-size: 11px">
        &lt;ufo:tagif id="TagIf1" runat="server" expression="0"&gt;<br />
            &lt;doaction&gt;<br />
                &lt;h1&gt;Pues sí&lt;/h1&gt;<br />
            &lt;/doaction&gt;<br />
            &lt;elseaction&gt;<br />
               &lt;h1&gt;Pues no!&lt;/h1&gt;<br />
               &lt;hr /&gt;<br />
               &lt;asp:textbox id="TextBox1" runat="server"&gt;&lt;/asp:textbox&gt;<br />
            &lt;/elseaction&gt;<br />
        &lt;/ufo:tagif&gt;<br />
</span>
</pre>
<p>
Según el contenido de Expression sea "0" o cualquier otro número distinto de 0, se ejecuta el código HTML (y ASP.NET) que esté contenido en DoAction o en ElseAction.</p><p>

Un saludo!</p><img src ="http://blogs.clearscreen.com/edu/aggbug/1455.aspx" width = "1" height = "1" /></body></item></channel></rss>