Tech Tips http://blogs.ugidotnet.org/dsenatore/category/Tech Tips.aspx Tech Tips it-IT Davide Senatore Subtext Version 2.6.0.0 SQL Server: strano comportamento della clausola IN http://blogs.ugidotnet.org/dsenatore/archive/2011/07/27/sql-server-strano-comportamento-della-clausola-in.aspx <p>Oggi mi è stato sottoposto un problema veramente curioso. Una collega mi ha fatto notare che durante un’operazione di manutenzione di un DB SQL Server 2008 R2 ha lanciato una query di DELETE che non si è comportata come previsto. In pratica, questa query stava cancellando arbitrariamente i dati dalla tabella senza rispettare la clausola WHERE che compariva regolarmente nel testo della query.</p> <p>Il comando dato al server è il seguente:</p> <blockquote> <p><font face="Courier New">DELETE FROM dbo.Utenti WHERE IDUtente IN (SELECT IDUtente FROM dbo.Operatori)</font></p> </blockquote> <p>Come mai il comportamento è strano? Perchè effettivamente in questa query c’è un errore! La tabella Operatori NON contiene il campo IDUtente, per cui, lanciato da solo, il comando</p> <blockquote> <p><font face="Courier New">SELECT IDUtente FROM dbo.Operatori</font></p> </blockquote> <p>Dà un errore di tipo:</p> <blockquote> <p><font color="#ff0000" face="Courier New">Msg 207, Level 16, State 1, Line 1 Invalid column name 'IDUtente'.</font></p> </blockquote> <p>Lo stesso errore <u>non viene riportato</u> se la query viene lanciata come subquery della clausola IN, bensì la query viene eseguita completamente, cancellando TUTTI i record dalla tabella Utenti, ignorando per cui la clausola WHERE IDUtente IN (…).</p> <p>E’ da notare come utilizzando un nome di campo non esistente nè nella tabella Utenti, nè nella tabella Operatori la query vada in errore; per cui è da supporre che il comando non vada in errore proprio perchè il campo IDUtente compare nella tabella Utenti (cosa comunque errata).</p> <p>Per ricreare il “problema” ed indagare ulteriormente, ho creato un piccolo DB con 2 tabelle, Utenti e Operatori, così strutturate:</p> <ul> <li><strong>Utenti</strong></li> <ul> <li>IDUtente [int] PK</li> <li>Nome [varchar(50)]</li> </ul> <li><strong>Operatori</strong></li> <ul> <li>IDOperatore [int] PK</li> <li>Nome [varchar(50)]</li> </ul> </ul> <p>nella tabella Utenti ho 5 records (con IDUtente 1,2,3,4,5), mentre in quella Operatori ne ho 2 (con IDOperatore 1,2)</p> <p>Questa query seleziona tutti gli utenti:</p> <blockquote> <p><font face="Courier New">SELECT * FROM dbo.Utenti</font></p> </blockquote> <p>Questa query seleziona solo gli utenti 1 e 2</p> <blockquote> <p><font face="Courier New">SELECT * FROM dbo.Utenti WHERE IDUtente IN (SELECT IDOperatore FROM dbo.Operatori)</font></p> </blockquote> <p>Questa query restituisce un errore:</p> <blockquote> <p><font face="Courier New">SELECT IDUtente FROM dbo.Operatori</font></p> <p><font color="#ff0000" face="Courier New">Msg 207, Level 16, State 1, Line 1 Invalid column name 'IDUtente'.</font></p> </blockquote> <p>Questa query, stranamente, restituisce TUTTI gli utenti:</p> <blockquote> <p><font face="Courier New">SELECT * FROM dbo.Utenti WHERE IDUtente IN (SELECT IDUtente FROM dbo.Operatori)</font></p> </blockquote> <p>Non dovrebbe restituire tutti gli utenti, in quanto il campo IDUtente non fa parte della tabella Operatori. Altrettanto stranamente anche questa query restituisce tutti gli utenti:</p> <blockquote> <p><font face="Courier New">SELECT * FROM dbo.Utenti WHERE IDUtente IN (SELECT IDUtente)</font></p> </blockquote> <p>Per induzione, penso che SQL interpreti il campo IDUtente come campo dell’unica tabella elencata nella clausola FROM, anche se questo è a mio avviso fuorviante.</p> <p>Quindi, quando fate una query di delete con una clausola IN, fate particolare attenzione ai nomi dei campi, e magari prima di eseguirla provate a fare una SELECT.</p><img src="http://blogs.ugidotnet.org/dsenatore/aggbug/100236.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2011/07/27/sql-server-strano-comportamento-della-clausola-in.aspx Wed, 27 Jul 2011 13:42:40 GMT http://blogs.ugidotnet.org/dsenatore/archive/2011/07/27/sql-server-strano-comportamento-della-clausola-in.aspx#feedback 17 http://blogs.ugidotnet.org/dsenatore/comments/commentRss/100236.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/100236.aspx Bad habits: non avere un (buon) processo di release e deployment http://blogs.ugidotnet.org/dsenatore/archive/2009/10/04/bad-habits-non-avere-un-buon-processo-di-release-e.aspx <p>Alle volte resto sconcertato: la maggior parte delle persone pensa che l’unica cosa importante per fornire il classico “programmino” ad un cliente sia scriverlo. Non mi stancherò mai di ripeterlo: il nostro obiettivo in qualità di sviluppatori è <strong>CONSEGNARE</strong> il software e non solamente scriverlo. Ecco perchè il processo di release/deploy di un software è di estrema importanza per la qualità e la gestione del ciclo di vita del software stesso.</p> <p>Inoltre, non si deve mai dimenticare che il processo di rilascio di un software deve essere <u>ripetibile</u>, ovvero non devo ogni volta impazzire dietro a mille variabili per rilasciare la nuova versione del programma al mio cliente. Alcuni degli errori/cattive abitudini nel rilascio di un software possono essere annoverate tra:</p> <ul> <li>Cattiva gestione (o addirittura non gestione) del versioning: se non gestiamo il versioning, non sapremo mai che versione del software sta usando il nostro cliente, con il risultato che se ci riporta un baco, non sapremo mai se l’abbiamo già risolto </li> <li>Impiego di un controllo del codice sorgente “fatto in casa” (tipo zip dei file di progetto, per intenderci): questo è piuttosto grave, in quanto non riusciamo ad avere una traccia delle precedenti versioni del progetto, nè possiamo “ripristinare” una precedente versione per simulare un bug riscontrato in sede dal cliente </li> <li>Scarsa (o addirittura nulla, sigh!) documentazione dei prerequisiti per far funzionare il software: avete promesso un software fighissimo, lo sviluppate su XP, quando lo consegnate venite a sapere che il cliente impiega Vista e, per qualche “leggerezza” (leggi bad habit) di programmazione, su Vista il tutto non funziona. </li> <li>Assenza di un qualsivoglia file/documento/vademecum/aiuto per l’installazione e la configurazione: alle volte non saremo noi ad installare il software, ma qualcun altro. In questi casi, ma anche se saremo sempre noi a farlo, perchè fra tre mesi mi sarò dimenticato a cosa serve il campo XYZ nel file web.config che DOVEVA assumere il valore 345, è bene produrre e tenere aggiornato un documento che illustri con sufficiente dettaglio cosa si deve fare per installare correttamente il software </li> <li>Assenza di un ambiente di test per il deployment: questa “bad habit” è piuttosto comune ed è la causa del famoso “baco pigliatutto”: “ma da me funziona!” (macchina dello sviluppatore). I veri problemi di deployment emergono in fase di deployment. Punto. Quindi bisogna simularla, esattamente come si farebbe con un qualunque altro test. </li> <li>Gestione errata o assente dell’aggiornamento del database (se il software ne impiega uno, ovviamente). Questo è uno dei tasti più dolenti, in quanto è veramente un grosso lavoro mantenere aggiornati gli script di allineamento del database. Del resto ho visto troppe volte cose VERAMENTE brutte fatte per mantenere aggiornati database di produzione e database di sviluppo. La strada qui è una sola: bisogna gestire le versioni e gli aggiornamenti del database con gli script che devono poter essere lanciati in sequenza, a partire da una certa versione di partenza del database. </li> </ul> <p>Gestire un buon processo di release e deployment non è una cosa da sottovalutare: è un’attività tanto importante quanto la scrittura di un buon codice. A mio parere, anche il prodotto più piccolo merita di avere una buona gestione del processo di release, in quanto il tempo speso si ripagherà con i grattacapi in meno che avremo in futuro, durante il ciclo di vita dei vari rilasci.</p><img src="http://blogs.ugidotnet.org/dsenatore/aggbug/97178.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2009/10/04/bad-habits-non-avere-un-buon-processo-di-release-e.aspx Sun, 04 Oct 2009 19:48:44 GMT http://blogs.ugidotnet.org/dsenatore/archive/2009/10/04/bad-habits-non-avere-un-buon-processo-di-release-e.aspx#feedback http://blogs.ugidotnet.org/dsenatore/comments/commentRss/97178.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/97178.aspx Nuova versione del tool VB6(2)XAML http://blogs.ugidotnet.org/dsenatore/archive/2006/12/18/60028.aspx <p>Ho rilasciato una nuova versione del tool da me realizzato VB6(2)XAML. In questa nuova versione ho aggiunto/risolto:</p> <ul> <li>una lista dei controlli "sconosciuti" che vengono rilevati nella form durante il parsing;</li> <li>un filtro di output per la modifica del codice XAML generato dopo il parsing;</li> <li>risolto il baco della mancanza della proprietà "Caption" nei controlli VB6. Ora il parser non va più in errore.</li></ul> <p>Per chi fosse interessato, può scaricare la nuova versione <a href="http://www.codesapiens.net/LinkClick.aspx?link=VB62XAML_03beta.zip&amp;tabid=74&amp;mid=434">qui</a>. Chiunque volesse è invitato ad inviarmi feedback.</p> <p><u>ENGLISH Version:</u></p> <p>I have released a new version of my VB6(2)XAML tool. In this new version&nbsp;I have added/fixed:</p> <ul> <li>a list of "unknown" controls found during parsing of VB form;</li> <li>an output filter for tweaking the XAML code generated after parsing;</li> <li>resolved the bug due to the missing of "Caption" property in some VB6 Controls. Now the parser doesn't generate errors anymore.</li></ul> <p>For those interested, the new version is <a href="http://www.codesapiens.net/LinkClick.aspx?link=VB62XAML_03beta.zip&amp;tabid=74&amp;mid=434">here</a>. if you want, leave a feedback.</p><img src="http://blogs.ugidotnet.org/dsenatore/aggbug/60028.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/12/18/60028.aspx Mon, 18 Dec 2006 12:50:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/12/18/60028.aspx#feedback http://blogs.ugidotnet.org/dsenatore/comments/commentRss/60028.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/60028.aspx VB6(2)XAML: il convertitore di Forms Visual Basic 6.0 http://blogs.ugidotnet.org/dsenatore/archive/2006/11/26/57347.aspx <img align="left" src="http://www.codesapiens.net/public/LogoNew.gif" alt="" /> <p>Dopo averlo "coltivato" per le varie CTP di WINFX e .net Framework 3.0, ed aver cercato di realizzare qualcosa di veramente aperto e modificabile, ho deciso di rilasciare gratuitamente il convertitore <strong>VB6(2)XAML</strong>. Questo convertitore consente di convertire una <strong>Form di Visual Basic 6.0 in una Windows di Windows Presentation Foundation</strong>, utilizzando XAML come linguaggio di descrizione. Il progetto è <strong>MOLTO</strong> in beta, nel senso che non è completo e non è testato a fondo... Mi attendo da voi tutti suggerimenti ed idee su cosa implementare e su come farlo per massimizzare le potenzialità di questo strumento. Per il momento, il progetto consiste in un parser che interpretato il codice della form vb6, passa il controllo ad una serie di classi che si occupano di convertire i particolari controlli VB6. Ovviamente il motore è estensibile, in quanto da solo non avrei mai potuto coprire le esigenze di conversione di tutti, e per questo ognuno sarà libero di creare la propria "conversion class" che si occupi della conversione di un particolare controllo. E' mia intenzione rilasciare un semplice tutorial con la spiegazione di come creare una classe che, ad esempio, converta in modo alternativo il controllo Label.</p> <p>Mi auguro di cuore che qualcuno possa trarre beneficio da tale programma, e che magari tutti insieme si possa ottenere qualcosa di veramente completo che consenta di ottenere una migrazione totale da VB6 a WPF.</p> <p>Per scaricare i binari, <a href="http://www.ingeniumsoft.com/LinkClick.aspx?link=VB62XAML_1_0_0_0.zip&amp;tabid=63&amp;mid=398&amp;language=en-US">cliccate qui</a>. Se qualcuno mi vuole contattare per commenti, idee od osservazioni, lo faccia pure senza alcuna remora!!</p> <p><strong><em>English Version:</em></strong></p> <p>After some time of "developing" through the various CTP of WinFX and the .net Framework 3.0, with the effort of building something really "open and editable", i have decided to release the VB6(2)XAML converter.<br /> This converter allows to convert a VB6 Form in a Windows Presentation Foundation Window, using XAML as declarative language.<br /> The project is *really* in beta version, because it is not complete and not thoroughly tested... I'm expecting from you ideas on what to imlement and how, to maximize the potential of this tool.<br /> For now, the project is a parser that parse a VB6 Form and then, for each control contained, use an "hand made" conversion class that tackle the conversion.<br /> Obviously the engine is extensible, and you can develop your own conversion classes to btain the results you need.</p> <p>I hope that someone can gain advantage from this tool, and maybe, with the help of the developer community we'll obtain a complete tool that can migrate every control from VB6 to WPF.</p> <p>To download the bits, <a href="http://www.ingeniumsoft.com/LinkClick.aspx?link=VB62XAML_1_0_0_0.zip&amp;tabid=63&amp;mid=398&amp;language=en-US">click here</a>. If you want to contact me, do it, without any kind of problem! I will be very happy to accept comments, ideas and of course, needs!<br /> </p><img src="http://blogs.ugidotnet.org/dsenatore/aggbug/57347.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/11/26/57347.aspx Sun, 26 Nov 2006 19:49:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/11/26/57347.aspx#feedback 8 http://blogs.ugidotnet.org/dsenatore/comments/commentRss/57347.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/57347.aspx Microsoft Expression Web http://blogs.ugidotnet.org/dsenatore/archive/2006/10/17/51961.aspx <p>Oggi mi sono imbattuto nella versione BETA 1 di Microsoft Expression Web (prima conosciuto come Microsoft Expression Web Designer).</p> <p>La potete trovare <a href="http://www.microsoft.com/products/expression/en/web_designer/wd_free_trial.aspx">qui</a>. Io l'ho scaricata ed installata... ma devo ancora apprezzarne le innovazioni...di primo acchito sembra un Frontpage con i controlli di ASP.net 2.0.</p> <p>A mio modesto avviso, uno strumento per la creazione di pagine web deve ASSOLUTAMENTE velocizzare il flusso di creazione delle pagine stesse, altrimenti non ha senso di esistere. Indagheremo...</p><img src="http://blogs.ugidotnet.org/dsenatore/aggbug/51961.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/10/17/51961.aspx Tue, 17 Oct 2006 16:39:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/10/17/51961.aspx#feedback 2 http://blogs.ugidotnet.org/dsenatore/comments/commentRss/51961.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/51961.aspx Utilizzare la referenza ad un SubReport in Reporting Services http://blogs.ugidotnet.org/dsenatore/archive/2006/09/07/47464.aspx <P><FONT face=Arial size=2>Impiegando SQL Server 2005 reporting Services, mi &#232; capitato di utilizzare l'oggetto Subreport. Una volta inserito all'interno del report, &#232; possibile impostare la propriet&#224; ReportName. Questa viene "suggerita" da una combo, e di primo acchito si potrebbe pensare che i subreport debbano trovarsi nella stessa cartella dove si trova il report "ospite". Questo non &#232; vero, in quanto &#232; possibile utilizzare reports presenti in altre cartelle, semplicemente utilizzando come ReportName il percorso completo che individua la posizione del subreport. Possiamo vedere il frammento XML che modella tale oggetto subreport:</FONT></P> <P><FONT face="Courier New" size=2>&lt;Subreport Name="subreport1"&gt;<BR>&lt;Left&gt;0.25cm&lt;/Left&gt;</FONT><BR><FONT face="Courier New" size=2>&lt;Top&gt;1cm&lt;/Top&gt;</FONT><BR><FONT face="Courier New" size=2>&lt;Width&gt;7.5cm&lt;/Width&gt;</FONT><BR><FONT face="Courier New" size=2>&lt;ReportName&gt;/SimpleReport/MySubreport&lt;/ReportName&gt;</FONT><BR><FONT face="Courier New" size=2>&lt;Height&gt;3cm&lt;/Height&gt;</FONT><BR><FONT face="Courier New" size=2>&lt;/</FONT><FONT face="Courier New" size=2>Subreport&gt;</FONT></P> <P><FONT face=Arial size=2>In questo modo &#232; possibile creare una "libreria" di subreport da includere in vari progetti di reporting.</FONT></P><img src="http://blogs.ugidotnet.org/dsenatore/aggbug/47464.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/09/07/47464.aspx Thu, 07 Sep 2006 01:04:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/09/07/47464.aspx#feedback http://blogs.ugidotnet.org/dsenatore/comments/commentRss/47464.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/47464.aspx EnableVisualStyles() e le icone dei controlli *View http://blogs.ugidotnet.org/dsenatore/archive/2006/05/10/40418.aspx <FONT face=Verdana size=2><P>Il supporto per i Temi di Windows è presente nelle applicazioni Windows Forms sin dalla versione 1.0 del Framework .net. Dalla versione 1.1, per evitare l'onere di aggiungere un file .manifest da distribuire con l'applicazione, è stato introdotto il metodo EnableVisualStyles() della classe Application. L'abilitazione dei temi, però, soffriva di un fastidioso bug, che consisteva nella "<STRONG>sparizione</STRONG>" <IMG height=19 src="http://www.imhoproject.org/files/serio.gif" width=19 align=absMiddle border=0>&nbsp;delle icone delle toolbar presenti nella nostra applicazione. Tale bug può essere risolto richiamando Application.DoEvents() appena dopo Application.EnableVisualStyles().</P><P>Nel Framework 2.0 il bug è stato risolto, ma ieri sera ho comunque trovato dei problemi relativi ai controlli ListView e TreeView, ovvero le icone sparivano nuovamente. Da notare che le toolbar funzionavano perfettamente visualizzando le icone. Il problema sembra infatti collegato all'uso del controllo ImageList. Se qualcuno si trovasse nella stessa situazione, consideri che <U>il problema è scomparso</U> <IMG height=19 src="http://www.imhoproject.org/files/allegro.gif" width=19 align=absMiddle border=0>&nbsp;nel momento stesso in cui ho spostato la chiamata Application.EnableVisualStyles() da un metodo che avevo creato alla prima riga del metodo Main, entry point dell'applicazione:</FONT></P></FONT><DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: black 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: black 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: gainsboro"><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">&lt;STAThread()&gt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Public&nbsp;Shared&nbsp;Sub&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Main()<BR>&nbsp;&nbsp;&nbsp;&nbsp;Application.EnableVisualStyles()<BR>&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;Application.Run(</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">new&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">MainForm())<BR></SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">End&nbsp;Sub<BR></DIV><P><FONT face=Verdana color=black>Il problema sembra dovuto al fatto che nella mia applicazione richiamavo codice relativo alle funzionalità delle Windows Forms <EM><STRONG>prima</STRONG></EM> della chiamata ad EnableVisualStyles(). Quindi è fortemente consigliato, qualora vogliate realizzare un'applicazione Windows Forms che faccia uso di temi ed utilizzi un metodo Main come entry point, richiamare come prima istruzione del metodo Main la <STRONG>Application.EnableVisualStyles()</STRONG>.</FONT></SPAN></P><!-- Powered by IMHO 1.3 (EN) Instant Blogger Copyright (c) 2005 A.Boschin - http://www.imhoproject.org --> <img src="http://blogs.ugidotnet.org/dsenatore/aggbug/40418.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/05/10/40418.aspx Wed, 10 May 2006 13:43:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/05/10/40418.aspx#feedback http://blogs.ugidotnet.org/dsenatore/comments/commentRss/40418.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/40418.aspx ASP.net e il nuovo modello di compilazione http://blogs.ugidotnet.org/dsenatore/archive/2006/05/04/40067.aspx <P><FONT face=Verdana size=2>Oggi ho fatto intrapreso uno studio del modello di compilazione di ASP.net che ha dato risultati interessanti. Infatti sono riuscito ad utilizzare due linguaggi di programmazione, VB e C#, all'interno della stessa applicazione Web. Come si fa? Bene, è presto spiegato. Come prima cosa, dopo aver creato un progetto di sito web nel linguaggio preferito, aggiungo la directory <STRONG>App_Code. </STRONG>A questo punto, all'interno di App_code, creo due sottodirectory<STRONG>, VB </STRONG>e<STRONG> CS</STRONG>, che conterranno, rispettivamente, i file Visual Basic e C#. Subito dopo, aprendo il file web.config, aggiungo nella sezione &lt;compilation&gt; le due directory di compilazione:</FONT></P><FONT face=Verdana size=2><DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: black 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: black 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: gainsboro"><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">&lt;compilation&nbsp;debug="false"&nbsp;strict="false"&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">explicit</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">="true"&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;codeSubDirectories&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">add&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">directoryName="VB"/&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">add&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">directoryName="CS"/&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/codeSubDirectories&gt;<BR>&lt;/compilation&gt;<BR></DIV><P><FONT face=Verdana>Occhio: non è obbligatorio chiamare le directory VB e CS <IMG height=19 src="http://www.imhoproject.org/files/occhiolino.gif" width=19 align=absMiddle border=0></SPAN></FONT>.</FONT></P><P><FONT face=Verdana>A questo punto creo la classe Person in VB</FONT></P><DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: black 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: black 1px solid; WIDTH: 705px; PADDING-TOP: 5px; BORDER-BOTTOM: black 1px solid; HEIGHT: 200px; BACKGROUND-COLOR: gainsboro"><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Imports&nbsp;Microsoft.VisualBasic<BR><BR>Public&nbsp;Class&nbsp;Person<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Private&nbsp;_name&nbsp;As&nbsp;String<BR>&nbsp;&nbsp;&nbsp;&nbsp;Public&nbsp;Property&nbsp;Name()&nbsp;As&nbsp;String<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;_name<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;Get<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set(ByVal&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">value&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">As&nbsp;String)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_name&nbsp;=&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">value<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">End&nbsp;Set<BR>&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;Property<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Private&nbsp;_age&nbsp;As&nbsp;Integer<BR>&nbsp;&nbsp;&nbsp;&nbsp;Public&nbsp;Property&nbsp;Age()&nbsp;As&nbsp;Integer<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Get<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;_age<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;Get<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set(ByVal&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">value&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">As&nbsp;Integer)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_age&nbsp;=&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">value<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">End&nbsp;Set<BR>&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;Property<BR><BR>End&nbsp;Class<BR></DIV><P><FONT face=Verdana>e la classe Developer in C# che faccio ereditare da Person (!!!)</FONT></P><DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: black 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: black 1px solid; WIDTH: 704px; PADDING-TOP: 5px; BORDER-BOTTOM: black 1px solid; HEIGHT: 200px; BACKGROUND-COLOR: gainsboro"><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">public&nbsp;class&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Developer:Person<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">public&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Developer()<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">private&nbsp;string&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_languageUsed;<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">public&nbsp;string&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">LanguageUsed<BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">get&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">{&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">return&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_languageUsed;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">set&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">{&nbsp;_languageUsed&nbsp;=&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">value</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>}<BR></DIV><P><FONT face=Verdana>Nella pagina Default.aspx, a questo punto, posso sbizzarrirmi con cose di questo tipo:</FONT></P><DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: black 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; BORDER-LEFT: black 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: black 1px solid; BACKGROUND-COLOR: gainsboro"><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Dim&nbsp;_d&nbsp;As&nbsp;New&nbsp;Developer<BR>_d.Age&nbsp;=&nbsp;30<BR>_d.Name&nbsp;=&nbsp;"Davide"<BR>_d.LanguageUsed&nbsp;=&nbsp;"Visual&nbsp;Basic.net"<BR></DIV><P><FONT face=Verdana>Non male come feature... <STRONG>Attenzione</STRONG> però! Quando si pubblica il sito (compilandolo) viene creata una dll per ogni directory! Questa feature può tornare utilile se abbiamo sviluppatori che utilizzano linguaggi differenti o se vogliamo fondere in un progetto codice già scritto in progetti precedenti, nei quali abbiamo usato VB o C#.</FONT></SPAN></SPAN></SPAN></SPAN></FONT></P><!-- Powered by IMHO 1.3 (EN) Instant Blogger Copyright (c) 2005 A.Boschin - http://www.imhoproject.org --> <img src="http://blogs.ugidotnet.org/dsenatore/aggbug/40067.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/05/04/40067.aspx Thu, 04 May 2006 19:01:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/05/04/40067.aspx#feedback 3 http://blogs.ugidotnet.org/dsenatore/comments/commentRss/40067.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/40067.aspx Custom TreeView...con .net 2.0 &#232; facile! http://blogs.ugidotnet.org/dsenatore/archive/2006/04/07/38501.aspx <FONT face=Verdana size=2><P>Lavorando su WinForms, ho cercato di creare una treeview che mi permettesse di disegnare a piacimento i nodi, le icone ed il testo. Con le "nuove" Windows Forms, è stato esposto l'evento DrawNode e DrawItem dei controlli TreeView e ListView, per cui è possibile gestire in modo autonomo il disegno dei nodi <IMG height=19 src="http://www.imhoproject.org/files/occhiolino.gif" width=19 align=absMiddle border=0>. Facendo l'overrides del metodo OnDrawNode, quindi, mi sono creato una treeview che imita il comportamento della toolbox di Visual Studio. Il codice per l'overrides è riportato qui sotto.</P><DIV style="BORDER-RIGHT: black 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: black 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; OVERFLOW: auto; BORDER-LEFT: black 1px solid; WIDTH: 691px; PADDING-TOP: 5px; BORDER-BOTTOM: black 1px solid; HEIGHT: 254px; BACKGROUND-COLOR: gainsboro">&nbsp;&nbsp;&nbsp;&nbsp;<SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Protected&nbsp;Overrides&nbsp;Sub&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">OnDrawNode(</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">ByVal&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">System.Windows.Forms.DrawTreeNodeEventArgs)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #008000; FONT-FAMILY: Courier New">'Clear&nbsp;Background<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Graphics.FillRectangle(SystemBrushes.Control,&nbsp;e.Bounds)<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Dim&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_rect&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Rectangle&nbsp;=&nbsp;Rectangle.Inflate(e.Bounds,&nbsp;-1,&nbsp;-1)<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">If&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Bounds.</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Width&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">&gt;&nbsp;0&nbsp;AndAlso&nbsp;e.Bounds.</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Height&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">&gt;&nbsp;0&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Node.Parent&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Is&nbsp;Nothing&nbsp;Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_boldFont&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;New&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Font(</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Me</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">.Font,&nbsp;FontStyle.Bold)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">If&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Node.IsSelected&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #008000; FONT-FAMILY: Courier New">'Selected&nbsp;Root&nbsp;node<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Dim&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_backGroundBrush&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;New&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">SolidBrush(Color.FromArgb(255,&nbsp;225,&nbsp;230,&nbsp;232))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.Graphics.FillRectangle(_backGroundBrush,&nbsp;_rect)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Dim&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_borderPen&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Pen&nbsp;=&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">New&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Pen(Color.FromArgb(255,&nbsp;49,&nbsp;106,&nbsp;194))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.Graphics.DrawRectangle(_borderPen,&nbsp;_rect)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_backGroundBrush.Dispose()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_borderPen.Dispose()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #008000; FONT-FAMILY: Courier New">'Standard&nbsp;Root&nbsp;Node<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Dim&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_gradientBrush&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;New&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Drawing2D.LinearGradientBrush(_rect,&nbsp;Color.FromArgb(255,&nbsp;221,&nbsp;220,&nbsp;203),&nbsp;Color.FromArgb(255,&nbsp;196,&nbsp;193,&nbsp;176),&nbsp;Drawing2D.LinearGradientMode.Vertical)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.Graphics.FillRectangle(_gradientBrush,&nbsp;_rect)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_gradientBrush.Dispose()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">End&nbsp;If<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Graphics.DrawString(e.Node.Text,&nbsp;_boldFont,&nbsp;Brushes.</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Black</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">,&nbsp;e.Bounds.X&nbsp;+&nbsp;e.Node.TreeView.Indent,&nbsp;e.Bounds.Y&nbsp;+&nbsp;2)<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">If&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Node.IsExpanded&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Graphics.DrawImage(My.Resources.Minus,&nbsp;e.Bounds.X&nbsp;+&nbsp;7,&nbsp;e.Bounds.Y&nbsp;+&nbsp;4,&nbsp;9,&nbsp;9)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Graphics.DrawImage(My.Resources.Plus,&nbsp;e.Bounds.X&nbsp;+&nbsp;7,&nbsp;e.Bounds.Y&nbsp;+&nbsp;4,&nbsp;9,&nbsp;9)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">End&nbsp;If<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If&nbsp;Not&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Node.TreeView.ImageList&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Is&nbsp;Nothing&nbsp;Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dim&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_image&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">As&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">Image&nbsp;=&nbsp;e.Node.TreeView.ImageList.Images(e.Node.ImageIndex)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">If&nbsp;Not&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">_image&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Is&nbsp;Nothing&nbsp;Then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Graphics.DrawImage(_image,&nbsp;e.Bounds.X&nbsp;+&nbsp;9,&nbsp;e.Bounds.Y&nbsp;+&nbsp;1,&nbsp;16,&nbsp;16)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">End&nbsp;If<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;If<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">e.Graphics.DrawString(e.Node.Text,&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Me</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">.Font,&nbsp;Brushes.</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">Black</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #000000; FONT-FAMILY: Courier New">,&nbsp;e.Bounds.X&nbsp;+&nbsp;e.Node.TreeView.Indent&nbsp;+&nbsp;7,&nbsp;e.Bounds.Y&nbsp;+&nbsp;2)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="FONT-SIZE: 10pt; COLOR: #0000ff; FONT-FAMILY: Courier New">End&nbsp;If<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;If<BR>&nbsp;&nbsp;&nbsp;&nbsp;End&nbsp;Sub<BR></DIV></SPAN></FONT><FONT face=Verdana size=2><P><STRONG>Attenzione!!</STRONG> Dovete creare una vostra treeview, ereditando dal controllo TreeView ed impostare il DrawMode a <STRONG>OwnerDrawAll</STRONG>.&nbsp;Considerando che è possibile far disegnare ciò che si vuole e che il nodo stesso può essere una classe derivata da TreeViewNode, non è difficile pensare alle applicazioni che questo approccio può avere. <IMG height=19 src="http://www.imhoproject.org/files/allegro.gif" width=19 align=absMiddle border=0></P></FONT><!-- Powered by IMHO 1.3 (EN) Instant Blogger Copyright (c) 2005 A.Boschin - http://www.imhoproject.org --> <img src="http://blogs.ugidotnet.org/dsenatore/aggbug/38501.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/04/07/38501.aspx Fri, 07 Apr 2006 15:49:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/04/07/38501.aspx#feedback http://blogs.ugidotnet.org/dsenatore/comments/commentRss/38501.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/38501.aspx Componente per il docking gratuito! http://blogs.ugidotnet.org/dsenatore/archive/2006/04/07/38488.aspx <FONT face=Verdana size=2><P>In questo periodo sto lavorando su un progetto che necessita di un'applicazione WinForm, la quale funga da Tool di configurazione. Cercando per la rete un componente che permetta il docking delle finestre, in stile Visual Studio, mi sono imbattuto in vari componenti, peraltro tutti molto ben realizzati, ma ahimè, tutti a pagamento. Poi ho trovato la <STRONG>DockPanel Suite di Weifen Luo</STRONG>... che dire? <IMG height=19 src="http://www.imhoproject.org/files/allegro.gif" width=19 align=absMiddle border=0>&nbsp;Il componente è realizzato bene, c'è il codice sorgente, e fa esattamente ciò che promette, con in più anche gli help per il docking, in stile VS2005. Complimenti a Weifen!!!</P><P>Lo potete trovare <A title="" href="http://sourceforge.net/projects/dockpanelsuite" target="" name="">qui</A>.</FONT><FONT face=Verdana size=2></P></FONT><!-- Powered by IMHO 1.3 (EN) Instant Blogger Copyright (c) 2005 A.Boschin - http://www.imhoproject.org --> <img src="http://blogs.ugidotnet.org/dsenatore/aggbug/38488.aspx" width="1" height="1" /> Davide Senatore http://blogs.ugidotnet.org/dsenatore/archive/2006/04/07/38488.aspx Fri, 07 Apr 2006 10:52:00 GMT http://blogs.ugidotnet.org/dsenatore/archive/2006/04/07/38488.aspx#feedback 4 http://blogs.ugidotnet.org/dsenatore/comments/commentRss/38488.aspx http://blogs.ugidotnet.org/dsenatore/services/trackbacks/38488.aspx