Technology Experience

.NET World

Programmazione, libri, snippet di codice, articoli tecnici

.NET World

Riavviare un’applicazione WPF

Da documentazione trovata su MSDN, nel buon vecchio Windows Forms era possibile riavviare l’applicazione con una sola linea di codice. Era infatti possibile invocare il metodo Restart() della classe System.Windows.Forms.Application ed il gioco era fatto.

Con WPF le cose sono un pochino cambiate, ma solo un pochino.

Dunque: innanzitutto la classe Application per le applicazioni WPF e la classe Application per le applicazioni Windows Forms sono classi differenti. Perciò occhio: se parliamo di WPF, la classe Application sta nel namespace System.Windows.

Questa classe espone una proprietà statica Current, tramite la quale è possibile accedere all’applicazione corrente all’interno dell’AppDomain. A questo punto è possibile invocare il metodo Shutdown(), che chiude l’applicazione. Come è possibile riavviarla? La cosa più semplice che ho trovato è intercettare l’evento Exit dell’applicazione e riavviarla. Quindi, supponiamo di aver messo un Button su una Windows e di voler chiudere e riavviare l’applicazione sul Click di questo bottone. Il codice sarà:

   1:  private void LanguageButton_Click(object sender, System.Windows.RoutedEventArgs e)
   2:  {
   3:      Application.Current.Exit += delegate(object s, ExitEventArgs args)
   4:      {
   5:          System.Diagnostics.Process.Start(Application.ResourceAssembly.Location);
   6:      };
   7:   
   8:      Application.Current.Shutdown();
   9:  }

Molto semplice, direi. L’unica osservazione da fare è quella di sottoscrivere l’evento Exit solo quando necessario. In questo modo, potete chiudere l’applicazione come al solito (ALT+F4, cliccando sulla X in alto a destra) e l’applicazione non riparte: riparte solo quando si va a cliccare su quel Button particolare.

Send to Kindle
.NET World

CodeProject : Designer realizzato con (e per) WPF

Il progetto su cui lavoro attivamente per la società per la quale lavoro, Brain-Sys (site under construction), comprende anche un designer realizzato con Windows Forms e WPF. Ci ho lavorato un pochino nelle ultime settimane, aggiungendo un po’ di funzionalità che ad un designer non dovrebbero mancare.

La cosa che mi è piaciuta di più è aggiungere la multiselezione degli oggetti. Immaginatevi l’editor di Windows Forms di Visual Studio: tenendo premuto CTRL e cliccando sui controlli, posso selezionarne più di uno contemporaneamente. Una volta che è attiva la multiselezione, posso spostare/ridimensionare in blocco i controlli, posso fare copia/incolla di oggetti multipli, etc. etc. Chiaramente, il designer su cui lavoro io non edita controlli nativi WPF, ma controlli che ereditano dalle classi di System.Windows.Controls, ma il ragionamento è lo stesso. Le pagine create con il mio designer vengono ovviamente salvate in Xaml, e così via. Non intendo scendere nel dettaglio, perchè non è lo scopo di questo post.

Quello che voglio dirvi è che per realizzare queste cose, ho preso spunto da questa serie di articoli su CodeProject, che voglio riportare anche a voi nel caso in cui doveste aver bisogno delle stesse cose:

WPF Diagram Designer – Part 1

WPF Diagram Designer – Part 2

WPF Diagram Designer – Part 3

WPF Diagram Designer – Part 4

Buona lettura!

Send to Kindle
.NET WorldFlight Simulation

Ottenere la nazione date latitude e longitudine (con Google Map)

Qualche giorno fa ho postato sui miei account Twitter e Facebook una piccola richiesta di aiuto, subito accolta da tutti i miei amici, che mi hanno suggerito la soluzione. La espongo qua, perchè può essere utile a qualcun’altro. E siccome sono blogorroico, vi descriverò lo scenario all’interno del quale l’ha utilizzata.

Anche in questo caso c’entra Flight Simulator.
Vediamo come e perchè.

Supponiamo il diagramma seguente. Scusatemi, ma non ho avuto il tempo di farlo in scala (cit.), e quello che vedete qui sotto non rappresenta in alcun modo una cartina vera. E’ solo un esempio, ma basta ed avanza.

Il pallino verde è un aeroplano che sta volando da qualche parte nel mondo.
La freccia blu è la direzione che sta seguendo.
I confini rossi sono appena gli ipotetici confini di tre nazioni: nazione A, B e C.

Il diagramma sopra mostra quindi l’aereo che sta volando nello spazio aereo della nazione C. Ma sta volando nella direzione indicata, quindi prima o poi oltrepasserà i confini della nazione C ed entrerà in B.

Esiste un servizio Web che mi permette, date latitudine e longitudine, di sapere in quale nazione mi trovo?

La risposta è ovviamente sì. Mi è stato ovviamente suggerito Google Map, e così ho fatto, ottenendo il risultato che volevo. Per la documentazione del caso, rivolgetevi a questo url.

La versione breve è questa. Richiamando (anche da un semplice browser) il seguente URL:

http://maps.google.com/maps/geo?q=45,9&output=kml&sensor=false&key=your_api_key

ottenete uno Stream di risposta in codice KML.

Il parametro q nella querystring sono latitudine/longitudine, separate da “,” (virgola). Latitudine 45, Longitudine 9 è un qualche punto della Lombardia, precisamente Voghera (PV). Il parametro output indica il formato di output che vogliamo in risposta: kml va più che bene. Il parametro sensor è messo a false. Il parametro key deve riportare l’api key che avete richiesto direttamente a Google.

KML non è nient’altro che XML che, opportunamente parserizzato, vi restituisce tutta una serie di informazioni, tra cui anche il country name.

Prima vediamo il codice della mia classe GoogleMapLookupCountry:

   1:      public class GoogleMapLookupContry : ILookupCountry
   2:      {
   3:          KmlParser parser = new KmlParser();
   4:   
   5:          public string GetCountry(double latitude, double longitude)
   6:          {
   7:              string apiKey = "your_api_key";
   8:   
   9:              string countryName = string.Empty;
  10:   
  11:              string outputFormat = "kml";
  12:              string stringLatitude = latitude.ToString().Replace(',', '.');
  13:              string stringLongitude = longitude.ToString().Replace(',', '.');
  14:              string url = string.Format("http://maps.google.com/maps/geo?q={0},{1}&output={2}&sensor=false&key={3}",
  15:                  stringLatitude, stringLongitude, outputFormat, apiKey);
  16:              HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
  17:   
  18:              string kml = ServiceHelper.GetStringResponse(request.GetResponse());
  19:   
  20:              return parser.GetCountryName(kml);
  21:          }
  22:      }

La prima cosa da fare è registrarvi su Google e richiedere un’API key, da incollare alla riga 7 del codice qui sopra.

Il metodo GetCountry ottiene in ingresso latitudine e longitudine (in formato double). Alla riga 14 costruisco l’url da richiamare via HttpWebRequest. Notare che l’output che vogliamo ottenere da Google Map deve essere in formato KML: il parametro {2} all’interno dell’url indica proprio il formato di output, che nel codice è cablato a “kml” (riga 11).

Alla riga 18 nascondo un po’ di complessità: passo la WebResponse (ottenuta da request.GetResponse()) al metodo statico GetStringResponse che prende il byte[] e mi ritorna la stringa in caratteri ASCII. Tutto ciò finisce nella variabile string kml (riga 18).

Alla riga 20 passo il codice KML al metodo GetCountryName che restituisce appunto il nome in chiaro della nazione in cui mi trovo. Ecco il codice della classe KmlParser:

   1:  public class KmlParser
   2:      {
   3:          XmlNamespaceManager nsmgr;
   4:   
   5:          public KmlParser()
   6:          {
   7:              nsmgr = new XmlNamespaceManager(new NameTable());
   8:              nsmgr.AddNamespace("google", "http://earth.google.com/kml/2.0");
   9:              nsmgr.AddNamespace("address", "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0");
  10:          }
  11:   
  12:          public string GetCountryName(string kmlCode)
  13:          {
  14:              string countryName = string.Empty;
  15:   
  16:              XmlDocument document = new XmlDocument();
  17:              document.LoadXml(kmlCode);
  18:   
  19:              XmlNode node = document.SelectSingleNode("//address:CountryName", nsmgr);
  20:   
  21:              if (node != null) countryName = node.InnerText;
  22:   
  23:              return countryName;
  24:          }
  25:      }

Non sto qui a descrivervi il codice riga per riga. Voglio solo fare questa annotazione: il codice KML restituito da Google dichiara il namespace specificato alla riga 8 del codice qui sopra (“http://earth.google.com/kml/2.0”). Prima di poter fare il SelectSingleNode (riga 19), dovete quindi istanziare un XmlNamespaceManager ed aggiungere i vari namespace che ci servono (nel nostro caso due). La ricerca tramite XPath, quindi, deve utilizzare “//” per selezionare il primo nodo che si chiama CountryName, indipendentemente da dove questo si trovi all’interno dell’KML, ma deve anche specificare il prefix per il namespace (“address”) e l’istanza di XmlNamespaceManager creata nel costruttore della classe.

Conclusione

Supponiamo di interrogare FSX ogni 60 secondi per chiedere la posizione dell’aereo. Otterremo la sua latitudine e la sua longitudine ogni 60 secondi. E’ sufficiente una piccola chiamata al servizio di Google Map ed otterremo la nazione in cui ci troviamo. Esempio pratico: decollate da Trieste ed otterremo ovviamente “Italia”. Dopo aver preso quota, virate verso est (direzione 90°) e quando entrerete in Slovenja, ecco che magicamente il servizio Google Map ci dirà – guarda caso – proprio “Slovenja”.

Detta così è una cosa banale e stupida, ma vi posso assicurare che si possono tirar fuori un certo numero di cose interessanti.

Send to Kindle
.NET World

Siete alla ricerca di un hosting?

Questa mattina presto stavo leggendo questo post su Dr.WPF: il tizio si lamenta perchè il provider DailyRazor (su cui si appoggia il blog) ogni tanto gli butta giù il sito a causa dell’elevato numero di richieste che arrivano ai suoi server. Quindi, se anche voi come me ricevete ogni tanto un errore 404 quando tentate di raggiungere una pagina su http://drwpf.com, adesso sapete il motivo.

All’interno nei commenti suggeriscono giustamente a Dr.WPF di spostarsi come host, e come in tutte le cose c’è chi consiglia questo o quello. Ho trovato invece il sito WebHostingStuff, che mette in classifica i diversi hosting in giro per il pianeta, mettendoli ordinatamente in ordine (ooppss) in base a costi, prestazioni, uptime, bandwidth e via dicendo.

Siccome so che anche mio fratello ha problemi con Aruba (e chi non ne ha?), magari questo link può essere utile anche a lui.

Send to Kindle
.NET World

NHibernate e applicazioni WPF

Faccio rimbalzare qui sul mio blog il post di Alberto Dallagiacoma tratto dal Muro di UGIdotNET. Effettivamente sono d’accordo con lui: le prime volte che cercavo documentazione o dritte su NHibernate, trovavo sempre pagine che spiegavano come usare l’ORM in ambito Web, e mai su Windows Forms o WPF. Mai capito il perchè.

Sul numero corrente di MSDN Magazine c’è un articolo di Ayende che illustra proprio questo scenario, utile a tutti coloro (come me in altri tempi e circostanze) che lavorano con WPF in combinazione con NHibernate. Da leggere, insomma.

Send to Kindle
.NET World

Attivare Windows Vista/Server 2008 con licenza Open License

Il mio server TFS, che gira in una macchina virtuale Windows Virtual PC, questa mattina mi ha chiesto l’attivazione via Internet. Fiducioso che tutto vada a buon fine, clicco sul pulsante Activate Now. Windows ragiona qualche secondo, e poi l’operazione fallisce. Purtroppo non ho screenshots da fornirvi.

Fortunatamente, c’è un bel More Information che dà qualche dettaglio in più: DNS doesn’t exists.

La prima cosa che penso è che non sia connesso ad Internet. Falso, perchè apro IE e raggiungo tranquillamente Google. Magari è giù il server Microsoft per l’attivazione delle licenze. Scarto questa possibilità.

Allora cerco sul Web questo messaggio di errore, ed effettivamente trovo questo articolo su TechNet che parla proprio di problemi relativi all’attivazione di Windows Vista o Server 2008 Enterprise/Standard, specialmente con licenze Open License. Lì è riportata la soluzione più rapida.

  1. Aprire il command prompt come amministratore
  2. Eseguire il comando:
    slmgr -ipk xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
  3. Le x indicano il punto dove scav….ehm…indicano il codice MAK da inserire. Cos’è il codice MAK? Non ne ho idea: so solo che mi sono loggato al portale Microsoft dedicato alle licenze Open License, sono andato nella sezione delle keys et voilà…ho copiato ed incollato il codice MAK relativo al mio sistema operativo. C’è una colonna apposta.
  4. L’esecuzione del comando slmgr dura qualche secondo: una MessageBox deve comunque apparire, sia in caso di errore, sia in caso di successo. Perciò aspettate fiduciosi e pazienti.
  5. Se l’esito è positivo, a questo punto potete attivare il sistema senza più problemi da Start –> Control Panel –> System. Cliccare sul link nella sezione Windows activation e siete a posto.

C’è sempre una soluzione a tutto! 🙂

Send to Kindle
.NET World

Usare Visual Studio 2008 e TFS come repository di documentazione

Il progetto su cui sto lavorando comprende una parte server, una parte client ed una parte admin (che comprende una serie di strumenti interni che nessuno distribuirà). Ciascuna di queste tre è quindi un progetto C#, che viene mantenuta sotto source control con TFS 2008.

Oltre a tutto questo, c’è una directory in più, docs, che – come dice il nome – contiene una serie di files PDF, immagini, piccoli documenti di testo, documenti Word ed Excel, e così via. Questa – fino a ieri – non era mantenuta sotto TFS. E quindi, mi son chiesto: è possibile farlo?

E’ possibile aggiungere una directory che non è un progetto .NET al source control di TFS 2008?
La risposta è ovviamente sì.

Ecco la procedura che ho seguito io: mi aspetto critiche e commenti, precisando che è stata inventata di sana pianta, per cui…

  1. Anche se non è una solution .NET nel vero senso del termine, dovete comunque utilizzare VS2008. Quindi, aprite VS2008 e create un nuovo progetto. Dalla finestra di dialogo New Project, selezionate il gruppo Other Project Types –> Visual Studio Solutions, selezionate Blank Solution e dategli un path ed un nome (es: X:docs).
  2. Fatto questo, VS2008, vi crea la cartella X:docs, all’interno della quale ci sono i files docs.sln e docs.suo.
  3. Ok, a questo punto potete aggiungere tutti i files che volete. Come? Se fosse un progetto .NET normalissimo, potreste drag’n’droppare i files: qui non potete. Perchè? Semplice: perchè solitamente dentro una solution c’è sempre un project, mentre qui no. E non potete nemmeno aggiungerlo, perchè non c’è un template Blank Project.

    L’unico modo che avete per aggiungere files alla solution appena creata è quella di cliccare – banalmente – col pulsante destro del mouse e fare Add –> Existing Item. VS2008 vi fa sfogliare directories e files per decidere quali di essi devono essere inclusi nella solution. Con un’altra piccola differenza rispetto ad un progetto .NET. Quando fate Add –> Existing Item in un progetto C# e selezionate un file esterno alla directory della solution, esso viene copiato in tale directory. Mi spiego meglio: se avete una console application in X:console ed aggiungete un file Main.cs preso dal desktop, esso viene copiato in X:console. Qui no. Se aggiungete files da un path esterno rispetto alla blank solution creata, i files rimangono lì dove sono. E quindi?

    Beh, è semplice. Dopo aver creato la blank solution, ho manualmente copiato tutti i files dentro la directory X:docs. A VS2008 non danno fastidio: l’importante è non pasticciare con i files docs.sln e docs.suo. Terminata la copia, fate Add –> Existing Item dalla stessa directory ed il gioco è fatto.

  4. Ma c’è un altro piccolo problema. Nel momento stesso in cui cliccate sul pulsante Add – non ho capito il perchè – ma o VS2008 o il sistema operativo apre tutti i files selezionati. Li aggiunge alla solution, che è quello che volevamo ottenere, ma allo stesso tempo li apre con l’applicazione predefinita. Quindi, se avete aggiunto alla solution 10 files pdf, vengono aperte 10 istanze di Adobe Reader, e così via. Se avete un buon processore e tanta RAM, tutto fila liscio. Dovete avere anche un po’ di pazienza, perchè dopo dovrete chiuderle tutte! 🙂
  5. A parte questo problema, dopo potrete aggiungere la solution al source control, esattamente come fareste con un normale progetto .NET.

A questo punto, tutto funziona regolarmente. Se aprite un file di testo e tentate di modificarlo, prima ne viene fatto il check-out. Se aprite il file senza modificarlo (un pdf, ad esempio), il server non entra neppure in gioco. Da notare che VS2008 apre il file con l’applicazione predefinita: i .xls vengono aperti con Excel, i .pdf con Adobe Reader, e così via. Altrimenti potete cliccare con il destro e fare Open With…

Direi che l’obiettivo è stato raggiunto: adesso qualsiasi modifica ad uno dei files di documentazione passa da un check-out e da un check-in. Ma soprattutto, versioning dei files e via dicendo. Cose che chi utilizza TFS conosce benissimo! 🙂

Send to Kindle
.NET World

Nuovo look di MSDN

Avevo letto già da qualche settimana che MSDN, il portale di Microsoft dedicato agli sviluppatori, avrebbe cambiato look, ma non avevo davvero capito che la cosa sarebbe accaduta nel giro di pochi giorni.

Adesso basta raggiungere la home-page per vedere un nuovo stile ed una nuova impaginazione grafica. E siccome quest’anno tutte le sfumature di viola sono andate di moda, ecco che lo stesso colore compare anche qui. Insomma, più fashion per tutti! 🙂

Send to Kindle
.NET World

Webhosting4life e i database SQL Server gratuiti

Da qualche anno ormai ho il mio bravo Advance Plan di Webhost4life che, nel costo annuale, mette a disposizione 2 istanze di database SQL Server. Almeno così risultava a me, nel senso che sono sicuro di non aver pagato nulla in più per aver messo on-line i miei 2 database: uno per Subtext (che chiameremo A), l’altro per scopi miei personali (che chiameremo B).

La settimana scorsa ho voluto mettere on-line un terzo database (C), ma la procedura del backend di Webhost4life giustamente mi bloccava: per averne un terzo avrei dovuto pagare 45 dollari all’anno. Stavo quindi pensando al piccolo investimento, però poi mi son detto: non mi conviene cancellare il database B (che comunque non usavo più), così da liberare uno slot e poter mettere on-line il terzo, senza spendere un euro in più?

E infatti così ho agito così: ho fatto il backup del database B, l’ho scaricato e l’ho installato sul mio SQL Server locale, giusto per averlo in caso di necessità. Poi tento di importare il database C, il terzo, in vari modi: creandolo da zero in primis, e poi attacchando direttamente il file .mdf. Ma in entrambi i casi Webhost4life continuava a bloccarmi: tutto ad un tratto il numero massimo di database SQL Server “gratuiti” pare sia sceso ad uno solo. Burp.

Mi stavo mettendo il cuore in santa pace, e la mano sul portafoglio: 45 dollari all’anno è una cifra più che accettabile, e quindi non era un grosso problema. Ma giusto per togliermi lo sfizio ho provato a contattare l’help desk di Webhost4life cercando lumi. Insomma…per circa una decina di minuti ho chiaccherato amabilmente con una certa Nancy, che mi informa del fatto che con l’Advance Plan come il mio è a disposizione solo un database SQL Server. Secondo me, è cambiata la politica causa crisi, ma può essere che mi sbagli.

Nancy mi dice però un’altra cosa, che mi lascia di stucco e mi fa comparire sul mio faccione un bel sorriso: può aumentare il numero dei database SQL Server a 5, gratuitamente. Ed infatti lo fa. Sono contento, perchè finalmente il terzo database può andare on-line, senza alcuna spesa aggiuntiva: e siccome si tratta di un freeware, il regalo è ben accetto. Grazie Nancy!

Webhost4life: questo sì che è un servizio!

Send to Kindle
.NET World

XAML Power Toys 5.0

L’altro giorno, mentre lavoravo bello tranquillo da casa, ho notato un aggiornamento dai miei following di Twitter. Mi arrivano in automatico grazie a Twhirl, un desktop client per Twitter. Beh, insomma, per farla breve, il nostro amico MVP Corrado Cavalli ci informa che sono usciti i XAML Power Toys 5.0.

Di cosa si tratta? Si tratta di un add-on per Visual Studio 2008 SP1 che aggiunge moltissime funzionalità a chi lavora con XAML, Windows Presentation Foundation e Sliverlight. Questo add-on si “incastra” nelle finestre di editing di XAML e C#, aggiungendo diverse voci davvero indispensabili. Ad esempio:

  • creare un nuovo StackPanel, Canvas, DockPanel, Border, Grid inserendo al loro interno elementi di UI già presenti e definiti nello XAML (in pratica, la funzione Group Into già presente – mi pare – in Expression Blend)
  • creare ListView, Grid e nuove Window partendo da classi di object-model già definite
  • il comportamento del punto precedente è customizzabile: tramite Reflection, il tool mostra le proprietà pubbliche delle vostre entità di dominio, e potete decidere come essere devono apparire (tramite TextBox, ComboBox, etc. etc.) e quali stringhe di formattazione applicare (bellissimo!)
  • pulizia dello XAML (geniale!!!), rimuovendo le proprietà Margin & Padding!! Bellissimo…

Ovviamente, trovate maggiori informazioni presso il sito dell’autore, dal quale potrete anche scaricare l’installer ed i sorgenti. Mentre siete sulla pagina, date un’occhiata ai links sulla destra: è pieno di esempio di tutti i tipi sul mondo WPF. Alcuni sono davvero imperdibili!

Grazie a Corrado per la segnalazione.

Send to Kindle