in

DotNetSide

Dot Net South Italy Developers User Group

Tips

June 2006 - Posts

  • Recuperare i dati da una cella del DataGridView

     

    Autore: Michele Locuratolo

    Spesso si ha la necessità di recuperare i dati da una cella di una DataGrid. La regola vuole che tali elementi vengano recuperati dal DataSource e non dalla DataGridView in quanto, come spesso accade, nella gliglia potrebbero non essere mostrati tutti i dati.
    Per farlo, usiamo il seguente codice:


    1    private object GetCurrentBindedObject(DataGridView dgv) {
    2
    3 if (dgv == null || dgv.DataSource == null) {
    4 return null;
    5 }
    6
    7 BindingManagerBase bmb = dgv.BindingContext[dgv.DataSource];
    8
    9 if (bmb == null) {
    10 return null;
    11 }
    12
    13 return bmb.Current;
    14 }

    Il tipo di ritorno è un object che, in caso la sorgente dati sia una DataTable, dovrà essere castato a DataRowView.
    A questo punto, per accedere al dato che ci interessa leggere, possiamo usare il seguente codice:

    1    DataRowView drv = (DataRowView)GetCurrentBindedObject(dgvUsers); 
    2 string strNome = drv["Nome"].ToString();


    Il .NET Framework 2.0 però, ci permette di creare in modo semplice delle collection di oggetti bindabili ad elementi della UI.
    Usando questa nuova caratteristica ed i comodi Generics, possiamo modificare il codice di GetCurrentBindedObject per farci ritornare direttamente il tipo che ci interessa.
    Supponiamo di avere un oggetto User che rappresenta l’utente e la collection Users, che deriva da BinsingList<T> che rappresenta l’elenco dei nostri utenti (vedi codice allegato).
    Il nostro codice può essere modificato come segue:


    1    private T GetCurrentBindedObject(DataGridView dgv) where T: class {
    2
    3 if (dgv == null || dgv.DataSource == null) {
    4 return null;
    5 }
    6
    7 BindingManagerBase bmb = dgv.BindingContext[dgv.DataSource];
    8
    9 if (bmb == null) {
    10 return null;
    11 }
    12
    13 return bmb.Current as T;
    14 }


    da usare con il seguente codice:

    1    User user = GetCurrentBindedObject(dgvUsers);
    2 string Nome = user.Name;

     Lo stesso metodo, essendo generico, potrà essere usato per tutti gli object del nostro domain model.
    Il codice completo è disponibile nel file allegato.

    Posted Jun 30 2006, 11:36 PM by VitoA with 1 comment(s)
    Filed under:
  • Leggere il sorgente di una pagina html

    Autore: Vito Arconzo

    Ecco una funzione che restituisce il codice HTML di una pagina web.
     

    1        Function GetHtmlPageSource(ByVal url As String, _
    2                Optional ByVal username As String = Nothing, _
    3                Optional ByVal password As String = Nothing) As String
    4            Dim st As System.IO.Stream
    5            Dim sr As System.IO.StreamReader
    6    
    7            Try
    8                ' invia una Web request
    9                Dim req As System.Net.WebRequest = System.Net.WebRequest.Create(url)
    10   
    11               ' se sono specificati username/password usa le credenziali
    12               If Not username Is Nothing AndAlso Not password Is Nothing Then
    13                   req.Credentials = New System.Net.NetworkCredential(username, password)
    14               End If
    15   
    16               ' ricava la risposta e legge lo stream coi risultati
    17               Dim resp As System.Net.WebResponse = req.GetResponse
    18               st = resp.GetResponseStream
    19               sr = New System.IO.StreamReader(st)
    20   
    21               Return sr.ReadToEnd
    22           Catch ex As Exception
    23               Return ""
    24           Finally
    25               sr.Close()
    26               st.Close()
    27           End Try
    28       End Function
    
     
    Posted Jun 30 2006, 11:55 AM by VitoA with no comments
    Filed under:
  • Verificare se un anno è bisestile

    Autore: Vito Arconzo

    Spesso è necessario conoscere se un anno sia bisestile.
    Con VB.NET è molto semplice in quanto, il problema, è stato risolto alla fonte: è fornito un opportuno metodo, IsLeapYear, che accetta in input un valore intero (l'anno) e restituisce un valore booleano (True = bisestile, False = non bisestile).

    Per provare questa funzione, creare una form, aggiungere due TextBox di nome rispettivamente TextBox1 e TextBox2 ed un pulsante e infine, nell'evento Click del pulsante inserire il seguente codice:

     
    1      If TextBox1.Text = "" Then
    2 TextBox2.Text = "anno non indicato"
    3 Else
    4 If
    (DateTime.IsLeapYear(Integer.Parse(TextBox1.Text)) = True) Then
    5 TextBox2.Text = "Anno " & TextBox1.Text & " bisestile."
    6 Else
    7 TextBox2.Text = "Anno " & TextBox1.Text & " NON bisestile."
    8 End If
    9 End If

     
    Posted Jun 22 2006, 11:28 AM by VitoA with no comments
    Filed under:
  • Verificare se l'applicazione è già in esecuzione

    Autore: Fabio Cozzolino

    Verificare se l'applicazione è già in esecuzione

    Spesso mi viene chiesto: come posso fare per verificare se il mio programma è già in esecuzione?

    Una possibile soluzione è l'utilizzo della classe Mutex del namespace System.Threading. Mutex verifica che in esecuzione esista un unico thread in base al nome passato come parametro stringa.

    Un esempio in Visual Basic .NET:

    1    Private Shared m As Mutex
    2
    3 Private Shared Sub Main()
    4 Dim first As Boolean
    5
    6 m = New Mutex(true, Application.ProductName, first)
    7 if (first) then
    8 Application.Run(new MainForm())
    9 m.ReleaseMutex()
    10 else
    11 MessageBox.Show("Applicazione già in esecuzione")
    12 end if
    13 End Sub
     
    Posted Jun 21 2006, 10:16 AM by VitoA with no comments
    Filed under:
  • Creazione di una stringa di connessione

    Autore: Vito Arconzo

    Ecco un comodissimo metodo (poco documentato) per la creazione di una stringa di connessione di qualsiasi tipo:

    • Creare un file di testo chiamato test.udl (in qualsiasi posizione);
    • Doppio click sul file appena creato;
    • Apparirà un wizard molto familiare, è lo stesso utilizzato da VS e tools vari in fase di creazione di stringhe di connessione;
    • Configurare la connessione al database utilizzando il provider che vi serve.

    Una volta terminata la creazione guidata e, naturalmente, confermata cliccando sul pulsanto OK, è possibile aprire il file udl con il notepad e, magia, all'interno troviamo la stringa di connessione pronta per essere copiata ed utilizzata a nostro piacimento.

    Posted Jun 12 2006, 10:12 AM by VitoA with no comments
    Filed under:
  • Invertire una stringa

    Autore: Vito Arconzo

    Questa funzione restituisce la stringa passata come parametro invertita.

    1    Public Function ReverseString(ByVal stringToReverse As String) As String
    2 ' dichiarazione variabili

    3 Dim s As String = ""
    4 Dim lunghezza As Integer = 0
    5 If stringToReverse = "" Then
    6 ' se stringa vuota restituiscila
    7 s = ""
    8 Else
    9 ' altrimenti esegui l'inversione della stringa
    10 lunghezza = stringToReverse.Length
    11 For i As Integer = (lunghezza - 1) To 0 Step -1
    12 s = String.Concat(s, stringToReverse.Substring(i, 1))
    13 Next
    14 End If
    15 Return
    (s)
    16 End Function
     
    Posted Jun 09 2006, 09:55 AM by VitoA with 1 comment(s)
    Filed under:
  • Interfaccia Inserimento e ReadOnly

    Autore: Francesco Guadagno

    Molto spesso mi son trovato difronte al semplice “problema” di dover gestire una interfaccia o form di inserimento, nella doppia modalità Inserimento e sola visualizzazione.

    Il problema, se pur semplice, ci costringe a iterare sulle varie proprietà “ReadOnly” ed “Enabled” dei vari controlli impostando il valore che ci serve in quel momento.

    Se sfruttiamo la ControlCollection di un qualsiasi WebControl, è possibile fare qualcosa di questo tipo:

    1    public static void EnableFields(Control c, bool bEnabled){
    2        foreach (Control c1 in c.Controls){
    3            string sType = c1.ToString();
    4            switch (c1.ToString()){
    5                   case "System.Web.UI.WebControls.TextBox":
    6                        ((TextBox)c1).Enabled = bEnabled;
    7                        break;
    8                   case "System.Web.UI.WebControls.DropDownList":
    9                        ((DropDownList)c1).Enabled = bEnabled;
    10                       break;
    11                  case "System.Web.UI.WebControls.CheckBox":
    12                       ((CheckBox)c1).Enabled = bEnabled;
    13                       break;
    14                  case "System.Web.UI.WebControls.ListBox":
    15                       ((ListBox)c1).Enabled = bEnabled;
    16                       break;
    17             }
    18             if (c1.HasControls()){
    19                  EnableFields(c1, bEnabled);
    20             }
    21       }
    22   }
    

    Si tratta di una funzione ricorsiva che accetta in input un qualsiasi controllo, ad esempio la tabella che contiene tutti i webcontrols, e che ripete la procedura per ogni controllo trovato nella ControlCollection.

    Le operazioni effettuabili sono le più disparate. Possiamo in questo modo pensare di gestire anche problematiche come visibilità, abilitazioni di Validator,Reset form, ecc.

    Posted Jun 08 2006, 01:03 PM by VitoA with no comments
    Filed under:
  • StringBuilder vs Concatenamento

     

    Autore: Michele Locuratolo

    Mi capita spesso che mi venga richiesto come fare per migliorare le performance di una applicazione e, altrettanto spesso, scopro che viene usato il semplice concatenamento di stringhe per comporre dei messaggi. Si va dal semplice messaggio di poche parole (che concatena 4 o 5 stringhe) a veri e propri testi.
    Questo modo di fare causa spesso problemi di performance. Scopriamo insieme il perchè.
    Usiamo allo scopo questo semplice codice:

     string myString = string.Empty;
     
    for (int i = 0; i < 10000; i++) {
         myString += i.ToString();
     }

    Il funzionamento è estremamente semplice: la nostra stringa sarà il risultato del concatenamento di 10.000 numeri.
    Internamente però, questa operazione è decisamente pesante. Partendo dal concetto che una stringa è un oggetto immutabile e che, ad ogni modifica di essa, ne deve essere creata una copia che contiene il nuovo valore, non è difficile immaginare cosa accade all'interno del nostro ciclo.
    Al primo "giro", verrà creata una nuova stringa che conterrà il valore precedente (string.Empty) ed il nuovo (0). Al secondo cliclo, ancora una volta, verrà creata una nuova stringa che contenente il valore precedente ed il nuovo (1) e così via. Ne consegue che, per 10.000 cicli, verranno create 10.000 stringhe! Tutte le stringhe precedenti vengono poi eliminate dal Garbage Collector.
    Se mandiamo in esecuzione il codice di sopra aggiungendo un paio di timer, otterremo il seguente risultato:

    Avvio ciclo di concatenamento
    Tempo impiegato: 00:00:00.5107344

    Praticamente 1/2 secondo per concatenare 10.000 stringhe. Apparentemente potrebbe sembrare poco ma vediamo cosa accade usando un oggetto realizzato apposta per questo scopo: lo StringBuilder:

     StringBuilder sb = new StringBuilder(10000);
     
    for (int i = 0; i < 10000; i++) {
         sb.Append(i.ToString());
     }

    Grazie a questo oggetto, il concatenamento non avviene più creando una copia della stringa. StringBuilder contiene un vettore di caratteri ed il concatenamento avviene direttamente sul vettore evitando inutili copie di oggetti. Se mandiamo in esecuzione il codice otterremo:

    Avvio ciclo con StringBuilder
    Tempo impiegato: 00:00:00.0100144

    50 volte più veloce! Ma la velocità è solo la minima conseguenza. Se usiamo un tool come CLR Profiler (esiste sia per la versione 1.1 che 2.0 del framework), possiamo vedere quanto sia più pesante da eseguire il primo codice rispetto al secondo. Di seguito un report:

      Concatenamento StringBuilder
    Allocated bytes:
    Relocated bytes:
    Final Heap bytes:
    Objects finalized:
    Critical objects finalized:
    Gen 0 collections:
    Gen 1 collections:
    Gen 2 collections:
    Induced collections:
    Gen 0 Heap bytes:
    Gen 1 Heap bytes:
    Gen 2 Heap bytes:
    Large Object Heap bytes:
    Handles created:
    Handles destroyed:
    Handles surviving:
    Heap Dumps:
    Comments:

    379.311.360
    20.536.640
    1.575.328
    0
    0
    449
    47
    0
    0
    847.516
    390.678
    12
    8.784
    27
    0
    27
    0
    0

    544.756
    0
    544.756
    0
    0
    0
    0
    0
    0
    Unknown
    Unknown
    Unknown
    Unknown
    27
    0
    27
    0
    0

    Come è evidente, tanto la memoria allocata quanto il lavoro fatto dal Garbage Collector sono notevolmente ridotti dallo StringBuilder.
    Personalmente, se devo concatenare più di 3 stringhe, uso il secondo codice. Fino a 3, non c'è quasi differenza tra i 2 sistemi.

    Posted Jun 05 2006, 01:17 AM by VitoA with 22 comment(s)
    Filed under:
  • Utilizzo ANSI Jolly in SQL

    Autore: Vito Arconzo

    Se siamo abituati ad utilizzare caratteri jolly ANSI (* e ?), questa funzione converte il caratteri jolly SQL (% e _), quindi, in ANSI.

        Public Function AnsiJolly(ByVal Value As String) As String
            If (Value Is Nothing) Then
                Return String.Empty
            End If

            Value = Value.Replace("*", "%")
            Return Value.Replace("?", "_")
        End Function

    Posted Jun 03 2006, 09:49 AM by VitoA with 3 comment(s)
    Filed under:
  • Convertire una stringa in una DataTable

    Autore: Vito Arconzo

    Questa utilissima funzione permette la conversione di una stringa contenente valori separati da un carattere in  DataTable.

        Public Function StringToTable(ByVal value As String, ByVal delimiter As Char) As DataTable
            Dim table As DataTable = New DataTable
            table.Rows.Clear()
            table.Columns.Clear()
            table.Columns.Add("Value", GetType(String))

            If ((Not value Is Nothing) AndAlso (value.Length > 0)) Then
                Dim text1 As String
                For Each text1 In value.Split(New Char() {delimiter})
                    Dim objArray1 As Object() = New Object() {text1}
                    table.Rows.Add(objArray1)
                Next
            End If

            table.AcceptChanges()
            table = Nothing
            Return table
        End Function

    Posted Jun 03 2006, 01:35 AM by VitoA with 3 comment(s)
    Filed under:
  • Verificare validità numerica di una stringa

    Autore: Giuseppe Russo (Croghen)

    A volte abbiamo la necessità di verificare che un valore sia numerico o meno. Alcune possibilità in C# sono:
    1) Usare try/catch (non performante e poco elegante)
    2) Referenziare Microsoft.VisualBasic.dll, usare quindi IsNumeric (lo farebbe mai uno sviluppatore C# ???)
    3) Riscriversi IsNumeric

    Ecco qui una semplicissima funzione StringIsNumeric che verifica, appunto, che una stringa sia numerica

    public static bool StringIsNumeric(string StringToAnalyze)
    {
        bool bIsNum = true;
        foreach(char cChar in StringToAnalyze.ToCharArray())
        {
            if(cChar < 48 || cChar > 57)
            {
                bIsNum = false;
            }
        }
        return bIsNum;
    }

    Posted Jun 01 2006, 05:42 AM by VitoA with 5 comment(s)
    Filed under:
Powered by Community Server (Commercial Edition), by Telligent Systems