Autocomplete combobox

Discussion in 'Microsoft Dot NET Framework Forms' started by Simon Harvey, Apr 14, 2009.

  1. Simon Harvey

    Simon Harvey Guest

    Hi Guys,

    I have a small problem with the Windows Forms Combobox control.

    I need to allow it to have its Autocomplete behaviour enabled so that
    the user can type in items and have the combo suggest values. This works
    fine apart from the fact that it allows the user to add entirely new
    items to the list - which causes validation problems later on.

    Essentially what I would like is for the combobox to work exactly as it
    does now, with the exception that if the user presses a key that would
    mean that the new text would no longer represent a valid item in the
    list - the control should just totally ignore the key press. It should
    be as though the user hadn't pressed the key at all.

    I've created a class that inherits from the Windows Forms combobox class
    and that all works fine - I just can't figure out what to do from there.
    I've tried handling things like the TextChanged event and KeyDown event
    but I haven't been able to figure out how to get the correct effect.

    Does anyone have an example of how to do this? I'm sure it must be very
    simple, but I've never really inherited from an existing control.

    Any help would be much appreciated

    Many thanks in advance

    S
     
    Simon Harvey, Apr 14, 2009
    #1
    1. Advertisements

  2. Simon Harvey

    Mel Weaver Guest

    Change it to a drop down list


    "Simon Harvey" <> wrote in message
    news:%...
    > Hi Guys,
    >
    > I have a small problem with the Windows Forms Combobox control.
    >
    > I need to allow it to have its Autocomplete behaviour enabled so that the
    > user can type in items and have the combo suggest values. This works fine
    > apart from the fact that it allows the user to add entirely new items to
    > the list - which causes validation problems later on.
    >
    > Essentially what I would like is for the combobox to work exactly as it
    > does now, with the exception that if the user presses a key that would
    > mean that the new text would no longer represent a valid item in the
    > list - the control should just totally ignore the key press. It should be
    > as though the user hadn't pressed the key at all.
    >
    > I've created a class that inherits from the Windows Forms combobox class
    > and that all works fine - I just can't figure out what to do from there.
    > I've tried handling things like the TextChanged event and KeyDown event
    > but I haven't been able to figure out how to get the correct effect.
    >
    > Does anyone have an example of how to do this? I'm sure it must be very
    > simple, but I've never really inherited from an existing control.
    >
    > Any help would be much appreciated
    >
    > Many thanks in advance
    >
    > S
     
    Mel Weaver, Apr 14, 2009
    #2
    1. Advertisements

  3. Simon Harvey

    Simon Harvey Guest

    Hi Mel,

    Thats doesn't actually solve the issue because it prevents the user from
    typing into the combobox.

    Don't ask me why, but the client wants to be able to type into the list
    but be restricted to only those items in the list

    Many thanks

    Simon

    Mel Weaver wrote:
    > Change it to a drop down list
    >
    >
    > "Simon Harvey" <> wrote in message
    > news:%...
    >> Hi Guys,
    >>
    >> I have a small problem with the Windows Forms Combobox control.
    >>
    >> I need to allow it to have its Autocomplete behaviour enabled so that the
    >> user can type in items and have the combo suggest values. This works fine
    >> apart from the fact that it allows the user to add entirely new items to
    >> the list - which causes validation problems later on.
    >>
    >> Essentially what I would like is for the combobox to work exactly as it
    >> does now, with the exception that if the user presses a key that would
    >> mean that the new text would no longer represent a valid item in the
    >> list - the control should just totally ignore the key press. It should be
    >> as though the user hadn't pressed the key at all.
    >>
    >> I've created a class that inherits from the Windows Forms combobox class
    >> and that all works fine - I just can't figure out what to do from there.
    >> I've tried handling things like the TextChanged event and KeyDown event
    >> but I haven't been able to figure out how to get the correct effect.
    >>
    >> Does anyone have an example of how to do this? I'm sure it must be very
    >> simple, but I've never really inherited from an existing control.
    >>
    >> Any help would be much appreciated
    >>
    >> Many thanks in advance
    >>
    >> S

    >
    >
     
    Simon Harvey, Apr 15, 2009
    #3
  4. Hi Simon,

    Why not simply check it using the method findstring in the textchanged event

    http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.findstring(VS.71).aspx

    Cor

    "Simon Harvey" <> wrote in message
    news:%...
    > Hi Guys,
    >
    > I have a small problem with the Windows Forms Combobox control.
    >
    > I need to allow it to have its Autocomplete behaviour enabled so that the
    > user can type in items and have the combo suggest values. This works fine
    > apart from the fact that it allows the user to add entirely new items to
    > the list - which causes validation problems later on.
    >
    > Essentially what I would like is for the combobox to work exactly as it
    > does now, with the exception that if the user presses a key that would
    > mean that the new text would no longer represent a valid item in the
    > list - the control should just totally ignore the key press. It should be
    > as though the user hadn't pressed the key at all.
    >
    > I've created a class that inherits from the Windows Forms combobox class
    > and that all works fine - I just can't figure out what to do from there.
    > I've tried handling things like the TextChanged event and KeyDown event
    > but I haven't been able to figure out how to get the correct effect.
    >
    > Does anyone have an example of how to do this? I'm sure it must be very
    > simple, but I've never really inherited from an existing control.
    >
    > Any help would be much appreciated
    >
    > Many thanks in advance
    >
    > S
     
    Cor Ligthert[MVP], Apr 15, 2009
    #4
  5. Simon Harvey

    Simon Harvey Guest

    Hi Cor,

    Thanks very much for your answer.

    Hmm - I'm not quite sure how it would work. I've been trying to do
    something whereby I handle the key press event and detect if the user is
    about to enter a character that would be invalid.

    I can stop the user from entering the bogus character, but unfortunately
    something I'm doing seems to prevent the remainder of the text of the
    target item from remaining selected. I'm doing it in the KeyPress event
    and whatever I'm doing to prevent the users keypress from continuing
    seems to be interfering with the normal autocomplete behaviour of the
    control because when I kill the users action, the control immediately
    deselects the users text - which in effect kills the autocomplete behaviour.

    Sorry I hope that makes sense. I've copied the code of my control below
    just in case it helps. I'm really close to getting it to work - I just
    need to figure out how to stop my code from interfering with the
    autocomplete part that the control does itself.... :-(


    Thanks again for your thoughts

    S

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace AutoCompleteCombo {

    public class CustomCombobox: ComboBox {

    public CustomCombobox()
    : base() {
    }

    protected override void OnKeyPress(KeyPressEventArgs e) {
    string startOfText = null;
    string proposedComboValue = null;

    Console.Out.WriteLine(e.KeyChar.ToString());

    // If the character entered by the user is not a valid
    number/letter/symbol etc, we don't want to bother with our masking
    // logic as the user is probably just pressing the
    delete/backspace key or something similar
    if (Char.IsLetterOrDigit(e.KeyChar) == false &&
    Char.IsPunctuation(e.KeyChar) == false && Char.IsSymbol(e.KeyChar) ==
    false) {
    base.OnKeyPress(e);

    return;

    }

    # region [-- Determine Proposed Value --]

    startOfText = this.Text.Substring(0, this.SelectionStart);

    Console.Out.WriteLine("Start Value: " + startOfText);

    // If the character that the user has just provided would
    create a string that doesn't exist in our list of items, we need
    // to prevent the key press from continuing

    proposedComboValue = startOfText +
    e.KeyChar.ToString().ToLower();
    Console.Out.WriteLine("Proposed Value: " + proposedComboValue);

    # endregion

    # region [-- Determine if Proposed Value Is Valid --]

    foreach (object currentListItem in this.Items) {

    // If we find at least one item in the list that starts
    with the proposed text, we know that the user should be allowed
    // to continue with what they've done
    if
    (currentListItem.ToString().ToLower().StartsWith(proposedComboValue) ==
    true) {
    base.OnKeyPress(e);

    Console.Out.WriteLine("Value is in the list");

    return;

    }

    }

    # endregion


    // If we reach here it means that the user has attempted to
    add a character that would mean that the text entered in the combo
    // no longer represents a valid list item.
    Console.Out.WriteLine("Value is NOT in the list");

    // Prevent the KeyPressEvent from continuing by marking the
    event as "handled"
    e.Handled = true;

    }

    private string FindFirstMatchingItem(string targetText) {
    string result = null;

    foreach (object currentItem in this.Items) {

    if
    (currentItem.ToString().ToLower().StartsWith(targetText) == true) {
    return currentItem.ToString();
    }

    }

    return result;
    }

    }

    }


    Cor Ligthert[MVP] wrote:
    > Hi Simon,
    >
    > Why not simply check it using the method findstring in the textchanged
    > event
    >
    > http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.findstring(VS.71).aspx
    >
    >
    > Cor
    >
    > "Simon Harvey" <> wrote in message
    > news:%...
    >> Hi Guys,
    >>
    >> I have a small problem with the Windows Forms Combobox control.
    >>
    >> I need to allow it to have its Autocomplete behaviour enabled so that
    >> the user can type in items and have the combo suggest values. This
    >> works fine apart from the fact that it allows the user to add entirely
    >> new items to the list - which causes validation problems later on.
    >>
    >> Essentially what I would like is for the combobox to work exactly as
    >> it does now, with the exception that if the user presses a key that
    >> would mean that the new text would no longer represent a valid item in
    >> the list - the control should just totally ignore the key press. It
    >> should be as though the user hadn't pressed the key at all.
    >>
    >> I've created a class that inherits from the Windows Forms combobox
    >> class and that all works fine - I just can't figure out what to do
    >> from there. I've tried handling things like the TextChanged event and
    >> KeyDown event but I haven't been able to figure out how to get the
    >> correct effect.
    >>
    >> Does anyone have an example of how to do this? I'm sure it must be
    >> very simple, but I've never really inherited from an existing control.
    >>
    >> Any help would be much appreciated
    >>
    >> Many thanks in advance
    >>
    >> S

    >
     
    Simon Harvey, Apr 15, 2009
    #5
  6. Simon,

    http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/msg/cb2df568c7b5c0c6

    I hope this helps, I did it never this way but it should go

    Cor

    "Simon Harvey" <> wrote in message
    news:...
    > Hi Cor,
    >
    > Thanks very much for your answer.
    >
    > Hmm - I'm not quite sure how it would work. I've been trying to do
    > something whereby I handle the key press event and detect if the user is
    > about to enter a character that would be invalid.
    >
    > I can stop the user from entering the bogus character, but unfortunately
    > something I'm doing seems to prevent the remainder of the text of the
    > target item from remaining selected. I'm doing it in the KeyPress event
    > and whatever I'm doing to prevent the users keypress from continuing seems
    > to be interfering with the normal autocomplete behaviour of the control
    > because when I kill the users action, the control immediately deselects
    > the users text - which in effect kills the autocomplete behaviour.
    >
    > Sorry I hope that makes sense. I've copied the code of my control below
    > just in case it helps. I'm really close to getting it to work - I just
    > need to figure out how to stop my code from interfering with the
    > autocomplete part that the control does itself.... :-(
    >
    >
    > Thanks again for your thoughts
    >
    > S
    >
    > using System;
    > using System.Collections.Generic;
    > using System.Linq;
    > using System.Text;
    > using System.Windows.Forms;
    >
    > namespace AutoCompleteCombo {
    >
    > public class CustomCombobox: ComboBox {
    >
    > public CustomCombobox()
    > : base() {
    > }
    >
    > protected override void OnKeyPress(KeyPressEventArgs e) {
    > string startOfText = null;
    > string proposedComboValue = null;
    >
    > Console.Out.WriteLine(e.KeyChar.ToString());
    >
    > // If the character entered by the user is not a valid
    > number/letter/symbol etc, we don't want to bother with our masking
    > // logic as the user is probably just pressing the
    > delete/backspace key or something similar
    > if (Char.IsLetterOrDigit(e.KeyChar) == false &&
    > Char.IsPunctuation(e.KeyChar) == false && Char.IsSymbol(e.KeyChar) ==
    > false) {
    > base.OnKeyPress(e);
    >
    > return;
    >
    > }
    >
    > # region [-- Determine Proposed Value --]
    >
    > startOfText = this.Text.Substring(0, this.SelectionStart);
    >
    > Console.Out.WriteLine("Start Value: " + startOfText);
    >
    > // If the character that the user has just provided would
    > create a string that doesn't exist in our list of items, we need
    > // to prevent the key press from continuing
    >
    > proposedComboValue = startOfText +
    > e.KeyChar.ToString().ToLower();
    > Console.Out.WriteLine("Proposed Value: " +
    > proposedComboValue);
    >
    > # endregion
    >
    > # region [-- Determine if Proposed Value Is Valid --]
    >
    > foreach (object currentListItem in this.Items) {
    >
    > // If we find at least one item in the list that starts
    > with the proposed text, we know that the user should be allowed
    > // to continue with what they've done
    > if
    > (currentListItem.ToString().ToLower().StartsWith(proposedComboValue) ==
    > true) {
    > base.OnKeyPress(e);
    >
    > Console.Out.WriteLine("Value is in the list");
    >
    > return;
    >
    > }
    >
    > }
    >
    > # endregion
    >
    >
    > // If we reach here it means that the user has attempted to
    > add a character that would mean that the text entered in the combo
    > // no longer represents a valid list item.
    > Console.Out.WriteLine("Value is NOT in the list");
    >
    > // Prevent the KeyPressEvent from continuing by marking the
    > event as "handled"
    > e.Handled = true;
    >
    > }
    >
    > private string FindFirstMatchingItem(string targetText) {
    > string result = null;
    >
    > foreach (object currentItem in this.Items) {
    >
    > if
    > (currentItem.ToString().ToLower().StartsWith(targetText) == true) {
    > return currentItem.ToString();
    > }
    >
    > }
    >
    > return result;
    > }
    >
    > }
    >
    > }
    >
    >
    > Cor Ligthert[MVP] wrote:
    >> Hi Simon,
    >>
    >> Why not simply check it using the method findstring in the textchanged
    >> event
    >>
    >> http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.findstring(VS.71).aspx
    >> Cor
    >>
    >> "Simon Harvey" <> wrote in message
    >> news:%...
    >>> Hi Guys,
    >>>
    >>> I have a small problem with the Windows Forms Combobox control.
    >>>
    >>> I need to allow it to have its Autocomplete behaviour enabled so that
    >>> the user can type in items and have the combo suggest values. This works
    >>> fine apart from the fact that it allows the user to add entirely new
    >>> items to the list - which causes validation problems later on.
    >>>
    >>> Essentially what I would like is for the combobox to work exactly as it
    >>> does now, with the exception that if the user presses a key that would
    >>> mean that the new text would no longer represent a valid item in the
    >>> list - the control should just totally ignore the key press. It should
    >>> be as though the user hadn't pressed the key at all.
    >>>
    >>> I've created a class that inherits from the Windows Forms combobox class
    >>> and that all works fine - I just can't figure out what to do from there.
    >>> I've tried handling things like the TextChanged event and KeyDown event
    >>> but I haven't been able to figure out how to get the correct effect.
    >>>
    >>> Does anyone have an example of how to do this? I'm sure it must be very
    >>> simple, but I've never really inherited from an existing control.
    >>>
    >>> Any help would be much appreciated
    >>>
    >>> Many thanks in advance
    >>>
    >>> S

    >>
     
    Cor Ligthert[MVP], Apr 15, 2009
    #6
  7. Simon Harvey

    Simon Harvey Guest

    Hi Cor

    Thanks for that. I am using the handled event but unfortunately it seems
    to interfere with the autocomplete functionailty in that it deselects
    all the text in the control when the user enters an invalid character.

    I just need to figure out why doing e.handled = true deselects the text
    in the control cos I really wish it didn't!

    Thanks agaain though

    S
     
    Simon Harvey, Apr 15, 2009
    #7
    1. Advertisements

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page