Hi,
Can you please tell me the conditions under which the EditValue of a WPF TextEdit can be updated? Does the control need to have focus in order for the two way binding to work?
I have a grid control that is bound to a viewmodel that is populated using the entityframework.
As there are issues using the touch keyboard in WPF on a Surface Pro tablet, I am trying to use the Virtual Keyboard provided by James Hurst (https://jhvirtualkeyboard.codeplex.com/). This involves setting the EditValue of the TextEdit (actually a derived class of this) that is created internally for the GridColumn.
Whenever I set EditValue, the text is visible in the control on the screen. But when I click on another row and then back onto the edited column cell, the value returns to the original value.
I think this maybe due to the fact that the Virtual Keyboard takes over focus when typing? When the cell is clicked/touched, the virtual keyboard is opened and it's current target is set to the cell in question. Once you start typing on the keyboard, the focus transfers away from the cell and onto the keyboard. The keyboard then calls an implemented interface method on the TextEdit derived class which is where I'm updating the EditValue. The Dependency Property set method does not get called and hence the Raise Property Changed method does not update the entity object.
If I don't show the virtual keyboard and just use the physical keyboard on a PC then the updates are persisted as expected. I guess this is because the control has focus and it's updated using the internal mechanism on focus lost. I did notice that the Dependency Property set method is called this way and hence the Raise Property Changed method is called. Obviously my setting of EditValue is bypassed using the physical keyboard method.
Sorry but I can't post my code. I can try and knock an example up if you really need it. I've not tried this on the tablet yet as I can't get it to work yet, so I'm trying this on a Win 7 machine.
Thanks,
John
Hi John,
I'm afraid it is not possible to work with DXGrid editors directly when they are not focused and are in display mode (not edit mode). Can you use another keyboard that doesn't take focus? Or, is it possible to modify the current keyboard to make it not take focus?
If not, there is an alternative solution. Do not set the editor's value, but use the GridControl.SetCellValue method instead. It sets cell values directly and doesn't require active editors.
Hi Alexander,
Ok, thanks for the info - I'll give that a go.
The other solutions to displaying the keyboard are to start the tabtip.exe process (which has it's issues) or to use https://code.msdn.microsoft.com/windowsapps/Enabling-Windows-8-Touch-7fb4e6de (I can't get the keyboard to show for my DevExpress WPF project).
The actual problem I'm trying to solve is to do with editing a cell in a grid control. If that cell is near the bottom row of the grid, when touched, the keyboard displays and covers the cell so you cannot see what you are typing. It doesn't seem easy to move the keyboard out of the way when using tabtip.exe. Also, when the tablet is in landscape there is not a lot of real estate between the keyboard and the header for the grid to be displayed.
Something else that I might try is to use the VisualStateManager to make WPF apps Layout Aware like Windows 8 Apps are in order to be able to 'move the page up' when the keyboard is displayed (note: I can't develop my current solution as a Windows App).
This seems to be such a difficult thing to sort out. Is this a common issue in Windows 8 WPF tablet dev? Have any other customers solved this problem? Also should the grid control display the keyboard on touch by default?
Thanks,
John
Hi John,
As for the DXGrid control, no, it shouldn't show the touch keyboard automatically. Moreover, I'm afraid WPF controls don't support this feature. As you can see in the aforementioned MSDN article, Dmitry Lyalin suggested disabling touch in an application partially to show the touch keyboard automatically. Since it is the only way to do this automatically, I suggest that you show the touch keyboard manually and modify the application layout when it is shown.
Should you have any questions regarding our controls, feel free to contact us.
Regards,
Alex
Hi Alex,
Thanks again for the info and your suggested solution.
I have been doing some more investigation why the keyboard is displayed automatically if I touch a cell in a standard WPF grid but not if I use a DevExpress grid.
The standard touch screen keyboard uses the Automation API to determine whether to display or not for the control that gets focus. These 3 properties need to be set: IsEnabled, IsKeyboardFocusable and a ValuePattern exists. I noticed that the TextBox and TextEdit both have corresponding AutomationPeer classes that set these properties correctly. I was wondering therefore what the difference was?
If I use Inspect.exe from the Windows SDK to view the properties of the Grid Cell when it has keyboard focus, the object appears to be a DataItem (a child element of the ViewModel that our Grid is bound to) and I would've expected it to be a TextEdit control. The IsKeyboardFocusable is False for this DataItem. I'm not certain how this AutomationElement info is populated as the ViewModel does not inherit from UIElement. I guess the framework must be using some default settings for it?
Interestingly if I override the OnCreateAutomationPeer for our TextEdit derived implementation class, it does get called when I touch the cell. So it's wierd why those settings are not being used.
Anyway, I guess this is because we're using MVVM? Do you know if there is any way to return a custom AutomationPeer with the required settings for a data item in the view model of a grid?
Sorry for the long winded posts and my exploration down rabbit holes but I'm still trying to get my head around what is possible and what isn't.
Thanks a lot,
John
Hello John,
If I correctly understand you, you've implemented an automatically shown touch keyboard and currently it works as expected in the standard DataGrid, but does not work in GridControl.
GridControl returns a GridRowAutomationPeer object for each row in GridControl (DataItem) and GridCellAutomationPeer for each cell in this row. Values of the properties you are interested in (IsEnabled, IsKeyboardFocusable, etc.) are taken from the GridCellAutomationPeer object. AutomationPeers created at the internal editor level are not taken into account.
At the moment we do not have plans to change this behavior, but I've informed our developers about a possible need in such implementation. We will take this information into account in the future.
I think we can try to find a suitable solution for your current task if you provide us with your current implementation of showing the touch keyboard on clicking the standard DataGrid's cell. We will research what we can do for applying your approach to our GridControl. We are looking forward to your response.
Thanks,
Andrey
Hello John,
Due to bad performance when Automation UI is used with WPF controls, the corresponding events are not used by default if you use GridControl (Bad performance because of Automation events). That is why if you add it into the window, the touch keyboard does not appear even on touch in DataGrid's cells. To disable this behavior, set the static ClearAutomationEventsHelper.IsEnabled property to False.
Wpf controls do not support opening the touch keyboard automatically by default, and the approach suggested in the article (Automatic Touch Keyboard for TextBoxes in WPF Applications on Windows 8+) is a kind of a workaround that works correctly for standard WPF controls. This approach will not work with our GridControl out of the box, and I do not see an easy way to achieve the desired functionality.
As you mentioned above, the only issue is that the value returned in the GridCellAutomationPeer.IsKeyboardFocusable method is always False. I've created GridCellAutomationPeer and overridden the IsKeyboardFocusableCore method to make it return always True, but the workaround from that article still does not work in GridControl. See the attached sample. Perhaps, there are additional requirements that should be implemented in the AutomationPeer.
Thanks,
Andrey
Hi Andrey,
Thanks for the information and the example project. I've found this other link that says for a control to be able to invoke the on-screen touch keyboard when it obtains input focus, it must have a custom automation peer that derives from FrameworkElementAutomationPeer and implements the IValueProvider and ITextProvider interfaces.
https://books.google.co.uk/books?id=Da9CAwAAQBAJ&pg=PA890&lpg=PA890&dq=ITextProvider+touch+keyboard&source=bl&ots=cNTkn2czkG&sig=PKNAIhdwATWgbsU5ZqhWaC0VZEY&hl=en&sa=X&ei=I_xSVb-RK8Ou7Abns4HgDg&ved=0CEYQ6AEwBg#v=onepage&q=ITextProvider%20touch%20keyboard&f=false
I see that GridCellAutomationPeer does not derive from FrameworkElementAutomationPeer and I'm unsure how I can adapt it to test if it gives us what we want. Anyway, I thought I'd provide this link to you in case that here is something that your developers can do for future versions.
I think we've exhausted all possiilities on this, so will probably launch the tabtip.exe process in order to show the keyboard.
I'll let you know on my work account if we manage to come up with a better solution.
Thanks very much for you help.
John
Hello John,
Thank you for additional information. Since WPF controls do not support such a functionality out of the box, we cannot provide you with a working approach for GridControl. Even if the workaround suggested in the first link works for GridControl, its usage is not a good way, since it has some side effects like switching off scrolling in the grid.
Our developers will research this question in the future, and perhaps we will find a way to automatically open the on-screen touch keyboard when a cell editor is opened. Stay tuned to our announcements.
Please do not hesitate to contact us if you have any further difficulties with this. We are always happy to assist you, John!
Thanks,
Andrey