I have a class that implements INotifyPropertyChanged. I use a binding source to bind the class to a form's controls. I'm using WinForms.
When I enter some text in a textbox and click on the Save button (I don't leave the textbox), the property bound to the textbox doesn't get updated.
Is this normal behavior? And if yes, is there a way to accept all changes?
Related
I bound Selected Item of ListView with my viewmodel property SelectedLayout and I have changed SelectedLayout from code behind. The Selected Item is changing properly But focus is not coming to the selected item. It is clear when I press enter. Focus is at button where it was before setting SelectedLayout . How can I get Focus to the selected Item in windows 10 UWP?
Just changing the value of bound property does not automatically change the focus to the corresponding element. It is done by design, as in many cases you do not need to change focus, just to update the value of the control. So what you need to do is to implement the logic of changing focus in your MVVM code.
To do that, the good practice would be to use Attached Property as outlined here: Set focus on textbox in WPF from view model (C#). In this manner, you can bind the IsFocused attached property of your controls to your ViewModel, and then implement any focusing logic in the ViewModel.
I have a C# WPF MVVM application that works fine.
The only problem is when I modify a textbox and click on the menu. If I do that without clicking on another control, the view->viewmodel event is never fired because the textbox hasn't lost focus. Correct me if I am wrong, but I think the RaisePropertyChanged is only fired on LostFocus (or OnBlur, or any similar event).
So, clicking on the menu save button right after editing the textbox causes the viewmodel to save the data using old values.
So, resuming:
This sequence works fine:
Edit the text box
Click on another control
RaisePropertyChanged is fired, the viewmodel is updated
Click on save button on the menu
Data Saved with correct values
This sequence gives me an error:
Edit the text box
Click on save button on the menu
Data Saved with correct values
How to solve this?
This is a common gotcha with TextBoxes in both WPF and WinForms. You can get around this by instructing the binding system to update the VM with every change to the TextBox instead of when it loses focus. To do this, set the UpdateSourceTrigger of the binding to PropertyChanged. This will write back to the VM any time the TextBox raises the PropertyChanged event for its Text property.
<TextBox Text="{Binding MyText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
For the TextBox.Text dependency property, its default UpdateSourceTrigger is LostFocus (ie, your view model property gets updated when the control loses focus). To make the property update immediately whenever text is entered, set UpdateSourceTrigger=PropertyChanged. (See the link above for more info -- it actually covers your example specifically.)
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.
Is there a way to make a "click-to-edit" control in silverlight? I've got some items that
will be displayed in a treeview control, and I would like the labels to be editable directly in the treeview.
Anyone know how to do this?
Very easy actually. I have implemented many forms with such a swapping mechanism.
You could do this using a Converter and do a simple BooleanToVisibility conversion on an IsEditable property that exists on the entities that you bind to your TreeView. Within your TreeView ItemTemplate just bind the TextBlock in such a way that it is Collapsed whenever the IsEditable property is true and bind the TextBox in such a way that it is collapesed when IsEditable property is false (and vice versa).
If you wanted to build a custom ClickToEdit control you would need to do the following:
Create a class that inherits from ContentControl
Expose a new dependency properties of type DataTemplate: one called EditableTemplate.
Add a MouseLeftButtonUp event handler inside your OnApplyTemplate to listen for the click.
Change the active content template to be your EditableTemplate on the click event.
Change the template back when the control loses focus.
Now to use your custom control inside TreeView:
Override your ItemTemplate for your TreeView
Put your custom ClickToEdit control inside there
Implementing a custom control would allow you (or other developers) to easily specify what control they wanted to use as the content editor. For example, they could specify a NumericUpDown or a DateTimePicker instead of just using a TextBox.
Check out DataForm in Silverlight 3. It has similar functionality but the switching of the editable vs. read-only is not done by a click.
Is there a property or setting to force a bound control in Winforms to update the object it is bound to when the input value, either in a textbox or whatever, actually changes?
And not after the control is tabbed out of.
Assuming you have already bound the textbox to something:
Select the textbox in the designer
Click property "databindings"
Click property "advanced"
In this dialog look for the "datasource update mode"
Select onpropery changed instead of onvalidate
Now the datasource gets updated on every change of the text property of the textbox.