Force WPF to Commit Changes on Focused Element - wpf

I'm working with VS2010, WPF and EF. I've placed controls on my window by dragging an entity out of the Data Sources toolwindow. I used the "details" setting so my entity is represented by several labels and textboxes. I've also added a button with the following code:
_context.SaveChanges();
When I'm editing data, the changes in whichever textbox has focus are not committed back to the DB. Everything else commits just fine. If I shift focus to another element prior to hitting the save button, it commits as well. I've experienced the same thing with the DataGrid.
I know I'm missing something simple, but I can figure it out. Any ideas on what I'm missing?
Thanks!

This is because TextBox's default Binding UpdateSourceTrigger is LostFocus. If you modify all your Bindings to set this to PropertyChanged, it will work like you expect:
<TextBox Text="{Binding SomeProperty, UpdateSourceTrigger=PropertyChanged}" />

I just ran into this same issue when trying to set the value of a databound TextBox programmatically, but Abe's suggestion didn't work for our setup (it was causing some erratic validation behavior).
Here's how I got it to work:
TextBox tb = (TextBox)this.FindName("TargetTextBox");
tb.Text = "1234";
tb.GetBindingExpression(TextBox.TextProperty).UpdateSource();

Related

WPF Custom control with textbox doesnot update from viewmodel changes

I have a accustom control bound to a model class. So if any change in UI for textbox it updates ViewModel.model instance. but it doesnot work the other way. What is the necessary thing I need to look for? or troubleshoot steps pls.
Thanks.
You mean the value is displayed in the Textbox but a new typed value isn't?
If so you need to set two way binding on the Textbox binding:
<Textbox Text={Binding myTextProperty, Mode="TwoWay", UpdateSourceTrigger="ProprtyChanged"/>
This will enable both read & write functionality to your binding.
As #Ganesh says, you also need to make sure you're implementing the INotifyPropertyChanged interface in your ViewModel.

MVVM not binding after initial value has been entered

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.

Saving in a WPF data entry form

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

WPF .net 4.0: Textbox resets caret position when binding with UpdateSourceTrigger=PropertyChanged

I've got the following Situation:
TextBox which is bound to a property:
<TextBox Text="{Binding Settings.ClientName, UpdateSourceTrigger=PropertyChanged}"/>
The property ClientName stores its value in the unterlying structures and does NOT call Notifyon the property changed event. instead the underlying structures send an event to refresh the UI after they processed the value . If such an event is fired, the ClientNameProperty is set correctly and Notify is called for this property.
the problem is that if i enter any text, the caret seems to jump to the first position in the textbox, actuall reversing any string i enter. "abcd" becomes "dcba"
I noticed that this behaviour occured after we migrated to Net 4.0.
Are there any good solutions out there?
Many thanks
There is no built-in behavior that would do that. That problem is likely to come from your processing.
On a side note, if you want the TextBox to change from code-behind as well as from user input, you want to make it Two-Way:
<TextBox Text="{Binding Settings.ClientName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
EDIT:
You could also make the ClientName a dependency property (propdp snippet in vs2010). That would automatically fully support binding(/styling/animation), and gives you the possibility to act when the value changes as well as to coerce it back through callback delegates.
Last but not least, you still wouldn't need your Settings class to implement INotifyPropertyChanged.
Here is a place to start (msdn).
I suspect you are suffering from this behavior change in the WPF TextBox: https://connect.microsoft.com/VisualStudio/feedback/details/588343/changed-behaviour-from-net-3-5-to-net-4-0-of-wpf-textbox-formatting-when-propertychanged-is-used-as-updatesourcetrigger (Changed behaviour from .Net 3.5 to .Net 4.0 of WPF TextBox formatting when PropertyChanged is used as UpdateSourceTrigger)

How to data bind the text property of a TextBlock to the text property of a TextBox

I have a WPF application with two pages. On page one, there is a TextBox (boxSource). On page two, I have a TextBlock (blockDestination). I want to databind in XAML, the Text property of boxSource to the Text property of blockDestination.
I set the DataContext of page two to page one when the application is initialized. I setup blockDestination as follows:
<TextBlock Name="blockDestination" Grid.Row="0" Grid.Column="1" Text="{Binding boxSource, Path=Text, Mode=OneWay}" />
This does not pickup the value of the TextBox. My guess is that it is because the TextBox is a variable instead of a property?
Can anyone explain the issue, and is there an elegant solution?
Thanks for any help
For that XAML to work, your "page one" will need to be set as the data context of page two, with the boxSource variable defined as a property, so that in the setter, you can raise the PropertyChanged event.
Matthias is right, though, this is a pretty brittle way to implement this, and one of the places where an MVVM approach will be more robust in the long run.
An elegant solution would be to define a View Model common to all pages. You should always bind to properties of the view model and should avoid binding to UI Elements. Using a view model you can always access all neccessary values and define several presentations in different pages.
I've read something about pages having their own object space, so that UI elements can have the same name in different pages. Also it can happen that the first page isn't available after loading the second one. The binding target would then be unavailable.

Resources