2

I am developing an application in VB.NET, but the answer could be C#-based also. My problem is: I have a combobox for filtering some data and I am required to implement the search suggestions based on what was previously written (like the Google search bar). If the user inserts the filtering criteria from the pyshical keyboard everything is fine (as I set the AutoCompleteMode on Suggest and the AutoCompleteSource on ListItems). But the application I am working on also provides the user a numerical on-screen keyboard, something like this:

enter image description here

If any code sample is needed, I'll provide, but the functionality of the keyboard is simple: take the written text, append the last pressed key, overwrite the textbox with the new, appended text. So far, when the user inserts input from this on-screen keyboard, the suggestions are not displayed anymore. Is there any way to achieve the same behaviour with the on-screen keyboard, just like it does with the physical one? Thanks, have a nice day!

Edit: here is the code for the way the keypad works:

Private Sub AppendKey (ByVal key As String)
    Dim str1 As String = cboFilter.Text
    str1 = str1 & key 
    cboFilter.Text = str1
    cboFilter.Focus()
    cboFilter.SelectionStart = cboFilter.Text.Length 
End Sub 
Gabriel Stancu
  • 940
  • 2
  • 13
  • 26
  • *"suggestions are not displayed anymore"* - it looks like you need to help to fix your code, but you forgot to show one. See also [mcve]. – Sinatr Jul 02 '20 at 12:51
  • What do you mean? I don't need any help with "my code", as the keyboard is working as it is intended, just like the rest of the program. My problem is that it seems the suggestions appear only when the physical keyboard is used and I can't find the reason for it does not show suggestions for the on-screen keyboard also... – Gabriel Stancu Jul 02 '20 at 13:23
  • How can I reproduce issue on my PC? Step by step? I just tried to use OSK with Chrome and I see suggestions while using OSK, no problems. – Sinatr Jul 02 '20 at 13:52
  • Is that "MainWindow" OSK part of the same application as the ComboBox?...and you control the code for it? – Idle_Mind Jul 02 '20 at 14:11
  • 2
    Quick though: When a key is pressed in your OSK, switch focus to the ComboBox, use `SendKeys.Send()`, then switch back to your OSK? – Idle_Mind Jul 02 '20 at 14:21
  • 1
    Can you show your OSK without stealing the focus from the selected Control? A ComboBox will close its DropDown if it loses focus. You can use `SendKeys.SendWait()` to append chars, but the focus must stay on the recipient. If you use `SendKeys.Send()` and your switch the focus back to your TextBox, you may have a nasty surprise... – Jimi Jul 02 '20 at 15:37
  • If the OSK is a separate app (that you wrote) you can use the WS_EX_NOACTIVATE flag to display it without stealing focus. – Idle_Mind Jul 02 '20 at 22:41
  • @Idle_Mind Yes the osk is part of the same window as the combobox and I can control both. Will try the SendKeys.Send approach and will come back with results. I just usually avoid this approach as some unintended behavior might occur, but as a last option I'll try this. – Gabriel Stancu Jul 02 '20 at 23:04
  • @Jimi so, in other words, the reason for the physical keyboard does not make the combobox lose focus is because it never switches the control, as in the second case, when pressing a button (even on the same window) will definitely make it lose focus? I thought about that but was not quite sure about it... – Gabriel Stancu Jul 02 '20 at 23:06
  • @Sinatr It's not the osk provided by windows, not used in the Chrome or Google. It is a custom keypad inside my application. – Gabriel Stancu Jul 02 '20 at 23:07
  • 1
    Yes, you must set/send chars/keys to that ComboBox without stealing the focus from it. When you do, it'll work. As already mentioned, be careful when you use SendKeys: never move the focus right after, or you'll unleash hell on earth. For the Buttons, you can use Custom Controls (derived from Button), setting `SetStyle(ControlStyles.Selectable, false);` in their constructor, so you won't steal the focus from your TextBox when a Button is clicked. – Jimi Jul 02 '20 at 23:08
  • @Jimi The problem with this approach is that the keypad is WIDELY used over the entire application, which is quite huge as well, so I don't think changing that part would be a great idea taking the application as a whole, unless I misunderstood your suggestion. – Gabriel Stancu Jul 02 '20 at 23:13
  • 1
    I don't know to which part you're referring to. If it's about the Buttons, then I assume it's already working like that or the Keypad *screen* part is not a TextBox but a Label (or the text is painted or whatever), otherwise, you'd steal the focus from the TextBox each time a Button is clicked. But, I have no idea how that keypad works, you haven't posted any code related to its behavior. What's sure is that a ComboBox, when loses focus, closes its DropDown. That's what you need to avoid. Usually, virtual keyboards already do that, leave the focus on the active control. – Jimi Jul 02 '20 at 23:22
  • @Jimi I made an edit with the code for the keypad functionality. The Sub is called by each button with the key associated to it (I know an enum would have been better than sending a string as argument but the keypad was not made by me, and as I said, changing anything about it would be bad since it is used in a lot of places over the application). – Gabriel Stancu Jul 03 '20 at 07:58
  • @Jimi It works now thanks to your suggestion. If you want to post your suggestion as answer or anything, I'll mark it as the solution. Thanks for your help and patience, have a nice day! – Gabriel Stancu Jul 03 '20 at 08:16

1 Answers1

2

As suggested by Jimi, I will post the solution I found here as an answer, in case somebody else lands on this issue as well. In case the keypad is used for this particular combobox, I added a call to the following new created Sub in the provided Sub:

Private Sub AppendKey (ByVal key As String)
    If currentCbo = cboFilter Then 
        'currentCbo holds the currently editting combobox'
        AppendKeyInFilterCbo(key)
    Else 
        'The normal behaviour for the other comboboxes'
        Dim str1 As String = currentCbo.Text
        str1 = str1 & key 
        currentCbo.Text = str1
        currentCbo.Focus()
        currentCbo.SelectionStart = currentCbo.Text.Length 
    End If 
End Sub 

Private Sub AppendKeyInFilterCbo (ByVal key As String)
    cboFilter.Focus()
    cboFilter.SelectionStart = cboFilter.Text.Length
    SendKeys.Send("{" + key + "}")
End Sub 

This behaviour was needed only for the filter combobox because it is the only one where suggestions make sense for the user.

Gabriel Stancu
  • 940
  • 2
  • 13
  • 26
  • If you haven't done it already, add `` in the `` section of your `app.config` file. It works much better (if uses the `SendInput()` Win32 function) – Jimi Jul 15 '20 at 05:43
  • Thanks for the suggestion, will take it into consideration next time I encounter or I am assigned a task on this part of the program. – Gabriel Stancu Jul 15 '20 at 07:20