Ricerca in listbox

mercoledì 05 novembre 2008 - 10.29

jtpsala Profilo | Senior Member

Un buon giorno a tutti gli utenti di questo Forum.

Devo effettuare una ricerca nel contenuto di una ListBox e per il momento utilizzo questo codice:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Tutto funziona, ma nella TextBox devo digitare correttamente il testo ricercato.
Io invece volevo ricercare anche parzialmente nelle stringhe contenute nella listbox (ad esempio tutte le righe che contengono "abc", sia all'inizio, sia al centro, sia alla fine della stringa).

Qualcuno mi potrebbe aiutare?

Ringrazio tutti in anticipo.

Anonimo Profilo | Senior Member

Non sò se esistono metodi appositi, ho scritto due righe e sembrerebbe funzionare.
Ho scritto il codice in c# però, e sinceramente non me la sentivo di tradurtelo con qualche traduttore automatico.. dacci comunque un occhio..

using System; using System.Text.RegularExpressions; using System.Windows.Forms; namespace prova { public partial class Form1 : Form { private void button2_Click(object sender, EventArgs e) { ListBox.ObjectCollection obj = listBox1.Items; Regex reg = new Regex(textBox1.Text); for (int i = 0; i < obj.Count; i++) { if (reg.Match((string)obj[i]).Success) { listBox1.SelectedIndex = i; return; } } listBox1.SelectedIndex = -1; } } }

alexmed Profilo | Guru

Ciao
Per trovare l'occorrenza che cerchi puoi utilizzare "Contains"
Ad esempio:

For i As Integer = 0 To Me.ListBox1.Items.Count - 1
If Me.ListBox1.Items(i).ToString.Contains("abc") Then
MsgBox(Me.ListBox1.Items(i).ToString)
End If
Next

Ti visualizza una MessageBox se all'interno della stringa è contenuto "abc"

Ciao

jtpsala Profilo | Senior Member

Ragazzi vi ringrazio per avermi risposto.
Ho provato i vostri due spezzoni di codice ma non funzionano.
Il problema è che nella mia ListBox non esiste alcun Item.

Il caricamento dei dati avviene in questo modo:

Dim files As String() = IO.Directory.GetFiles("C:\DtsFatture\") For index As Integer = 0 To files.GetUpperBound(0) Step 1 files(index) = IO.Path.GetFileNameWithoutExtension(files(index)) Next index Me.ListBoxControl1.DataSource = files

Infatti, la ListBox non fa altro che visualizzare il contenuto della Directory "C:\DtsFatture", caricando i nomi dei file. I nomi di questi ultimi sono "Fattura nr. xx del dd-mm-aaaa".
Avete qualche altra soluzione?

Vi ringrazio ancora.

alexmed Profilo | Guru

Ciao
scusa ma non sapevo che esistesse un controllo ListBoxControl però credo che condivida molto con il ComboBox ed il ListBox quidi dovrebbe esserci un metodo per accedere agli Item

PS
Perchè usi un ListBoxControl e non un ListBox?

jtpsala Profilo | Senior Member

Si è un controllo personalizzato della Dxperience ed ha le stesse proprietà di una comune ListBox.
Il problema però è che io nelle items non carico nulla.
La visualizzazione dei dati all'interno avviene al caricamento della Form con quella "query" che ho postato.

Anonimo Profilo | Senior Member

potresti eseguire il codice sopra scritto sull'array files, tanto l'associazione dovrebbe essere la medesima.

Teech Profilo | Expert

Al posto di un array puoi utilizzare una List(of T) e utilizzare i BindingSource.

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Il binding funziona con le ListBox e non ho la ListBoxControl della DXperience (spero ancora per poco) ma il concetto dovrebbe essere uguale.
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

jtpsala Profilo | Senior Member

Ok, con il caricamento dei dati va bene.
C'è un solo problema: bs1.Filter="Campo='" & TextBox.Text &"'"....

Se il BindingSource lo creiamo nel momento in cui ha vita la Form, come faccio a determinare i nomi dei campi contenuti?

Teech Profilo | Expert

La determinazione dei nomi dei campi è esattamente il problema che non so risolvere perchè fondamentalmente non c'è un nome di campo non derivando da una "tabella", ma sicuramente ci sarà una soluzione a questo.
Per il dove dimensionare il BindingSource io lo farei a livello di classe:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Spero di esserti stato utile
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

jtpsala Profilo | Senior Member

Questo problema lo avevo già riscontrato tempo fa quando avevo scento di assegnare una BindingSorce alla ListBoxControl.
Ecco perchè avevo seguito la strada di caricare nella Load del Form i dati in questo modo:

Dim files As String() = IO.Directory.GetFiles("C:\DtsFatture\") 'For index As Integer = 0 To files.GetUpperBound(0) Step 1 files(index) = IO.Path.GetFileNameWithoutExtension(files(index)) 'Next index Me.ListBoxControl1.DataSource = files

ed il filtraggio in questo modo:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Io Vi ringrazio immensamente per il tempo che mi avete voluto dedicare.

Se non trovo altra soluzione, opterò di lasciare tutto come prima.

Grazie, grazie ancora.

Teech Profilo | Expert

Ho fatto una piccola ricerca.
il metodo Filter dell'oggetto BindingSource funziona solo con collection che implementano l'interfaccia IBindingListViev. L'oggetto List(Of T) non implementa tale interfaccia. Puoi però crearti una tua classe che eredita da BindingSource e implementare le interfacce che ti servono.
Ho trovato il seguente codice che fa circa questo (usa un BindingList(Of T)):

in C#
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
In VB
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Non è prettamente semplice ma può essere riutilizzato in futuro...

--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole

Anonimo Profilo | Senior Member

Ritorno a dire che una volta che trovi l'indice dell'array che corrisponde alla tua ricerca *dovresti* aver trovato anche l'indice che ha quell'elemento nella listbox.
C#

private void button2_Click(object sender, EventArgs e) { int i=0; foreach (string file in files) { if(file.Contains(textBox1.Text)){ listBox1.SelectedIndex = i; return; } i++; } listBox1.SelectedIndex = -1; }

in vb dovrebbe essere una roba del genere:

Private Sub button2_Click(ByVal sender As Object, ByVal e As EventArgs) Dim i As Integer = 0 For Each file As String In files If file.Contains(textBox1.Text) Then listBox1.SelectedIndex = i Return End If i += 1 Next listBox1.SelectedIndex = -1 End Sub

jtpsala Profilo | Senior Member

Si hai ragione, in questo modo funziona, ma funzionava anche il codice che già utilizzavo io inizialmente.
I nomi dei files salvati nella mia directory iniziano tutti con "Fattura nr. XX del XX-XX-XXXX" dove le "x" stanno per il numero della fattura e data.
Io volevo fare una cosa del genere:
utilizzando una textbox e scrivendo all'interno ad esempio 10 (xx come numero della fattura) automaticamente venisse ricercato tale valore nella ListBox.
Nel caso che hai postato tu, come anche nel mio, per fare il modo che venga selezionata la riga ricercata bisogna scrivere nella textbox "Fattura nr. xx del xx-xx-xxxx" perchè altrimenti non verrà ricercato nulla.

Magari bisognerebbe implementare la ricerca utilizzando dei like, "*" oppure "%".

Ho reso l'idea di cosa volevo fare?

Vi ringrazio.
Se avete qualche idea?

Anonimo Profilo | Senior Member

No attento, il codice che ti ho postato sopra fa quello che ti serve, ovvero data una stringa ricerca nell'array files la prima occorrenza che la contiene


330x278 9Kb

jtpsala Profilo | Senior Member

Si è vero, il codice da te postato funziona correttamente solo se nella mia listbox ho inserito delle stringhe nella Items.
Nella mia ListBox la Items è vuota. I dati vengono caricati dinamicamente alla Load della Form e perscati da una cartella (file system) che a loro volta vengono caricati tramite il datasource.

Comunque ho risolto inserendo nella TextBox di ricerca il completamento automatico.

Vi ringrazio tutti comunque.

A presto.

Teech Profilo | Expert

Potresti anche operare in un modo un pò diverso.
Crei una classe FileFattura con le proprietà Numero e Data. Fai L'overrride del metodo ToString (derivato da Object) mettendo quello che vuoi.
Per ogni file trovato nella directory istanzi un oggetto FileFattura e lo aggiungi ad una Collection FilesFattura
A questo punto puoi gestire la collection sulla tua List utilizzando il BindingSource e filtri sul campo (proprietà di ogni oggetto della collection) che preferisci.

Mi sembra una soluzione
--------------
Maurizio Brini
--------------
Nessuna impresa è mai stata compiuta da un uomo ragionevole
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5