searching in a listbox explorer style

  • Thread starter Stephan Steiner
  • Start date
S

Stephan Steiner

Hi

If you have multiple items in a listbox, click into the listbox, then type
for instante the letter "p", the first item whose text property starts with
"p" will be selected. Pressing "p" again will jump to the next item starting
with "p", etc.

In Windows explorer, you can type multiple letters after each other, and if
you're fast enough, they'll be taken as a search term together. For instance
pressing "p" then "e" then "a" would lead to the first folder/file whose
name starts with "pea" being selected.

Is there any way to achieve this functionality in a Listbox as well?

Regards
Stephan Steiner
 
J

Justin Rogers

I think you'd have to code that particular item... There are methods
for FindString and FindStringExact that might help. You'll have to
process these in response to a key message override along with
some timing logic for when the last key was pressed to decide
if you want to build the string or start anew.
 
S

Stephan Steiner

I was afraid to hear that

If anybody has an example of a similar operation that I could use as
inspiration for my own quest, please let me know.

Regards
Stephan
 
J

Justin Rogers

Sorry it took me a bit of a while to get around to this, but I think this may
help

using System;
using System.Windows.Forms;

public class AutoListBox : ListBox {
private AutoKeySearch searchKey;

public AutoListBox() : base() { }

protected override void OnKeyDown(KeyEventArgs e) { e.Handled = true; }
protected override void OnKeyUp(KeyEventArgs e) { e.Handled = true; }

protected override void OnKeyPress(KeyPressEventArgs e) {
e.Handled = true;

if ( searchKey.Keys == null || searchKey.LastPress.AddSeconds(1) <
DateTime.Now ) {
searchKey.Keys = new string(e.KeyChar, 1);
} else {
searchKey.Keys += e.KeyChar;
}
searchKey.LastPress = DateTime.Now;

int index = FindString(searchKey.Keys);
Console.WriteLine("Searching for {0}, {1}", searchKey.Keys, index);
if ( index > -1 ) {
SelectedIndex = index;
}
}

public struct AutoKeySearch {
public DateTime LastPress;
public string Keys;
}
}

public class AutoListBoxForm : Form {
private AutoListBox alb = new AutoListBox();

public AutoListBoxForm() {
this.alb.Dock = DockStyle.Fill;
this.alb.Items.AddRange(new string[] {
"a", "b", "c", "d", "e",
"aa", "bb", "cc", "dd", "ee",
"foot", "football" });
this.Controls.Add(alb);
}
}

public class Tester {
[STAThread()]
private static void Main(string[] args) {
Application.Run(new AutoListBoxForm());
}
}


--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

Stephan Steiner said:
I was afraid to hear that

If anybody has an example of a similar operation that I could use as
inspiration for my own quest, please let me know.

Regards
Stephan
 
S

Stephan Steiner

Thanks a bunch, that is just what I needed.

Stephan
Justin Rogers said:
Sorry it took me a bit of a while to get around to this, but I think this may
help

using System;
using System.Windows.Forms;

public class AutoListBox : ListBox {
private AutoKeySearch searchKey;

public AutoListBox() : base() { }

protected override void OnKeyDown(KeyEventArgs e) { e.Handled = true; }
protected override void OnKeyUp(KeyEventArgs e) { e.Handled = true; }

protected override void OnKeyPress(KeyPressEventArgs e) {
e.Handled = true;

if ( searchKey.Keys == null || searchKey.LastPress.AddSeconds(1) <
DateTime.Now ) {
searchKey.Keys = new string(e.KeyChar, 1);
} else {
searchKey.Keys += e.KeyChar;
}
searchKey.LastPress = DateTime.Now;

int index = FindString(searchKey.Keys);
Console.WriteLine("Searching for {0}, {1}", searchKey.Keys, index);
if ( index > -1 ) {
SelectedIndex = index;
}
}

public struct AutoKeySearch {
public DateTime LastPress;
public string Keys;
}
}

public class AutoListBoxForm : Form {
private AutoListBox alb = new AutoListBox();

public AutoListBoxForm() {
this.alb.Dock = DockStyle.Fill;
this.alb.Items.AddRange(new string[] {
"a", "b", "c", "d", "e",
"aa", "bb", "cc", "dd", "ee",
"foot", "football" });
this.Controls.Add(alb);
}
}

public class Tester {
[STAThread()]
private static void Main(string[] args) {
Application.Run(new AutoListBoxForm());
}
}
 
S

Stephan Steiner

By the way, I'm wondering if you, or anybody else knows the full logic
behind the search that Microsoft offers in the components used in Windows.
I'm not quite sure I'm getting the full logic behind it all. I'm playing
around in Explorer trying to get a grip on how the search works, but I think
I'm not quite there yet.

Stephan
Justin Rogers said:
Sorry it took me a bit of a while to get around to this, but I think this may
help

using System;
using System.Windows.Forms;

public class AutoListBox : ListBox {
private AutoKeySearch searchKey;

public AutoListBox() : base() { }

protected override void OnKeyDown(KeyEventArgs e) { e.Handled = true; }
protected override void OnKeyUp(KeyEventArgs e) { e.Handled = true; }

protected override void OnKeyPress(KeyPressEventArgs e) {
e.Handled = true;

if ( searchKey.Keys == null || searchKey.LastPress.AddSeconds(1) <
DateTime.Now ) {
searchKey.Keys = new string(e.KeyChar, 1);
} else {
searchKey.Keys += e.KeyChar;
}
searchKey.LastPress = DateTime.Now;

int index = FindString(searchKey.Keys);
Console.WriteLine("Searching for {0}, {1}", searchKey.Keys, index);
if ( index > -1 ) {
SelectedIndex = index;
}
}

public struct AutoKeySearch {
public DateTime LastPress;
public string Keys;
}
}

public class AutoListBoxForm : Form {
private AutoListBox alb = new AutoListBox();

public AutoListBoxForm() {
this.alb.Dock = DockStyle.Fill;
this.alb.Items.AddRange(new string[] {
"a", "b", "c", "d", "e",
"aa", "bb", "cc", "dd", "ee",
"foot", "football" });
this.Controls.Add(alb);
}
}

public class Tester {
[STAThread()]
private static void Main(string[] args) {
Application.Run(new AutoListBoxForm());
}
}
 
S

Stephan Steiner

I think I got the logic down now. I've also added the default sound in case
the search yields no result, just as in Windows Explorer.

If anybody is interested in having a searchable listbox that should live up
to what you can expect from Windows Explorer (obviously without all the
other bells and whistles explorer offers), let me know and I'll send it to
you.

Regards
Stephan
Justin Rogers said:
Sorry it took me a bit of a while to get around to this, but I think this may
help

using System;
using System.Windows.Forms;

public class AutoListBox : ListBox {
private AutoKeySearch searchKey;

public AutoListBox() : base() { }

protected override void OnKeyDown(KeyEventArgs e) { e.Handled = true; }
protected override void OnKeyUp(KeyEventArgs e) { e.Handled = true; }

protected override void OnKeyPress(KeyPressEventArgs e) {
e.Handled = true;

if ( searchKey.Keys == null || searchKey.LastPress.AddSeconds(1) <
DateTime.Now ) {
searchKey.Keys = new string(e.KeyChar, 1);
} else {
searchKey.Keys += e.KeyChar;
}
searchKey.LastPress = DateTime.Now;

int index = FindString(searchKey.Keys);
Console.WriteLine("Searching for {0}, {1}", searchKey.Keys, index);
if ( index > -1 ) {
SelectedIndex = index;
}
}

public struct AutoKeySearch {
public DateTime LastPress;
public string Keys;
}
}

public class AutoListBoxForm : Form {
private AutoListBox alb = new AutoListBox();

public AutoListBoxForm() {
this.alb.Dock = DockStyle.Fill;
this.alb.Items.AddRange(new string[] {
"a", "b", "c", "d", "e",
"aa", "bb", "cc", "dd", "ee",
"foot", "football" });
this.Controls.Add(alb);
}
}

public class Tester {
[STAThread()]
private static void Main(string[] args) {
Application.Run(new AutoListBoxForm());
}
}
 
J

Justin Rogers

Stephan, besides the sound, the only other logic I can think of is a search miss
for single character repeats. For instance:

f-f, really fast may yield the second word starting with f... How this works in
nested scenarios.

f-a-a, does that grab the second word starting with fa? Again, these are just
thoughts, without an attempt to care about what the Windows Explorer does,
but rather make the most functional UI from the user's perspective, even if
they do have to retrain themselves a little bit.


--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

Stephan Steiner said:
I think I got the logic down now. I've also added the default sound in case
the search yields no result, just as in Windows Explorer.

If anybody is interested in having a searchable listbox that should live up
to what you can expect from Windows Explorer (obviously without all the
other bells and whistles explorer offers), let me know and I'll send it to
you.

Regards
Stephan
Justin Rogers said:
Sorry it took me a bit of a while to get around to this, but I think this may
help

using System;
using System.Windows.Forms;

public class AutoListBox : ListBox {
private AutoKeySearch searchKey;

public AutoListBox() : base() { }

protected override void OnKeyDown(KeyEventArgs e) { e.Handled = true; }
protected override void OnKeyUp(KeyEventArgs e) { e.Handled = true; }

protected override void OnKeyPress(KeyPressEventArgs e) {
e.Handled = true;

if ( searchKey.Keys == null || searchKey.LastPress.AddSeconds(1) <
DateTime.Now ) {
searchKey.Keys = new string(e.KeyChar, 1);
} else {
searchKey.Keys += e.KeyChar;
}
searchKey.LastPress = DateTime.Now;

int index = FindString(searchKey.Keys);
Console.WriteLine("Searching for {0}, {1}", searchKey.Keys, index);
if ( index > -1 ) {
SelectedIndex = index;
}
}

public struct AutoKeySearch {
public DateTime LastPress;
public string Keys;
}
}

public class AutoListBoxForm : Form {
private AutoListBox alb = new AutoListBox();

public AutoListBoxForm() {
this.alb.Dock = DockStyle.Fill;
this.alb.Items.AddRange(new string[] {
"a", "b", "c", "d", "e",
"aa", "bb", "cc", "dd", "ee",
"foot", "football" });
this.Controls.Add(alb);
}
}

public class Tester {
[STAThread()]
private static void Main(string[] args) {
Application.Run(new AutoListBoxForm());
}
}


--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

Stephan Steiner said:
I was afraid to hear that

If anybody has an example of a similar operation that I could use as
inspiration for my own quest, please let me know.

Regards
Stephan

I think you'd have to code that particular item... There are methods
for FindString and FindStringExact that might help. You'll have to
process these in response to a key message override along with
some timing logic for when the last key was pressed to decide
if you want to build the string or start anew.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top