I'm using the Extended WPF ToolKit's DecimalUpDown control (v1.7). The control behaves as I expect when using the spinner controls but not when text is edited directly. This is a basic MVVM WPF app with the control bound to a View Model decimal property named CurrentWidth.
In the ViewModel there are various validation rules being enforced for CurrentWidth, at the end of the property it does a RaisePropertyChange("CurrentWidth"); sometimes leaving CurrentWidth unchanged if the value doesn't validate.
All the error checking, value reverting etc works when change is made with the spinner controls. When the user enters text directly in the box, the validation still works but the box is left showing what the user entered. When I send out some debug info, both the Value property and Text properties have the correct unmodified value but the box still shows the user entered value. I tried adding a LostFocus event handler and called InvalidateVisual() on the sender control and even tried an UpdateLayout() as well but after tabbing off the control, the user entered text still shows. Anyone know how to get it to reflect the actual current value?
Download WPFToolkit 1.8.0. This bug is solved there.
Related
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.
I have a form with a textbox bound to an integer, and a button. Now, when the value of the textbox is invalid, I want to immediately disable the button.
Normally, one would put a Can() method in the VM, and trigger a NotifyOfPropertyChange in the property's setter. However, if the user inputs a non numeric value for example, the textbox is invalid, but the property setter is never called, so I can't notify/disable the button.
So, how do I disable the button, when the user inputs an invalid value that doesn't cause the property setter to get called? My knowledge of CM is limited as I've just started out.
I've found the best approach to this problem is to make the property a string instead and do the necessary string to integer conversion in your property setter. If the conversion is invalid, then you could reset the TextBox value to a default value. This way your property setter will always get fired.
If your model has an integer property, then it makes sense to place the string version on the view model, as this is only really related to the UI, rather than business logic.
If you don't wish the user to be able to input non digit characters, then you can use a masked text box, such as the one included in the Extended WPF Toolkit, or in a third party control suite such as those offered by Telerik or Infragistics.
I'd use a MaskedTextBox instead and set the mask to integer only.
In a form, I have a TextBox Binding an Object on its member property "Title". Along with it is a "Save" button to test the binding.
Seems like the underlying object property does not get updated unless the textbox loses focus. But there no form.ActiveControl.Blur() for use. Besides, this does not seem like a sound hack.
Anyway to do this better? Thanks.
EDIT: Sorry for not being clear. My question is in the title: "How to commit a TextBox". I use the term "commit" from the DataGridView commit and BindingSource commit. And it's in WinForms. (Have never worked with WPF, so it didn't occur to me. Sorry).
The actual scenario I have is I have a bunch of TextBox binded to property of a single Object. The user enters values in all the TextBox and when the user clicks save (toolbar button), the last TextBox is still in focus (or in editing mode) hence the save will not capture the last value in the last textbox.
I want to find the correct way to "commit" the textbox value just before saving.
Thanks.
Since the question has been updated to indicate this is WinForms, you'll need to handle things a little differently than if this were a WPF application. Fortunately, it turns out that the solution is very simple.
Whenever the user clicks on the "Save" button (so, say, in your Save button's Click event handler), you need to call the EndEdit method on your BindingSource. This will cause all pending changes to be committed to the underlying data source, exactly what you were hoping to accomplish.
Also see the relevant documentation on MSDN for more details.
Sounds like WPF from the problem description..
You want to change the binding so that it updates when the property value changes instead of when the textbox loses focus (which is the default when binding to TextBox.Text). You can do this by setting the UpdateSourceTrigger property on your binding:
<TextBox Text="{Binding UpdateSourceTrigger=PropertyChanged}"/>
I have a UserControl with a Tab Control containing three tabs. Within the tabs are multiple controls - Datetimepickers, textboxes, comboboxes.
There is also a Save button which when clicked, calls this.ValidateChildren(ValidationConstraints.Enabled) Now, I click save and a geniune validation error occurs. I correct the error and then click save again - valdiation errors occur on comboboxes on a different tab. If I navigate to this tab and click save, everything works fine. How can this be? I haven't changed any values in the comboboxes so how can the fail validation then pass validation?
The comboboxes are bound to a dataset with their selectedValue and Text set. I just don't understand what is happening here.
This behaviour also occurs for some textboxes too. The validation rule is that they have to be a decimal - the default value is zero, which is allowed. The same thing happens, they fail validation the first time - I make no changes, click save again and they pass validation.
EDIT:
The error is not a Framework error - the error is the one I provide during my validation routine. e.g Select a valid drop down option.
I stepped through the process and the sometimes the combobox values are the default values other times the selectedvalue is the default but the text is null. I don't see how this can happen if I'm not changing anything in the combobox.
If you need any further information please let me know
thanks
Barry
The following is a quote from MSDN:
"Controls contained in a TabPage are not created until the tab page is shown, and any data bindings in these controls are not activated until the tab page is shown."
So I'm guessing that if before you press save the first time, you make sure that you've clicked on each tab at least once, it'll work as expected, but if you don't look at all tabs before saving, it fails?
Have you checked that the default value is not null ?
I use data binding to display values in text boxes in a C# Windows Forms client. When the user clicks Save, I persist my changes to the database. However, the new value in the active editor is ignored (the previous value is saved). If I tab out of the active editor, and then Save, the new value is persisted, as expected.
Is there a way to force the active control to accept its value before persisting?
If you can get the Binding instance that corresponds to the input (the TextBox), you can call the WriteValue method to force the value from the control to the object it is bound to.
Also, you can call the EndCurrentEdit method on the BindingManagerBase class (usually a CurrencyManager class instance) to finish the edit, but that requires implementation of the ICancelAddNew or IEditableObject interface on the object that is bound to (and wouldn't require you to fish for the binding).
The solution I've used is to call ValidateChildren on the Form from the Save event (call), before actually saving the database records. This forces validation of all fields and thus binding to occur without losing focus of the control currently being edited on the form. It is real handy if the save button is on the Windows menu system and not form itself - plus it returns False if data in any control on the form is invalid and thus can be used to prevent saving errant data.
This also gets around inconsistent updating of the bound field that occurs when OnPropertyChanged is used as a binding method instead of OnValidation. Also, it is critical if the binding method is set to Never with separate WriteValue calls made for each validated event trapped per control.
This is kind of a hack, but try setting the focus away from the active editor (by setting the focus to something else, like the save button for example) in the button event before you call save.