Welcome

Visual Basic Tips & Tricks Bloggers

Visual Basic Site
Visual Basic Forum

Blog Stats

  • Blogs - 39
  • Posts - 3501
  • Articles - 184
  • Comments - 26974
  • Trackbacks - 3194

Bloggers (posts, last update)

Powered By:
Powered by Subtext

Latest Posts

Windows Phone: cambiare skin all'emulatore

Stanchi della skin di default dell'emulatore di Windows Phone? Niente di più semplice: cambiatela!

C'è un bellissimo progetto su CodePlex chiamato Windows Phone 7 Emulator Skin Switcher che vi permette di scegliere tra ben 25 skin diverse che riproducono l'estetica dei dispositivi più diffusi.

Io, ovviamente, ho ora la skin del Nokia Lumia

Alessandro

posted @ 26/01/2012 22.42 by Alessandro Del Sole

Windows Phone: effetto turn-style nella navigazione tra pagine

Vi segnalo questo bellissimo post dell'amico Cristian Civera il quale ci spiega come applicare l'effetto di transizione che vediamo normalmente nella navigazione tra pagine in Windows Phone anche all'interno delle nostre app.

Cristian, secondo me, ha sempre avuto la grande dote di spiegare in modo semplice anche gli argomenti più complessi e questo post non è da meno.

Alessandro

posted @ 26/01/2012 22.33 by Alessandro Del Sole

Address Book Sample per LightSwitch

Beth Massi ha pubblicato l'esempio completo, chiamato Address Book, a corredo della serie di post intitolata "Beginning Visual Studio LightSwitch", che potete trovare in questo suo post.

Nel citato post è anche disponibile l'elenco completo della serie di articoli che vi permetteranno di comprendere ancora meglio questo speciale ambiente di sviluppo.

Alessandro

posted @ 26/01/2012 22.26 by Alessandro Del Sole

SQL: Backup automatici con Nant

Chi utilizza la versione Express di SQL Server sa bene che una delle differenze rispetto alle versioni “Full” è l’assenza del SQL Server Agent, un processo fondamentale per schedulare le diverse attività sul server. Una di queste è il backup di uno o più database che non dovrebbe mai mancare su un server!

Naturalmente esistono dei tools sia a pagamento che gratuiti per colmare questa lacuna ma si può ovviare al problema anche utilizzando strumenti non direttamente ricollegabili al mondo SQL.
Uno di questi è NAnt, un Build Tool ossia un framework per la creazione di script di build (in questo caso per .NET).
Senza entrare troppo nel dettaglio, si tratta di creare uno script che esegue una serie di task (chiamati Target) in maniera più o meno strutturata.
Nel nostro caso vogliamo creare uno script di backup di un database compattato in un archivio ZIP.

Installazione di Nant
Per prima cosa scarichiamo NAnt dal Download NAnt. Non esiste un setup automatico ma bisogna semplicemente scompattare il contenuto del file .ZIP in una cartella qualunque.

Creazione dello script
NAnt è basato su file script chiamati Build File che non sono altro che file xml con estensione .build. Ecco il nostro file db.backup.build:

 

<?xml version="1.0"?>
<project default="backup">
    <property name="backup.path" value="E:\Backup" />
    <property name="backup.name" value="" />
    <property name="backup-date" 
                    value="${datetime::get-year(current-date)}${string::pad-left(datetime::get-month(current-date),2,'0')}${string::pad-left(datetime::get-day(current-date),2,'0')}" />
    <property name="filename" value="${backup.name}_${backup-date}" />
	
    <target name="backup">
	<echo message="Running backup... ${datetime::now()}" failonerror="False" />
	<exec program="sqlcmd" 
                          commandline="-S .\sqlexpress -i &quot;E:\backup\sql\database.backup.sql&quot;  
                          -v dbname=${backup.name} filename=${filename} path=&quot;${backup.path}&quot;
                          -o &quot;${backup.path}\${filename}.log&quot;" />
	<call target="zip" />
    </target>
	
     <target name="zip">
	<property name="backup.file" value="${backup.path}\${filename}.bak" />
	<if test="${file::exists(backup.file)}">
		<echo message="Compressing..." failonerror="False" />
		<zip zipfile="${backup.path}\${filename}.zip">
			<fileset basedir="${backup.path}">
    			    <include name="${filename}.bak" />
			</fileset>
		</zip>
		<delete file="${backup.path}\${filename}.bak" />
	</if>
    </target>
</project>

 

Lo script definisce, all’inizio, delle varibili identificate dall’elemento <property> utilizzate nei vari task con la sintassi ${nome_variabile}. Da notare la variabile filename che identifica il nome del file finale composto dal nome del database e la data corrente calcolata dalla variabile backup-date nel formato yyyymmdd.

I task sono due. Il primo, “backup”, esegue il backup del database utilizzando l’utility sqlcmd per eseguire il file script database.backup.sql:

declare @filename nvarchar(500)
set @filename='$(path)\$(filename).bak' 

declare @dbname varchar(255)
set @dbname = '$(dbname)'

BACKUP DATABASE @dbname
	TO  DISK = @filename
WITH 
	NOFORMAT, 
	NOINIT,  
	NAME = @dbname,
	SKIP, 
	STATS = 10;
GO

 

Si tratta di un semplice comando BACKUP che sfrutta le variabili identificate da $(nome_variabile) che sono valorizzate sternamente utilizzando l’opzione –v variabile=valore del comando sqlcmd.

Il secondo task, “zip”, è lo zip del backup utilizzando un task predefinito di NAnt chiamato <zip> nel quale si specificano i file da includere nell’archivio mediante l’uso dell’elemtno <fileset>…</fileset>.
L’ultima operazione è eliminare il backup con la funzione <delete />.

Ora non ci resta che provare lo script eseguendo questo comando utilizzando la shell di Windows (cmd):

 

c:\> nant.exe -buildfile:E:\Backup\db.backup.build -D:backup.name=Northwind

 

I parametri specificati sono due:

1) buildfile: il path del nostro script (in questo esempio in E:\backup);

2) D: valorizza le <property> definite dello script. Nell’esempio specifichiamo il nome del database valorizzando la property backup.name.

 

Se tutto ha funzionato bene avremo il nostro backup zippato. A questo punto possiamo schedulare il tutto con il Task Scheduler di Windows Smile

posted @ 23/01/2012 22.44 by Antonio "tdj" Catucci

Interessanti opportunit&agrave; al .Net Campus 2012

Dall'organizzazione veniamo informati sulle novità relative all'evento, e io ve le comunico volentieri:

  • da oggi si è aperto il contest "progetti e idee": puoi pubblicare la tua idea di applicazione sul sito e farla valutare agli sponsor.
    Le 5 migliori proposte potranno essere presentate al .NET Campus Roma e la migliore proposta value uno stage retribuito in Avanade !
  • abbiamo pubblicato i primi annunci di lavoro degli sponsor sul sito:
    puoi segnalare la tua candidatura direttamente dal sito.
  • sul sito puoi inoltre pubblicare il tuo profilo tecnico per farti
    conoscere ed essere contattato dagli sponsor dell'evento.

Quindi, iscrivetevi :D:D:D

posted @ 20/01/2012 11.04 by Diego Cattaruzza

Windows Phone: salvare una foto dal Web all'hub sul device (Visual Basic)

La piattaforma di sviluppo per Windows Phone mette a disposizione una serie di API per l'interazione con il Pictures Hub, che è poi il posto in cui vengono memorizzate le foto.

Una richiesta molto frequente è quella di poter salvare nel device foto da Internet, dato il loro indirizzo Web. Posto che ci siamo accertati di avere il permesso di poterlo fare , ricorriamo a una serie di strumenti. Innanzitutto usiamo la classe WebClient per eseguire il download asincrono della foto. Quindi spostiamo il suo contenuto fatto di byte in un file all'interno dell'isolated storage, per poi eseguire il salvataggio vero e proprio.

Per interagire in modo rapido con l'hub delle foto è conveniente utilizzare la classe MediaLibrary (che non fa solo questo), messa a disposizione dall'assembly Microsoft.Xna.Framework. Tale assembly, al quale dobbiamo necessariamente aggiungere un riferimento nel nostro progetto, è specifico per i giochi sviluppati con XNA ma si integra perfettamente con le app.

Il codice che ci permette di eseguire questa operazione non è affatto complicato, richiede solo un po' di dimestichezza con gli stream. Eccolo, con i commenti che facilitano la lettura:

'The following Imports directives are required
'Imports System.Windows.Resources
'Imports System.IO
'Imports Microsoft.Xna.Framework.Media
'Imports System.IO.IsolatedStorage
 
Private Sub SavePictureToHub(webAddress As Uri, pictureName As String)
    Dim client As New WebClient()
    AddHandler client.OpenReadCompleted, Sub(sender As Object, e As OpenReadCompletedEventArgs)
                                             'Get the result of the download operation as a stream
                                             Dim resInfo As New StreamResourceInfo(e.Result, Nothing)
                                             Dim reader As New StreamReader(resInfo.Stream)
 
                                             'Get a reference to the isolated storage
                                             Dim store = IsolatedStorageFile.GetUserStoreForApplication
 
                                             'Read the downloaded stream
                                             Dim contents As Byte()
                                             Using bReader As New BinaryReader(reader.BaseStream)
                                                 contents = bReader.ReadBytes(CInt(reader.BaseStream.Length))
                                             End Using
 
                                             'Move the downloaded stream to a temp file into the isolated storage
                                             Using fStream As IsolatedStorage.IsolatedStorageFileStream = store.CreateFile(pictureName)
                                                 fStream.Write(contents, 0, contents.Length)
                                             End Using
 
                                             'Save the picture to the Pictures hub (Saved pictures)
                                             Using rStream As New IsolatedStorageFileStream(pictureName, FileMode.Open, store)
                                                 Dim ml As New MediaLibrary
                                                 ml.SavePicture(pictureName, rStream)
                                             End Using
 
                                             reader.Close()
 
                                             'Remove the temp file from the isolated storage
                                             store.DeleteFile(pictureName)
                                         End Sub
 
    client.OpenReadAsync(webAddress)
End Sub

Per una comodità personale uso le statement lambda dove posso, chiaramente si poteva incapsulare il codice della sub 'nidificata' in un delegate separato. L'unica cosa di cui tener conto (oltre, come detto, ad avere il permesso di scaricare la foto) è che le immagini verranno salvate nell'album chiamato Foto Salvate.

Alessandro

posted @ 19/01/2012 19.24 by Alessandro Del Sole

Windows Phone: proteggere dati sensibili (Visual Basic)

La tutela della privacy è importante in tanti contesti, ma forse in un dispositivo mobile lo è ancora di più. Non a caso, per l'invio di applicazioni al Marketplace di Windows Phone 7 per la certificazione, è necessario rispettare tutta una serie di policy.

Nello sviluppo per Windows Phone valgono ancora molti concetti relativi al namespace System.Security.Cryptography del .NET Framework, e proprio una tecnica già esistente ci permette di utilizzare un metodo semplificato per la protezione di informazioni, per così dire, meno delicate.

Esiste infatti la classe ProtectedData che espone due metodi condivisi, Protect e Unprotect. Il primo riceve una stringa e la restituisce sotto forma di array di byte sotto encryption. Il secondo, ovviamente, vuole l'array di byte e restituisce la stringa originaria.

Ciò premesso, vediamo come definire una classe che faccia uso di questa tecnica:

Imports System.Security.Cryptography
Imports System.Text
 
Public Class CryptoService
 
    Public Shared Function EncryptString(data As StringAs Byte()
        Dim PinByte = Encoding.UTF8.GetBytes(data)
 
        Dim ProtectedPinByte = ProtectedData.Protect(PinByte, Nothing)
        Return ProtectedPinByte
    End Function
 
    Public Shared Function DecryptData(data As Byte()) As String
        Dim unprotected = ProtectedData.Unprotect(data, Nothing)
        Return Encoding.UTF8.GetString(unprotected, 0, unprotected.Length)
    End Function
 
End Class

Il primo metodo, chiamato EncryptString, converte dapprima la stringa in array di byte e poi la protegge con il metodo ProtectedData.Protect. Viceversa, il secondo metodo, chiamato DecryptData, ottiene l'array di byte non protetto e ne restituisce la stringa corrispondente. L'utilizzo di questa tecnica va poi abbinato all'uso degli stream e dell'isolated storage del dispositivo. Il seguente codice dimostra come leggere informazioni protette e come elaborarle:

            Dim store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication
            Using protStream As New IsolatedStorageFileStream("miofile.bin", IO.FileMode.Open, store)
                Dim pinArray As Byte() = New Byte(CInt(protStream.Length - 1)) {}
                protStream.Read(pinArray, 0, pinArray.Length)
                info = CryptoService.DecryptData(pinArray)
            End Using

Dove info è una variabile di tipo stringa dichiarata altrove. Il seguente codice, invece, scrive in un file il contenuto di una stringa proteggendolo:

            Using protStream As New IsolatedStorageFileStream("miofile.bin", IO.FileMode.Create, store)
                Dim dati = "info delicatissime"
                Dim datiProtetti = CryptoService.EncryptString(dati)
                protStream.Write(datiProtetti, 0, datiProtetti.Length)
            End Using

A seconda del tipo di informazioni da proteggere può essere conveniente utilizzare altre tecniche, questa comunque è molto semplice e certamente efficace all'interno delle nostre app. Un'occhiata a MSDN per concludere.

Alessandro

posted @ 19/01/2012 19.00 by Alessandro Del Sole

Porte Seriali e VB.NET

Sul forum ho letto (e anche risposto) a parecchie domande che riguardano l’uso e/o la gestione di porte seriali in ambiente .NET.

Lungi dall’essere esaustivo come post, e quasi sicuramente pieno di bestialità, mi permetto di illustrare alcuni metodi che ho implementato nei miei programmi, grazie ai quali ho ottenuto comunque buoni risultati.

A partire dalla versione 2 del .NET framework, è disponibile una classe SerialPort che permette di gestire in maniera abbastanza completa le porte seriali.

Questa classe contiene le funzioni di lettura e scrittura, oltre che di gestione della porta stessa (che ometto di descrivere) e di tre eventi dei quali invece vorrei dire qualcosa:

  • DataReceived

Viene lanciato quando un carattere è presente nel buffer di ricezione.  Nel suo handler espone un oggetto della classe System.IO.Ports.SerialDataReceivedEventArgs, che ci indica se è stato ricevuto un carattere valido oppure il carattere di EOF (end of file)

  • ErrorReceived

Viene lanciato in caso di errore di trasmissione. Nel suo handler espone un oggetto della classe System.IO.Ports.SerialErrorReceivedEventArgs, che ci indica quale errore si è verificato (buffer overflow in trasmissione o ricezione, errore di parità etc.)

  • PinChanged

Viene lanciato in caso di cambiamento sui pin “fisici” della seriale, quali DSR, CD, RI o CTS oppure break. L’oggetto della classe System.IO.Ports.SerialPinChangedEventArgs esposto nel suo handler permette di capire quale evento si è verificato.

Raccomando di perdere qualche minuto e di leggere l’help in linea, si potrebbero trovare informazioni interessanti.

Alcune pessime pratiche comuni

Arrivati a questo punto vorrei parlare di alcuni errori, o meglio, alcune pratiche non ottimali spiegando il perché queste pratiche non mi piacciono e le considero errori.

Il modo più comune con il quale un programma comunica con un qualsiasi periferico via seriale è il cosiddetto “Get Param/Set Param” in cui la comunicazione è “pilotata” dal PC ed il periferico risponde a tono.

Il codice che normalmente viene utilizzato è qualcosa che assomiglia a questo:

SerialPort1.WriteLine("Data Request")
Dim Risultato As String = SerialPort1.ReadLine()

Questo banale codice in realtà è, a mio modo di vedere, un vero orrore.

Per quale motivo?

I motivi sono più di uno.

Il primo è che essendo la periferica attaccata ad un filo, può essere che la periferica non risponda in tempo utile (o non risponda affatto) ed il sistema vada in eccezione di timeout.

Una pezza peggiore del male sarebbe di gestire il timeout con un bel Try/Catch, visto che le eccezioni dovrebbero evitare di verificarsi tranne in casi eccezionali, e qui è ben lungi dall’esserlo.

Quando può succedere una cosa del genere?

Se la comunicazione è via “seriale vera”, può succedere, ad esempio, che la comunicazione sia disturbata dai macchinari elettrici nei dintorni (una seriale a 9600 baud può trasmettere qualche centinaio di metri), o peggio, topi o altri animali possono rosicchiare il cavo (ebbene si, mi è già successo!)

Se la comunicazione è via “Seriale virtuale da USB”, invece la situazione può essere ben peggiore a seconda che lo stack di comunicazione sia o meno fatto decentemente. Ad esempio, lo stack USB che viene rilasciato da NXP e CodeRed per l’uso sui micro ARM delle serie LPC1X (Cortex M3) ed LPC2X (ARM7TDMI), derivato dal (peraltro ottimo) lavoro di Bertrid Sikken, LPCUSB, ha due pesanti BUG sulla gestione dei NACK, che fanno si che la comunicazione si pianti spesso e volentieri e, comunque, sia esageratamente lenta, soprattutto quando si spostano notevoli moli di dati su e giù per una virtual com.

A parte la (doverosa) correzione dei BUG (9 righe), l’avere un sistema di comunicazione Bullet-proof è comunque indispensabile per evitare le bruttissime schermate di eccezione (ancora peggio quando questa è UnHandled).

Il secondo non è un vero e proprio problema, nel senso che il programma non si pianta, quanto un funzionamento “brutto” da vedere, e che comunque non gestisce il caso in cui si voglia interrompere un’operazione la cui esecuzione può durare anche qualche minuto ed è il fatto che la gestione della seriale in una form viene generalmente effettuata sul thread principale.

Un altra cosa che personalmente non mi piace è la gestione della ricezione fatta sfruttando l’evento DataReceived.

Molti puristi storceranno il naso, ma questa gestione corre il rischio di provocare degli errori imprevisti.

Contrariamente a quanto pensa la maggioranza dei programmatori, questo evento scatta solo “QUASI” ad ogni byte ricevuto, come ci ricorda l’help del .NET Framework, che riporto qui ad imperitura memoria

“The DataReceived event is not guaranteed to be raised for every byte received.“

Insomma, a seconda della velocità della seriale e del numero di byte da leggere può cambiare il comportamento della funzione ed il numero di volte che l’evento scatta.

 

Miglioriamo il nostro codice

Non è che pretenda di scrivere il miglior codice del mondo, ma codice funzionante si.

Dato che normalmente le operazioni da fare sono inviare dati al dispositivo seriale e leggerne il risultato, perché non costruire una funzione ad hoc per farlo?

Ecco che quindi ho scritto una funzione idonea, che ho chiamato ScriviELeggi (che fantasia!), che è fatta all’incirca così

Private Function ScriviELeggi(PortaSeriale As IO.Ports.SerialPort, Messaggio As String, TimeOutMilliseconds As Integer, ByRef Risultato As String) As Boolean
        Dim TimeOutCounter As Integer = 0
        Dim SB As New StringBuilder 
        Dim c As String = ""
        PortaSeriale.DiscardInBuffer()
        PortaSeriale.DiscardOutBuffer()
        Thread.Sleep(10)
        Try
            PortaSeriale.Write(Messaggio)
        Catch ex As Exception
            Return False
        End Try

        Thread.Sleep(10)
        While True
            While PortaSeriale.BytesToRead > 0
                c = Chr(PortaSeriale.ReadChar)
                If CondizioneFineLettura() Then
                    Risultato = SB.ToString
                    Return True
                Else
                    SB.Append(c)
                End If
            End While
            Thread.Sleep(10)
            TimeOutCounter = TimeOutCounter + 10
            If TimeOutCounter > TimeOutMilliseconds Then
                Return False
            End If
        End While
        Return True
    End Function

Dove CondizioneFineLettura è, come dice il nome stesso, la condizione  che indica che la lettura è stata terminata correttamente.

Può essere un carattere ben specifico, un frame fatto in un determinato modo, un numero di caratteri… dipende dall’applicazione specifica.

Qualora invece di una stringa si debba leggere un array di caratteri si può banalmente correggere la funzione in maniera opportuna.

Detto questo si noti che la funzione gestisce anche correttamente il timeout ed è non bloccante a parte il tempo in cui essa va in condizione di timeout ed è pertanto pienamente idonea alle applicazioni “Get Param/Set Param”, anche quando esse muovono mega di dati.

I più attenti mi possono far notare che la funzione di fatto congela il thread per il tempo della lettura o al più per il tempo necessario ad andare in timeout.

Questo è vero, ma questa funzione può tranquillamente lavorare in multithread.

Ad esempio, usando un BackgroundWorker, la funzione può lavorare correttamente, senza bloccare l’interfaccia principale.

Piccolo esempio (fatto maluccio ma funziona)

Private Sub bwComunicazione_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bwLetturaOvo.DoWork
    Dim Seriale As New System.IO.Ports.SerialPort
    Dim RisultatoLettura As String = ""
    Dim ErroriLettura As Integer = 0
    Dim Finito As Boolean = False
    Dim RisultatoOk As Boolean = True
    Dim Progresso As Integer
    Dim bw As ComponentModel.BackgroundWorker = CType(sender, ComponentModel.BackgroundWorker)
    Seriale.PortName = "COM5"
    Seriale.BaudRate = 38400
    Seriale.ReadBufferSize = 2000
    Dim IniziateTimbrature As Boolean = False
    Try
        Seriale.Open()
        While (Finito <> True)
            If bw.CancellationPending Then
                Seriale.Close()
                Exit Sub
            End If
            If ScriviELeggi(Seriale, ComandoIEsimo, 1000, RisultatoLettura) = True Then
                ParseRisposta(RisultatoLettura)  
                bw.ReportProgress(Progresso)
            Else
                ErroriLettura = ErroriLettura + 1
            End If
            If ErroriLettura > NumeroMassimoErrori Then
                Finito = True
            End If
        End While
    Catch ex As Exception
        MsgBox(ex.Message)
        If Not Seriale Is Nothing Then
            If Seriale.IsOpen Then
                Try
                    Seriale.Close()
                Catch ex1 As Exception
                    Return
                End Try
            End If
            Return
        End If
    End Try
    If Seriale.IsOpen Then
        Seriale.Close()
    End If
End Sub

Questa “semplice” funzione gestisce semplicemente l’evento DoWord di un BackgroundWorker, il quale può essere attivato alla pressione di un pulsante mediante il metodo RunWorkerAsync.

Si può vedere come la stessa funzione gestisca anche l’interruzione del lavoro andando a testare se c’è una richiesta di interruzione, ed anche inviando al thread principale il feedback dell’ avanzamento dell’esecuzione mediante il metodo ReportProgress

Piccola nota sulla parte di gestione delle eccezioni, che è fatta un po’ con i piedi.

Questo intortamento è nato quando ho cercato di gestire la rimozione di una porta seriale virtuale mentre c’era una lettura in corso. Al momento non ho trovato niente di meglio, ma, tempo permettendo, prometto di metterci mano e rendere la funzione degna.

Rimangono ancora da gestire le comunicazioni completamente asincrone, ovvero, nelle quali i dati arrivano in maniera completamente asincrona, che, data la casistica veramente molto ampia, mi rimane difficile da implementare in una qualche maniera completa, ed inoltre, in tanti anni di programmazione, ho dovuto implementare una volta sola.

Per un discorso veramente completo (e per codice molto diverso dal mio) rimando alla lettura del libro di Jan Axelson “Serial Port Complete”, seconda edizione.

Sperando che il mio sproloquio sia utile a qualcuno, vi rimando alla prossima.

posted @ 18/01/2012 16.00 by Davide Bertolino

Interfacciarsi con i file dbf

Ogni tanto, nel lavoro di programmatore, tocca interfacciarsi con procedure scritte da altri, e spesso si tratta di lavorare con i database.

Se si ha la fortuna che "il vecchio" sia un access, può capitare di dover perdere quei 3 decimi di secondo per dover trovare la password, e poi le librerie standard di .NET fanno il resto.

Quando invece "il vecchio" è un file dbf, allora c'è qualche problemino in più, anche perchè ho trovato poche procedure documentate e che funzionano, per cui, all'epoca, ho remato parecchio.

Ieri il mio amico Stefano mi ha fatto la domanda: Come posso aprire un file .dbf da .NET?

Sono andato a scartabellare nella chiavetta e gli ho passato il materiale (rigorosamente free) che mi ero trovato quando anche io ero nella stessa situazione.

Come data provider ho usato la libreria che può essere scaricata da CodePlex Fast DBF (http://fastdbf.codeplex.com/).

Non è eccezionale, non copre tutti i casi, ma è veloce e gratuita. Le operazioni sul record sono posizionali, nel senso che si fa riferimento al campo I-esimo del record.

Per vedere la struttura delle tabelle e vederne i dati in forma leggibile consiglio di scaricarsi il DBF Viewer Plus da http://www.alexnolan.net/. Ce ne sono altri, forse anche migliori, ma questo è free e non va installato (ad esempio io lo uso da chiavetta).

Vedo abbastanza inutile aggiungere del codice di esempio sull'uso della libreria (basta aprirla e seguire gli esempi), tuttavia sono pronto a fornirlo a richiesta.

Alla prossima.

posted @ 18/01/2012 9.54 by Davide Bertolino

Entity Framework: eccezione "New transaction is not allowed because there are other threads running in the session"

Spesso capita l'esigenza di eseguire un ciclo For..Each su entity set lavorando con ADO.NET Entity Framework. Qualcosa tipo:

For Each animal In MyModel.Animals

     'Do something here...

Next

Nell'esempio di cui sopra l'entity set Animals è di tipo ObjectSet(Of T), dove chiaramente T è un tipo fittizio Animal. Nel ciclare direttamente un oggetto di tipo ObjectSet(Of T) l'EF potrebbe restituire la seguente eccezione:

"New transaction is not allowed because there are other threads running in the session". Per risolvere  il problema è necessario evitare di ciclare direttamente contro l'ObjectSet, il che vuol dire poter usare anche un metodo extension come AsQueryable o ToList:

For Each animal In MyModel.Animals.AsQueryable()

Next

In questo modo sarà possibile eseguire correttamente il ciclo evitando l'errore, ovviamente potrebbe essere preferibile scrivere una query LINQ piuttosto che usare direttamente gli extension, a seconda del contesto.

Alessandro

posted @ 17/01/2012 14.58 by Alessandro Del Sole

Evento a Genova il 27 gennaio 2012 con DotNetLiguria

Venerdì 27 gennaio p.v. sarò a Genova con gli amici di DotNetLiguria, giovane user group con focus sulle tecnologie .NET che si propone di aggregare utenti e appassionati liguri.

Raf e i suoi ragazzi hanno infatti organizzato il 1° workshop del 2012 e in questo ambito presenterò, alle ore 18, una sessione su Visual Studio LightSwitch, sarà una sessione di livello introduttivo ma tarata per sviluppatori non troppo principianti

Ci sarà anche una interessante round-table sul futuro di Silverlight e una sessione sui code contracts. Se siete in zona ligure e non avete impegni venite a trovarci, potete trovare i dettagli sull'evento nell'home page di DotNetLiguria mentre potete registrarvi seguendo questo link.

Vi aspettiamo!

Alessandro

posted @ 17/01/2012 9.27 by Alessandro Del Sole

Bing Maps for WPF

 

Il 12 Gennaio 2012 è stato rilasciata la prima versione del Controllo Bing Maps per WPF fino ad oggi abbiamo utilizzato la Beta ma adesso è finalmente disponibile la versione ufficiale scaricabile da qui.

HTH

Francesco Valentino

posted @ 16/01/2012 12.46 by Francesco Valentino

Kinect for Windows in arrivo il 1 febbraio 2012

Grandi novità per quando riguarda Kinect!

Al CES 2012 di Las Vegas è stato annunciato il rilascio per Mercoledì 1 febbraio 2012 di Kinect for Windows.

La più importante novità di questo nuovo prodotto è il supporto della modalità ‘Near Mode’ che permetterà di interagire con Kinect a soli 50cm di distanza.

Grazie a questa novità si aprono interessanti scenari per applicazioni da utilizzare seduti tranquillamente alla propria scrivania da gestire contact-less.

In contemporanea all’uscita del prodotto sarà rilasciata anche la versione definitiva dell’SDK per la realizzazione di soluzioni (.NET) basate su questo dispositivo HardWare.

Per seguire le novità relative a Kinect for Windows vi segnalo il Blog Kinect for Windows.

 

Se volete approfondire dal vivo lo sviluppo per questo device vi aspetto alle mie prossime sessioni dedicate a questo prodotto :

Programmare KINECT for WINDOWS–Evento Live Martedì 24/01/2012

Evento gratuito Community Days 2012, 16 e 17 Febbraio–Milano–ULTIMI POSTI DISPONIBILI !!!

Renato Marzaro

posted @ 13/01/2012 15.03 by Renato Marzaro

Windows 8&ndash;White Paper sullo sviluppo futuro

In prossimità dell’annunciato rilascio della beta di Windows 8 vi segnalo questo interessante White Paper

White Paper: Assessing the Windows 8 Development Platform

Che traccia le linee per lo sviluppo che ci attende sul nuovo sistema operativo di casa Microsoft.

Come sicuramente già avrete letto in Windows 8 la tradizionale interfaccia utente

verrà affiancata dalla più moderna interfaccia Metro

 

sicuramente una opportunità da non perdere per aggiornare i ns applicativi ed essere da subito presenti sul mercato con soluzioni che supportino la nuova interfaccia utente Metro.

Il passaggio non sarà sicuramente indolore ma preparandosi per tempo si potrà sfruttare anche questa occasione.

 

Nel documento che vi ho segnalato troverete interessanti indicazioni su cosa e come utilizzare per affacciarsi a questo nuovo sistema operativo.

 

 

Come potete vedere il ns caro VB.NET è sempre presente! Open-mouthed smile

Vi lascio con questa immagine che riassume cosa e come sarà supportato in Windows 8

 

Renato Marzaro

posted @ 13/01/2012 14.47 by Renato Marzaro

Evento gratuito Community Days 2012, 16 e 17 Febbraio&ndash;Milano&ndash;ULTIMI POSTI DISPONIBILI !!!

Visual Basic Tips & Tricks presenta, in collaborazione con le altre community ed user group italiani, il maggior evento community dell'anno: 12 track spalmate su 2 giorni interamente dedicati alle ultime tecnologie, 4 lab ed i migliori speaker italiani.

Windows 8, Windows Phone, Entity Framework, ASP.NET, .NET Framework 4.5 e Visual Studio 11, applicazioni mobili, HTML 5 e tanto, tanto altro ancora!

La partecipazione, come sempre, è totalmente gratuita. Le iscrizioni sono aperte e l'agenda è disponibile sul sito.

Io sarò presente con una sessione dal titolo "Natural User Interface con Kinect SDK", all'interno della quale discuteremo delle, tante :-),  novità di Kinect for Windows presentate al CES 2012 disponibili dal 1 febbraio 2012 e quindi già visibili all’evento!.

Per la nstra community ci sarà anche Alessandro Del Sole con una interessante sessione sulle novità di WPF 4.5.

 

Iscriviti subito cliccando sull'immagine:

Ci vediamo lì! E se siete su Twitter, non dimenticate l'hashtag ufficiale dell'evento: #cdays12

 

Renato Marzaro

posted @ 13/01/2012 14.29 by Renato Marzaro

Programmare KINECT for WINDOWS&ndash;Evento Live Marted&igrave; 24/01/2012

Martedì 24 gennaio 2012 avrò il piacere di essere speaker all’evento organizzato da INTEL e DotNetLombardia

Presenterò una sessione dedicata a KINECT for WINDOWS di cui è stata appena annunciato il lancio per il 1 febbraio 2012.

Vi attendo numerosi per presentarvi tutte le ultime novità annunciate su questo interessante prodotto che segnerà sicuramente il nostro futuro di programmatori ed utenti.

Per iscrizioni seguite questo link

Renato Marzaro

posted @ 13/01/2012 13.51 by Renato Marzaro

Windows Phone: elencare e riprodurre video da YouTube (con Visual Basic)

In un'app che sto sviluppando per Windows Phone 7.5 avevo la necessità di integrare un elenco di video proveniente da uno specifico canale di YouTube, visualizzando tale elenco in una ListBox e permettendo la riproduzione del video selezionato dall'utente.

Non avendolo mai fatto e cercando un po', mi sono imbattuto in questo interessante articolo su Visual Studio Magazine che mi ha messo sulla strada giusta e che, ovviamente, ho riadattato alle mie esigenze (non ultimo il passaggio del codice a Visual Basic ).

La prima cosa da fare è determinare l'indirizzo Web del feed contenente l'elenco dei video desiderati. Ci sono URL diversi a seconda del fatto che si voglia interrogare un canale o una categoria. In questo esempio mostrerò come interrogare un canale, che poi si traduce nell'interrogare tutti i video caricati da uno specifico utente.

YouTube mette a disposizione delle specifiche API per fare questo, atteso che i feed RSS non sono più disponibili come una volta. La developer guide di YouTube è disponibile qui.

Supponiamo di voler elencare tutti i video nel canale YouTube dei Queen, ma la mia rock band preferita. Il feed per questo elenco è così conformato:

http://gdata.youtube.com/feeds/api/users/queenofficial/uploads?orderby=updated

Potete banalmente verificarlo digitando il link nel vostro browser. Come fare ora per utilizzarlo in Windows Phone? Innanzitutto ci vuole un DataTemplate per la ListBox che utilizzeremo. In questo template decidiamo di mostrare la thumbnail del video e la descrizione:

    <phone:PhoneApplicationPage.Resources>
        <DataTemplate x:Key="SearchResultsItemTemplate">
            <StackPanel Margin="0,0,0,30" Orientation="Horizontal">
                <Image Source="{Binding VideoImageUrl}" HorizontalAlignment="Left" Width="100"   
         Height="90" Stretch="UniformToFill" VerticalAlignment="Top"/>
                <TextBlock Text="{Binding Title}" VerticalAlignment="Top" Width="300"
         HorizontalAlignment="Left" Margin="10,0,0,0" TextWrapping="Wrap"/>
            </StackPanel>
        </DataTemplate>
    </phone:PhoneApplicationPage.Resources>

Successivamente ci vuole la ListBox... molto semplice:

                <ListBox x:Name="ResultsList" 
                         
                         ItemTemplate="{StaticResource SearchResultsItemTemplate}" 
                         ItemsSource="{Binding}" SelectionChanged="VideoListSelectionChanged" />

Come vedete viene specificato il template per gli elementi. Ora ci sono tre cose da fare. La prima è definire una classe che rappresenti un video. In forma semplificata, per le informazioni che servono a noi, questo può essere un esempio:

Public Class YouTubeVideo
    Public Property Title As String
    Public Property VideoImageUrl As String
    Public Property VideoId As String
End Class

La seconda cosa da fare è stabilire il caricamento dell'elenco dei video. Il posto all'interno dell'applicazione varia a seconda delle vostre esigenze, diciamo che il frammento di codice necessario è, a livello generale, simile al seguente:

Dim w As New WebClient
AddHandler w.DownloadStringCompleted, Sub(sender As Object, e As DownloadStringCompletedEventArgs)
Dim atomns = XNamespace.Get("http://www.w3.org/2005/Atom")
Dim medians = XNamespace.Get("http://search.yahoo.com/mrss/")
Dim xml = XElement.Parse(e.Result)
Dim videos = (From entry In xml.Descendants(atomns.GetName("entry"))
              Select New YouTubeVideo With {.VideoId = entry.Element(atomns.GetName("id")).Value,
              .VideoImageUrl = (From thumbnail In entry.Descendants(medians.GetName("thumbnail"))
              Where thumbnail.Attribute("height").Value = "90"
              Select thumbnail.Attribute("url").Value).FirstOrDefault(),
              .Title = entry.Element(atomns.GetName("content")).Value}).ToArray()
                                                        ResultsList.ItemsSource = videos
 
searchUri = "http://gdata.youtube.com/feeds/api/users/queenofficial/uploads?orderby=updated"
w.DownloadStringAsync(New Uri(searchUri))

 Il feed RSS è sempre un contenuto XML, di conseguenza usiamo LINQ to XML per analizzare il contenuto del feed e per creare un'istanza della classe YouTubeVideo, popolandola con le relative proprietà, per ciascun elemento nel feed. Non ho utilizzato gli XML Literals di VB in questo caso per due ragioni: la prima è che dobbiamo fare riferimento a un namespace diverso nei descendants e la seconda è che tanto lo so che anche chi usa C# capita di qua

Fatto questo l'ultimo step è gestire l'evento changed sulla selezione nella ListBox. Ecco il codice:

    Private Sub VideoListSelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs)
        Dim video = CType(ResultsList.SelectedItem, YouTubeVideo)
        If video IsNot Nothing Then
            Dim parsed = video.VideoId.Split(CChar("/"))
            Dim id = parsed(parsed.Length - 1)
            Dim playbackUrl = "vnd.youtube:" + id
 
            Dim task As New WebBrowserTask With {.Uri = New Uri(playbackUrl)}
            task.Show()
        End If
    End Sub

In sostanza l'elemento selezionato viene convertito in un'istanza della classe YouTubeVideo della quale vengono lette le proprietà e con queste viene costruito l'URL del video, che viene avviato tramite il launcher WebBrowserTask.

A questo punto entra in gioco quello che secondo me è l'unico neo di questa tecnica: per riprodurre il video è necessario avere sul device l'app per YouTube, che è quella gratuita di Microsoft. Neo nel senso che la riproduzione avverrà, a causa del formato di video, tramite un'app esterna che comunque rimane gratuita e comunque, se non disponibile, sarà il dispositivo a suggerire all'utente di installarla. Questo ha anche un'implicazione: l'emulatore non permette il download dal Market Place, di conseguenza sarete in grado di visualizzare l'elenco ma per riprodurre un video dovrete fare il test sul device fisico.

Nonostante queste piccolezze, si tratta di una tecnica molto efficace soprattutto se dovete visualizzare video che non avete in altro formato ma che sapete siano disponibili su YouTube.

Alessandro

posted @ 11/01/2012 10.36 by Alessandro Del Sole

Passaggio di parametri a un Reportviewer

Spesso ci si trova nella condizione di dover scrivere direttamente dentro il reportviewer senza poter attingere a dei dati esistenti nel database. In questo caso ci viene in aiuto il concetto di parameters.
Aprendo il report si può accedere alla finestra Report data. Aggiungiamo tre parameters, nel mo caso iva4, iva10 e iva21.
Poi, da codice:

 Dim doc = From docm In mydc.vwDocumentos _
                      Where docm.idDocumento = idDocumento _
                      Select docm

Imposto la sorgente di dati ricevendo come valore idDocumento

        vwDocumentoBindingSource.DataSource = doc

associo la sorgente al bindingsource collegato al report


           Dim p4 As New Microsoft.Reporting.WinForms.ReportParameter("iva4", cDocumenti.TotaleImponibile_IVA(idDocumento, 1))
        Dim p10 As New Microsoft.Reporting.WinForms.ReportParameter("iva10", cDocumenti.TotaleImponibile_IVA(idDocumento, 2))
        Dim p21 As New Microsoft.Reporting.WinForms.ReportParameter("iva21", cDocumenti.TotaleImponibile_IVA(idDocumento, 3))


inizializzo i tre parametri

        ReportViewer1.LocalReport.SetParameters(p4)
        ReportViewer1.LocalReport.SetParameters(p10)
        ReportViewer1.LocalReport.SetParameters(p21)

li passo al report
        Me.ReportViewer1.SetDisplayMode(DisplayMode.PrintLayout)
        Me.ReportViewer1.RefreshReport()

infine mostro il risultato

posted @ 10/01/2012 14.08 by Flavio Firmo

LightSwitch Tips & Tricks supera i 1000 iscritti

A circa un anno e mezzo dal suo lancio, avvenuto il 24 agosto del 2010 in concomitanza col rilascio della Beta 1 di Visual Studio LightSwitch, qualche giorno fa la nostra community LightSwitch Tips & Tricks ha superato i 1000 iscritti, un traguardo davvero entusiasmante per un sito di questo tipo.

Per festeggiare degnamente l'avvenimento il millesimo iscritto, il fortunato Andrea Romeo, si è aggiudicato una copia del mio libro Visual Studio LightSwitch Unleashed che uscirà a breve.

Ne approfitto per ringraziare innanzitutto i miei compagni di avventura che ogni giorno contribuiscono alla gestione impeccabile della community ma anche per un ringraziamento proprio agli iscritti che con le loro domande nei forum e con i loro contributi tecnici hanno permesso da un lato alla community stessa di accrescere il proprio livello qualitativo e dall'altro di dimostrare che LightSwitch non è affatto solo un prodotto per principianti, ma che si presta a scenari applicativi decisamente complessi e interessanti.

A quota 2000 faremo un altro regalo, anche se ora è un po' presto per pensarci

Ancora un grazie e vi aspettiamo in community!

Alessandro

posted @ 08/01/2012 16.10 by Alessandro Del Sole

Promozione natalizia per i soci di VisualBasic-Tips&amp;Tricks

OFFERTA ESCLUSIVA PER I SOCI di VBTT – estensione fino al 30/01/2012!

Per tutto il periodo natalizio e oltre, fino al 30 gennaio 2012, sarà possibile acquistare CyberInstaller Suite 2011 o un suo aggiornamento col 50% di sconto!

Vi basterà contattare il Servizio Clienti SilverCyberTech comunicando questo codice promozione:

CIS2011-XMAS-PROMOCODE-FORVBTTONLY

per ricevere la modalità di pagamento tramite la quale perfezionare l'acquisto con il 50% di sconto.

Ecco il listino prezzi con la promozione:

Licenza CyberInstaller Suite 2011 Enterprise "full": € 199,90 € 99,90

Licenza CyberInstaller Suite 2011 Enterprise "update": € 119,90 € 59,90

Licenza CyberInstaller Suite 2011 Enterprise "upgrade path": € 139,90 € 69,90

Licenza CyberInstaller Suite 2011 Professional "full": € 149,90 € 74,90

Licenza CyberInstaller Suite 2011 Professional "update": € 89,90 € 44,90

Licenza CyberInstaller Suite 2011 Professional "upgrade path": € 104,90 € 52,40

Non fatevi scappare quest'irripetibile occasione... e ancora mille auguri!

posted @ 05/01/2012 12.53 by Sergio Pappalardo