I'm handling CellValidating and setting e.Cancel = true if the data in the cell is invalid. This almost gets me where I want to be, but the problem is if the user has some invalid data in the cell, the rest of the UI is essentially off-limits until they fix the error or press Esc.
Since pressing Esc might not be intuitive to certain users, they may find it frustrating that they can't e.g. click on the "Back" button I have on the form to leave the screen altogether. (In such a scenario, their change-in-progress should be discarded as if they had pressed Esc.)
Any ideas on how to achieve this? I do like that they aren't allowed to start editing other cells without fixing errors in their current cell, but I'd prefer they still be able to press the "Back"/"Cancel" buttons on the form.
Thanks in advance!
You could set the CausesValidation property to false.
Related
I am trying to put an entire DataGridViewRow into edit mode after a button click event. When I need to programmatically edit a cell I use the code below, but BeginEdit doesn't work with rows, it only allows one cell to be edited.
DataGridView.CurrentCell.ReadOnly = false;
DataGridView.BeginEdit(true);
How can I make an entire DataGridViewRow editable?
There is a standard way that the DataGridView is supposed to work ... try to make it work differently and you are in for much frustration and large quantities of code.
There are several things I can think of here:
1) Find a third-party grid control that does what you need.
2) Write your own grid control to do this.
3) Try to make the DataGridView do what it was not designed to do.
I am assuming by your message that you are restricted to option 3? If so, then you could try this:
Keep a flag denoting that you are in edit mode (I hate flag-based programming - but sometimes there is no other easy choice...).
When the user clicks the button, set the flag and execute BeginEdit on the cell.
On the EndEdit, use BeginEdit to start edit of the next cell (assuming the flag is still set).
When the user presses the Enter key, exit edit on the currenlty edited cell and turn the flag off (which should prevent any other cell from being edited).
I'm using a form (FormView) with databinding (ObjectDataSource) and all my input fields are bound by using '<%# Bind("field") %>'.
Everything works fine, but I have two problems (which I found various hints about like using this.Validate() or .EndEdit() - but none seem to work):
Entries are only saved after leaving the input field so it looses focus
Let's say I have a textbox with an ID of Name and enter "George". When I would tab to the next textbox or when I click somewhere else and click save - everything is saved. But when I keep the focus in the textbox the value is not saved. Why is this happening? What magic can I use to circumvent this (JavaScript to the rescue?).
I set a textbox's field value (element.value) via Javascript (upon selecting something in a combobox).
The same problem as above applies, only when I give the textbox focus and tab out the value is saved. This creates the problem that I only want the user to choose something in the combobox (the textbox is updated accordingly) and move on - I don't want the user to click into the textbox afterwards and tab out again.
Edit:
The second problem I resolved now by setting the focus onto my textbox via Javascript (textbox.focus();) and right after set the focus back to the combobox (combobox.focus();) and that does the trick - this seems fairly hackish to me, doesn't it?
I'm assuming this is fairly common, but my mighty Google fu hasn't help me find a simple solution.
A similar issue can crop up in Winforms development when working with DataGridView controls. I typically attach some logic to the submit button's Click event to cause the DataGridView to validate. I suspect a similar solution would work for you here.
In XtraGridView, from the way RowValidation works, it seems that user has no choice but first correct the values (leading to validation being successful) and then press Discard button (which I provided separately and it does RejectChanges). I want an option that user can discard the row without any pop-up alert even if row has invalid data.
In my case when user presses Discard, it leads to row validation being fired (due to focus change). The discard button event handler is suppressed, if row validation is unsuccessful. This way I am never able to simply discard the invalid row.
This is common feature anyone with a grid would need. Expecting a standard solution or a workaround.
You made me curious, as you say,something as basic as that should be in there somewhere.
Bit of gooling found that waht you do is trap the InvalidRowException, it has a var argument and you can set it to ignore.
Here's where I found it.
DevExpress
Can't you check the focused button and sidestep validation if the discard button is focused.
The general DevExpress setup forces the user to insert valid values when validating, pressing Esc is a simple solution to reset the field to the original value.
I have a feature request that when a ComboBox is 'clicked into' that it clears the text so that the user can start entering in new data to search. Does anyone know of a way to hook into this? The 'click' event is raised on when the text is clicked as well as when the drop down arrow is also clicked (which opens up the drop down with items). I only want it to happen on the first, not the latter.
Right now I'm capturing the click event and filtering on the DroppedDown property like so:
if(!comboBox.DroppedDown)
{
// clear selection
}
This seems to work most of the time, but bugs out frequently as well... so its not 100%.
If anyone knows of a proper way to do this I would appreciate!
Don't handle the click event. For one thing, it won't fire if the user tabs the focus into the control. Use the Enter event which fires when the control receives focus. And rather than clearing text you should just select it all which will give the best of both worlds:
1) The user can start entering new text which will clear any old text or
2) tab past the control and leave the contained text as it was.
If you always remove the previous text you may anger users.
Try the "Enter" event. It happens when a control gains focus on the form.
I have a UserControl that consists of three TextBoxes. On a form I can have one or more or my UserControl. I want to implement my own tab behavior so if the user presses Tab in the second TextBox I should only move to the third TextBox if the the second TextBox has anything entered. If nothing is entered in the second TextBox the next control of the form should get focus as per the normal tab behavior. If the user hasn't entered anything in the first or second TextBox and the presses tab there is this special case where a control on the form should be skipped.
By using the ProcessDialogKey I have managed to get it work kind of ok but I still have one problem. My question is if there is a way to detect how a WinForms control got focus since I would also like to know if the my UserControl got focus from a Tab or Shift-Tab and then do my weird stuff but if the user clicks the control I don't want to do anything special.
As a general rule, I would say overriding the standard behavior of the TAB key would be a bad idea. Maybe you can do something like disabling the 3rd text box until a valid entry is made in the 2nd text box.
Now, having said this, I've also broken this rule at the request of the customer. We made the enter key function like the tab key, where the enter key would save the value in a text field, and advance the cursor to the next field.
I don't think there's a built-in way that you could do it. All of the WinForms focus events (GotFocus,LostFocus,Enter,Leave) are called with empty EventArgs parameters, which will not give you any additional information.
Personally, I would disable the third textbox, as Rob Thomas said. If you're determined to do this, though, it wouldn't be difficult to set up a manual (read: hackish) solution. Once the tab key is pressed (if the focus is on the second textbox), set a variable inside your form. If the next object focused is then the third textbox, then you know exactly how it happened.
The reason for this odd tab behavior is all about speed in the input process. It was really good to get some input, I hadn't thought about disabling a textbox but that could actually work. But using the Enter key to accept the input hadn't even crossed my mind. That will work so much better. The user can enter the numbers and then press enter to accept the input and the next possible textbox will be the active one. It's like having the cake and eating it too, The speed factor is there since when using the enter key no unnecessary tabing must be done to get to the correct field and using the enter key next to the numeric keyboard makes it really smooth.
Thanks for the input!
I agree with DannySmurf. Messing with the tab order might give you hell later on if the requirements for the application change.
Another thing that you could do is to implement some kind of wizard for the user to go through.
Better than disabling controls, try monkeying around with TabStop - if this is false, the control will be simply skipped when tabbing.
I'd also suggest that the Changed event of the TextBox is the place to be updating TabStop on the other controls.
I've done something similar to this with a login control, where users could enter either a username or an email address (in separate fields), plus their password, and tabStop is what I used to get the job done.