Quando mi capita di realizzare qualche gestionale, la richiesta che mi sento fare di più dai clienti è quella di poter lavorare senza staccare le mani dalla tastiera.. odiano il mouse. Per far fronte a tale richiesta, qualche tempo fa, ho realizzato uno UserControl facilmente riadattabile che permette la ricerca e la selezione di elementi ( ad esempio clienti, articoli etc etc ) all'interno di una DataGridView in modo molto rapido.
Nell'immagine qui in alto possiamo vedere una lista di clienti filtrata per "Codice Cliente" e "Nome Cliente". Mentre si digitano le parole chiave con le quali filtrare l'elenco di clienti, è possibile muoversi all'interno dell'elenco filtrato usando le freccie su e giù senza dover spostare il focus sulla DataGridView. A questo link potrete scaricare una soluzione vb.net 2005 contenente il codice delle UserControl. Qui brevemente mi limiterò ad illustrare le idee sulle quali si basa il filtro. Le due caselle di testo "Codice Cliente" e "Nome Cliente" sono il cuore del filtro, attraverso di esse si deve poter filtrare i clienti e contestualmente muoversi all'interno dell'elenco filtrato. Per ora puntiamo la nostra attenzione sulla parte di scorrimento e selezione del filtro. Entrambe le sopracitate caselle di testo sono istanze della classe bcc_TextBox, una classe che eredita da TextBox La classe bcc_TextBox contiene l'override della funzione ProcessCmdKey attraverso la quale è possibile intercettare la pressione di ogni tasto all'interno del controllo TextBox. I tasti che ci interessa intercettare e gestire sono ovviamente i tasti freccia SU e GIU e il tasto INVIO, per tutti gli altri vogliamo che la classe bcc_TextBox si comporti come un normale TextBox. Ecco il frammento di codice qui di seguito:
Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean
Select Case keyData
Case Keys.Down, Keys.Up, Keys.Return, Keys.Enter
RaiseEvent OneKeyPressed(keyData)
Return True
Case Else
Return MyBase.ProcessCmdKey(msg, keyData)
End Select
End Function
Come si può vedere dal codice, la classe bcc_TextBox lancia un evento OneKeyPressed per notificare all'esterno l'avvenuta pressione di uno dei tasti che si vuole gestire passando come parametro proprio il codice del tasto premuto. Sarà poi lo UserControl che si occuperà di gestire l'evento in questione attraverso il seguente handler:
Private Sub m_OneKeyPressed(ByVal key As System.Windows.Forms.Keys)
If IsNothing(dgv_Clienti.DataSource) Then Exit Sub
Dim cm As CurrencyManager
cm = Me.BindingContext(dgv_Clienti.DataSource)
If cm.Position = -1 Then Exit Sub
Select Case key
Case Keys.Up
If cm.Position = 0 Then
cm.Position = cm.List.Count - 1
Else
cm.Position -= 1
End If
Case Keys.Down
If cm.Position = cm.List.Count - 1 Then
cm.Position = 0
Else
cm.Position += 1
End If
Case Keys.Return, Keys.Enter
m_SelezionaCliente()
End Select
End Sub
Per spostarsi tra le righe del DataGridView si è usato un CurrencyManager, sfruttandone la proprietà Position è semplicissimo muoversi tra l'elenco filtrato dei clienti . Il CurrencyManager viene anche impiegato per restituire il cliente selezionato.
Private Sub m_SelezionaCliente()
Dim drv As DataRowView
Dim cm As CurrencyManager
cm = Me.BindingContext(dgv_Clienti.DataSource)
If cm.Position = -1 Then Exit Sub
drv = CType(cm.Current, DataRowView)
RaiseEvent ClienteSelezionato(drv("Id"), drv("Nome"))
End Sub
Resta da spiegare come avviene il filtraggio dei dati. Nessuna particolare novità, si è settato un evento TextChanged sulle due caselle di testo e si è composta una stringa con la quale filtrare il DataView usato come DataSource del DataGridView
Private Sub txt_DoFilter(ByVal sender As System.Object, ByVal e As System.EventArgs)
Try
RemoveHandler txt_CodiceCliente.TextChanged, AddressOf txt_DoFilter
RemoveHandler txt_NomeCliente.TextChanged, AddressOf txt_DoFilter
Dim dv As DataView
Dim strFilter As String = ""
dv = dgv_Clienti.DataSource
strFilter = ""
If txt_CodiceCliente.Text.Trim <> "" Then
Dim val As Int64
Try
val = CInt(txt_CodiceCliente.Text.Trim)
Catch ex As Exception
txt_CodiceCliente.Text = ""
Finally
strFilter = "( Id = " & txt_CodiceCliente.Text.Trim & " )"
End Try
End If
If txt_NomeCliente.Text.Trim <> "" Then
Dim tmp As String
tmp = txt_NomeCliente.Text.Trim
tmp = tmp.Replace("'", "")
tmp = tmp.Replace("""", "")
tmp = tmp.Replace("%", "")
If tmp <> txt_NomeCliente.Text.Trim Then txt_NomeCliente.Text = tmp
strFilter &= IIf(strFilter <> "", " AND ", "") & "(Nome Like '%" & txt_NomeCliente.Text.Trim & "%')"
End If
dv.RowFilter = strFilter
lb_ClientiTrovati.Text = dgv_Clienti.RowCount
Catch ex As Exception
Finally
AddHandler txt_CodiceCliente.TextChanged, AddressOf txt_DoFilter
AddHandler txt_NomeCliente.TextChanged, AddressOf txt_DoFilter
End Try
End Sub
Nessun commento:
Posta un commento