In WPF how can I duplicate the old WinForms OnKeyPressed functionality? - wpf

We have a WPF application where we need to detect if the user is typing something that can appear in a textbox. WinForms used to have a nice OnKeyPressed override that differed from OnKeyDown in that it was only called when a printable character was typed (e.g. it differentiated between 'A' and 'a' but not between the '1' on the top row vs. the numeric keypad. It also ignored keys like 'Shift', etc.) We need to duplicate that functionality in WPF.
Now I know I can override OnKeyDown and inspect the keycode, but that means manually testing for every possible key that would result in something appearing in a textbox. That seems to be the consensus from the other similar SO questions that I've found, but I just can't believe something so basic would be left out of the API.
Asides from a monster if-tree, one 'hacky' solution is to use an in-memory textbox, pass the keycode to it, then inspect if the text has a length. But I'm getting nauseous even typing that as a possible solution! UGH!! I feel dirty!
SO... what's the easiest way to tell if a user pressed a key or keys that will result in a printable character?
TIA,
Mark

Actually, I think I just found it so I'm posting the answers for others. You don't use any 'Key' events at all. WPF more clearly separates those out from the textual values. As such, you override the OnPreviewTextInput and/or OnTextInput functions. To get what was actually typed, check the .Text property on the event args which returns a simple string.
Done and done!
Hope this helps others! Been driving me up a wall!

Related

NVDA and JAWS reading order using React

When using NVDA on Firefox, it reads in row-wise order in React. How can I change the reading order?
Sample code:
<Row1>
<row-item-left>{some content1-left}</row-item-left>
<row-item-right>{some content1-right}</row-item-right>
<Row1>
<Row2>
<row-item-left>{some content2-left}</row-item-left>
<row-item-right>{some content2-right}</row-item-right>
<Row2>
Now it reads, "some content1-left, some content1-right, some content2-left, and some content2-right." I want it to read, "some content1-left, some content2-left, some content1-right," and, "some content2-right."
I use tabindex. It's working fine with tabs, but I don't want to focus elements Also it's not working with arrow keys. Please help me on this.
The reading order is always the same as it appears in the accessibility tree, and the accessibility tree is built from the DOM.
This basic rule can't be changed. CSS has no effect on reading order.
So if you want the content to be read column by column instead of row by row, you have no choice but rearrange your code so that it appears in the right order in the source:
<row-item-left>{some content1-left}</row-item-left> 
<row-item-left>{some content2-left}</row-item-left> 
<row-item-right>{some content1-right}</row-item-right> 
<row-item-right>{some content2-right}</row-item-right> 
I leave CSS experts tell you how you can achieve it.
Firstly accessibility isn't about what you want, never try to change expected behaviour.
When using a screen reader it is expected that items flow from left to right, top to bottom in 99% of cases (the way you would read the page normally).
The idea is that a screen reader user gets the same experience as someone who does not need to use one.
With regards to focus, never interfere with that either if it is something that is interactive (a clickable cell, link etc.).
If something is focusable it should also have a distinctive border (this helps users who use tab to navigate due to mobility issues know where their current cursor is placed on your site.) - just an extra tip, not relevant to your question.
The current read order is correct, do not interfere with it.
With regards to using arrow keys that may be useful, just use JavaScript to intercept the key presses and move focus accordingly (give that a go and post another question with a code example if you get stuck.)
Bear in mind you should also provide a way for people to disable this arrow key behaviour as they may have changed the key bindings on their screen reader and that would cause accessibility issues if your JavaScript interferes with their preferred key bindings.
I am not sure why you said you don't want to focus the element, if your custom HTML elements have focus in the first place then adjust those elements (as you must have added a tabindex=0 or some JS to those elements in the first place to make them focusable as <divs> are not focusable by default.)

How to determine if WPF TextBox is dirty (when using UpdateSourceTrigger=LostFocus)

How can I determine when a user has updated the text in a textbox before the Binding has updated the source?
I was expecting to find an "IsDirty" property on either the TextBox or the Binding ...
My problem is that the "Cancel" button Enabled property is bound to the ViewModel's IsDirty property and is disabled until the focus moves out of the textbox.
"IsDirty" needs to be defined as ViewModel.IsDirty || TextBox.IsDirty
WPF can't support the typical IsDirty behaviour that users would expect in a high quality application.
The problem stems from the strange design of the Binder class.
Furthermore WPF architecture is kind of hard-coded to using the default Binder implementation, replacing it is a huge job and requires many "dirty tricks" to work around the endless WPF design flaws.
The easiest way I found to workaround this limitation is to move all value conversion logic to the view model and use UpdateSourceTrigger=PropertyChanged, and implement your own IsDirty and IsInvalid logic and flags.
This approach also plays nicely with Caliburn.Micro
First, why is Cancel disabled? It should be enabled all the time. Any other behavior would be odd. The user should be able to cancel although he hasn't done anything.
Second, I would use Commands so that it can determine whether it can be executed or not based on the state of the viewmodel. Should be easy to implement, if the viewmodel also provide the implementation of the command.
I'd recommend to read some articles and/or tutorials about it. Google for the interface ICommand.
And to answer your question. Assuming you're using binding you could use the INotifyPropertyChanging interface to determine when a value is about to change. You could then store the current value in a backup field or something.
EDIT - Regarding "let him lose data"
Sure it's a valid strategy. Think on a larger input dialog e.g. 5 input controls, which must be validated before persisting the input. I'm assuming that the data is very important according to your arguments. Furthermore, you started to hack your data into the dialog. On input control 3 you decide to press 'ALT + F4'.
First, ask yourself, why did the user press the keys? IMHO he doesn't care about what's happening to his data.
If 'ALT + F4' is just an example for being robust. Forget about it. I think absolute robustness cannot be implemented without being very expensive.
Second, regarding consistency and validity after the restart of the application, you have to throw the data away so that you don't start with an undefined state. Remember, the entity the user began to fill is not valid at this state. Neither the states respectively the values of the properties are.
So IMHO the much better strategy is to restart with a clean and defined state, so that the user is able to continue with whatever you want him to do with your application.
Why is this strategy better? Well, it's much easier to implement. And the much more important argument, the user never gets lost because of an odd state.

WPFToolkit RichTextBox - Update text color on typing

I'm using the WPFToolkit RichTextBox in order to allow the user to view and edit text.
One of the things I need to support is the coloring of specific words as they are being typed, as well as when loading them from an pre-existing source.
For example if the user type the word - "Hello" it should be colored in blue.
Since I'm using MVVM I would like to avoid code behind as much as possible.
So far I've been trying handling this in the ViewModel with a custom TextFormatter however it helped only when the I update the source property and when I updated the RichTextBox directly it didn't color anything as the TextFormatter's SetText wasn't even called. Only SetText was called.
I hope you guys could help me out.
Thanks!
In the end I used the solution I found in here -
http://blogs.microsoft.co.il/blogs/tamir/archive/2006/12/14/RichTextBox-syntax-highlighting.aspx
It's doing its job, but it sometimes has minor hiccups when typing fast or when holding the backspace.
So for now its good enough since my RichTextBox is relatively small.
Though if anyone knows how to fix the hiccups, it would be really great!
EDIT: I found a way to really improve the hiccups. I used a DispatcherTimer and started it on the TextChanged event, that way only after a second/half a second, it would start the coloring logic. So far it works much faster, and I didn't notice any problems when typing quickly. So for my needs of a single row with colored words, it seems like it worked!

WPF ComboBox history - Looking for implementation suggestion

Im looking forward to writing a combobox with history. Much like address bar, only simpler(no searching, use history only). Since this is quite common, i think maybe there is a library or anything on it. I dont want to write the system from scratch(which ive been doing anyway until i realize its too much work for simple unrequired feature).
So, my question is, how can i have a combobox that can save information that user entered, manage the information that the user entered(delete, rank up/down etc).
Thanks.
i think one solution could be to define an object with hold the entered information and other information like delete command, rank value. then put this object in a observablecollection, use it as the combobox itemsource and whenever a user put something in your comboxbox update your collection in the way you want.

What is a good way to indicate a field is mandatory?

I would like to indicate to the user that a particular textbox or combobox is mandatory. What is a neat way to do this?
Currently, I have a gradient red border around the textbox when the text is null or empty, but it seems a bit much when you show a form and a number of the fields are red. I'm looking for something that is clear, but is not so overwhelming to the user. Something subtle.
I would prefer to make the textbox indicate that the field is mandatory rather than say make the label bold or have an asterisk. What are my options or any ideas you might have.
A recent usability study suggests taking the opposite approach and indicating which fields are optional rather than required. Furthermore, try to ask for only what you really need in order to reduce the number of optional fields.
The reason is that users tend to assume all fields are required anyway. They may not understand or pay attention to the asterisk, whereas they readily understand clearly labeled optional fields.
Link to the study (see Guideline 5):
https://www.cxpartners.co.uk/our-thinking/web_forms_design_guidelines_an_eyetracking_study/
Just put a * in front on the mandatory fields. It's simple, yet effective. I think most people will know what this means. Also, when they try to submit and it fails, because some mandatory field was not filled in correctly, then you let the user know which field they need to change (by using those red borders, for instance). I think this is what most people are accustomed to.
Edit: I saw that you didn't want to use an asterisk by the way. I still think this is the best option, simply because I think most people will recognize it right away and know what to do :)
I do it this way. Mark the left-border of the element with 2px Red color.
you can also change background color of textbox..
It depends on your design, of course, but I prefer something simpler like the labels of the input being bold. The red outline, while clear, does have an "error" connotation associated with it, which might be misleading to the user. Bolding the labels is subtle, but easy to understand without being an eyesore.
I like the jquery 'example' plugin for text input fields. A subtle grey inlay for instructions or sample input.
See demo page here for an, ahem, example. http://mucur.name/system/jquery_example/
Depending on how many fields you have, it might be too cluttered, but light-colored, italicized text like:
first name (required)
last name (required)
might work for your app.
HTH

Resources