I have a MVVM app, which shows a TextBox with its text bound to a viewmodel property:
Text="{Binding Path=Caption, Mode=TwoWay}
The update of 'Caption' property happens only when putting cursor to any other control. Is there a way, a good way, to have the 'Caption' property updated immediately when typing any char? I need this because my app displays a view twice, in same window - one is real 'work area', another - a 'thumbnail', in a listbox of all loaded 'work areas'. 'Work area' would show the new text correctly. A 'thumbnail' updates the textbox only when it loses cursor
For the text property, the default way to update bindings is LostFocus not PropertyChanged, you need to set this explicitly.
Text="{Binding Path=Caption, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}
Source
Related
I'm facing an odd issue with my WPF (MVVM) project.
I have a few controls which bind to the properties in the ViewModel. INotifyPropertyChanged is configured, everything (initially works). I type in some values into my controls and I click a button. I can see, by stepping through the code, all the property values are what they should be. So far, it is text book.
Now I notice the issue. After I click the button, some logic is performed, such as saving these values to a database. I can then edit the control values and then save to the database again. The properties at this point to do not update.
Binding clearly works, because the output shows no binding errors and when I click the Save button, the properties are correct. However, after I click the save button, and then change the property values, the properties are not updatdd. I cannot fathom why this is the case.
As a trial, I added the PropertyChanged to the update source trigger and this seems to fix the issue, however, I've never had to do this before. Any ideas what could be wrong?
I don't believe the answer is 2 way binding (I am happy to be wrong) because it binds!
<TextBox Text="{Binding DataSource, UpdateSourceTrigger=PropertyChanged}" Grid.Row ="1" Grid.Column="2" />
Where as normally I would use
<TextBox Text="{Binding DataSource}" Grid.Row ="1" Grid.Column="2" />
UpdateSourceTrigger property determines the time, when the binding has to be updated. The default value for this property is LostFocus. So by default, after you type something and move the focus out, the binding will update. If you set the property value to PropertyChanged, binding will update immediately once you entered the value in text box.
http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger(v=vs.110).aspx
In your case, the binding is updated on button click, since focus transferred to Button from textbox. Once the UpdateSourceTrigger set to PropertyChanged, the binding will update on every text change.
I have an app and a Settings window with TabControl containing couple of TabItems. Each of them have some fields (textboxes) which are databinded to the same Singleton object.
Is there any elegant and WPF-like way to the the databinding only after Save button click?
Right now it's databinded immediately after changing the content of the textbox, and I want that singleton have old values and update them only after clicking the save button.
For your DataBinding object used in XAML for the Textbox, use the UpdateSourceTrigger property with value Explicit as below:
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=Explicit}" />
When you set the UpdateSourceTrigger value to Explicit, the source value only changes when the application calls the UpdateSource method as below (you can put below code in Save Click event):
BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
Instead of raising the notification of change on the set of each property (as that is what triggers the re-binding, and update), put all the raise notifications in the save button. Then when you click save, you save and tell the View to rebind to those (now set) properties.
To further this:
Bind to non singleton properties (as you want to keep the old settings until save is clicked) - without a raise notification on those properties.
In your save button, set your singleton properties, then raise all the notifications of the other properties.
In your cancel button, set your other properties to the values of the singleton properties, and raise all the notifications.
Don't forget to set your properties to the singleton properties when the view has been loaded the first time, and raise all the notifications (just like a cancel).
If you are using WPF change the UpdateSourceTrigger to LostFocus. I think that will solve the purpose.
Text="{Binding Path=MyText, UpdateSourceTrigger=LostFocus, Mode=TwoWay}"
I have a view model that has two properties. One of them is myDataGridSelectedItems, that is update in the selection changed event of the datagrid (I am using MVVM light to convert an event to command).
The second property is myText, that is the text that has a textbox in the view.
In my view I have a textBox which text depends on the selection of the dataGrid, if the selection is one item then I put the information of a column of the dataGrid in the textBox, if the selection is 0 or more than 1, then I clear the textBox.
To do that, I use the following code:
<TextBox Height="23" HorizontalAlignment="Stretch" Margin="5,26,0,0" Name="mytextBox" VerticalAlignment="Top"
Text="{Binding ElementName=Principal, Path=DataContext.MyDatagridSelectedItems, Converter={StaticResource TextBoxValueConverter}}">
This works fine because when I select one row in the data grid the textBox has text (the text that the convert returns) and is empty when I select more that one or unselect all rows.
However, in this way the property myText is not update because I don't set the binding, because the binding of the Text property in the axml use the converter, not the property myText of the view model.
So I was wondering if it possible to set two bindings in the Text property of the textBox, or if exists some way to update the myText property in the view model when the text in the TextBox changes.
Thanks.
You are doing it the wrong way around:
Right now, you have view logic encoded in a converter in the view. But view logic is precisly what the view model is there for.
You should have a property for the text of that text box in the view model and bind the text box only to that property.
In the view model you change its value according to the selection.
I have a WPF MVVM app that contains a data entry form with several text boxes. I noticed that when the user is in a textbox and makes a change that the Context object does not know a change was made until the user tabs out of that text box. Once the user tabs out of the textbox, everything works fine. But I would like to know a change was made without the user having to tab off the textbox.
Is this possible?
The way my form works is that the Save and Cancel buttons bind to ICommands. These commands have a "CanSave" and "CanCancel" method that checks to see if the EntityState changed in anyway but allowing the buttons to enable. This works great but the user has to tab off the textbox to make things work.
How can I make this work without the user tabbing off a changed textbox?
Set the binding direction (Mode) of the TextBox to be TwoWay instead of the default and set the UpdateSourceTrigger to be PropertyChanged instead of default... like so:
<TextBox x:Name="txtPersonLastname" Text="{Binding Person.LastName, Mode=TwoWay, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" />
(I have some additional attributes for validation in this excerpt.)
The key difference is the PropertyChanged which will update your backing property in the ViewModel. When the user types anything into the TextBox, that PropertyChanged event will fire, and in turn should trigger your CanSave, Save routines.
In Blend, it should look like this:
You have to chnage the Update Source Trigger Property to refelct the chages in your ViewModel
For Example
<TextBox Text={Binding Path=MyProperty,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}></TextBox>
Dont forget that My Property should fire Property Changed from ViweModel
My app. contains the window in the picture:
The ItemsSource of the DataGrid is set to _editList ( declared as IList < Vendor > _editList;).
The data grid is set to Read Only.
The Vendor Name text box has the binding set as :
Text="{Binding ElementName=dataGridVendors, Path=SelectedItem.Name, Mode=TwoWay}"
This works well. However, as it is the Vendor Name cell only updates when the user is done typing in the Vendor Name textbox and clicks on something else. Say I want to change the vendor name to "John Lennon II" . I have to click on the textbox and type the characters I want to add and than I have to click on something else and only then the datagrid makes the update.
I want to make the update happen as the user types the characters....Is this possible ?
Regards,
Sebastian
Add the UpdateSourceTrigger to your Binding
Text="{Binding ElementName=dataGridVendors, Path=SelectedItem.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Its default trigger is lost focus. When you change it to PropertyChanged the Updates will done when you're typing.