Get previous value on Binding - c#

I am trying to get the previous value of textbox binding. Binding is like:
<TextBox Text="{Binding UserName}" />
There is string property in viewModel and i am following strict MVVM approach.
Is there any available property or event or any workaround to get the previous textbox value in xaml?
Thanks
EDIT : I thought that i can write interaction trigger to the got keyboard focus event and i can bind the current value as previous value to some other property. With that way i can have the previous value right?

When using binding your property UserName uses an event to tell the text box for change. This event might be of INotifyPropertyChanged class or DependencyProperty, both of which have events you can listen to.
If you need more info post the code for context class

Related

INotifyDataErrorInfo. ErrorsChanged how to make wpf show the errors of property like `Address.Country`

There is only 3 things inside of INotifyDataErrorInfo:
HasErrors: a read-only boolean property which tells if the object as a whole have any validation errors;
GetErrors: a method which returns validation errors for a given property;
ErrorsChanged: an event which must be raised when new errors – or the lacks of errors – is detected. You have to raise this event for each property.
In the demo project I create a form which display the properties of an object named ‘Person’. Here is how the validation with INotifyDataErrorInfo is enabled in the Binding:
<TextBox Text="{Binding Name,Mode=TwoWay,ValidatesOnNotifyDataErrors=True}"/>
We have to set the ValidatesOnNotifyDataErrors property to true.
The binding will then register itself for the ErrorsChanged event of the binded Person. Eeach time this event is raised for the binded property, the controls will dress itself to display an error. this is done only if the HasErrors is set to true.
Question:
Is there anyone know more detail aobut the ErrorsChanged event is raised for
the binded property, the controls will dress itself to display an
error?
If I binding Address.Country of Person ,will the ErrorsChanged event be raised for the binded property Address.Country or not? why? is there a way make this binding to show Errors too?
<TextBox Text="{Binding Address.Country,Mode=TwoWay,ValidatesOnNotifyDataErrors=True}"/>
I think I can risk an answer, this question is already one year old.
The Binding will register to the ErrorsChanged event in the Class containing the property. In that case, Address must implement INotifyDataErrorInfo.
And, it's you to raise the ErrorsChanged event when you implement the validation logic. Once you have validated the Address.Country, you store the ValidationResults (or simple strings list) and raise the event. The Binding will get the stored ValidationResults list for the PropertyName he is binded to, by calling the method GetErrors(string propertyName)that you wrote yourself implementing the INotifyDataErrorInfo interface.
If this list is not empty, the Binding will set the Property Validation.HasError to True and the control will raise the Validation.Error event. Some controls have a built-in behavior to change their appearance in error case (a TextBox will have a red frame around its border). If you want to show the errors, you have to retrieve them by writing a style in xaml. Plenty of examples out there.
The HasErrors method is used if you want to know if the Person has any errors in its Properties. It's mostly used in such cases : enabling or disabling a save button. Once again, it's you to implement the logic using the HasErrors Property. It's mostly done by binding it to a control Property in xaml.

TextBox TextChanged Event Problems

I'm using a basic TextBox that is bound to an object. Basically, what I want to do is call a method every time the text in the box is edited and the user de-selects the box or when the underlying bound data is edited. What I am using right now is the TextChanged event, but this has a few problems:
It is called when the TextBox is first created, and I don't want this.
It is called every time a new character is added, and I only want it called when the underlying bound data is changed (which seems to be whenever focus shifts from the box).
How can I accomplish this?
EDIT: I've tried several other TextBox properties like Get/LostFocus but they never seem to fire.
Also, I don't want to put this method call in the Setter of the Property, because the underlying data is something that is logically separate from the UI of this project and I don't want any method calls that relate to doing computations for the UI.
The event LostFocus fires when the focus is shifted from the current element. I tried it and its working fine.
As jods says, the best way to bind your TextBox's Text to ViewModel's property. The Code are:
View:
<TextBox x:Name="TextBox1" Text="{Binding Path=Text1,Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
ViewModel:
public string Text1
{
get { return _text1; }
set
{
_text1 = value;
RaisePropertyChanged("Text1");
}
}
View code behind:
private void ViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Text1")
{
//Call UI related method...
}
}
In this way, it satisfy your two conditions:
1. Every time when you edit TextBox and lose the focus, Setter of Text1 will be called and ViewModel will raise PropertyChanged event.
2. When underlying Text1 is changed. Text1 will also raise the event so View can know it.
Also it can avoid your two concerns:
1. In the first time binding, only getter of Text1 is called. No event is raised.
2. Setter of Text1 is only called after TextBox is lost focus.
every time the text in the box is edited and the user de-selects the box
Hmmm AFAIK it's a standard behaviour of TextBox if you bind text like that: Text={Binding Property}
when the underlying bound data is edited
You can provide this functionality inside setter of your property.
Best design is to listen for changes in the underlying bound property. You can do that without changing the setter if you use a DependencyProperty or if your object implements INotifyPropertyChanged.
When the underlying property changes (LostFocus by default, or each char at a time) is a binding option.
If you don't want to follow my advice of listenning for changes in your (view-)model, you could subscribe to GotFocus and LostFocus events. Save the current value when you get focus, compare with current value when you lose it. If it's different -> do what it is you want to do.
I am not sure what you are finally trying to achieve but I am going to take a guess at this. If you are following an MVVM pattern then, then it seems like you can achieve what you want by using the updateSourceTrigger property of the binding. If you are not using MVVM then you might what to take a look at using MVVM

Get a change event when the value bound to TextProperty is changed for Decended TextBox

I have my own custom TextBox class (call it MyCustomTextBox). In part it helps me handle scans from a barcode reader.
Part of what I need for this to work is a way to capture when the value bound to TextProperty changes.
Note: I am not looking for the "TextChanged" event or any kind of event that relates to a key press (except when that key press updates the source).
Here is an example:
I need an event (in MyCustomTextBox) that will fire ONLY when the underlying value (CustomerId) gets changed.
Note: The actual TextProperty gets changed every time a key press happens. But the Source is not updated until later (depending on your UpdateSourceTrigger setting). The TextProperty changes too frequently for what I am trying to do. So attaching to it will not help me.
Is there any way to attach to the value under the TextProperty?
Is this possible?
Yep, you need to hook up 2 events though
<TextBox Name="Fred" Text="{Binding Foo, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}" TargetUpdated="Fred_TargetUpdated" SourceUpdated="Fred_SourceUpdated">
TargetUpdated event will get fired when something other than the textbox changes the underlying property (and when it first binds) eg. some method in your VM say
Sourceupdated event will get fired when your textbox updates its binding eg on lost focus

Find and Update a WPF TextBox's Bound Property (From the TextBox)

Say I have a text box like this:
<TextBox Text="{Binding MyBoundProperty, Mode=TwoWay"/>
Is there an easy way to find and set "MyBoundProperty" in code behind?
I am working in a custom attached property for a TextBox (catching the OnTextBoxKeyUp event) and want to set the property directly in some scenarios (when a scan happens).
If it's two-way binding, changing the Text property of the TextBox should update the source.

WPF Databinding Magic

I have ObservableCollection<Foo> that is bound to an ItemsControl (basically displaying a list).
Foo mostly looks like this (there are other members but it doesn't implement any interfaces or events):
class Foo
{
public string Name { get; set; }
//...
}
When the user clicks on an item I open a dialog where the user can edit Foo's properties (bound to a small viewmodel with a Foo property for the selected item), the Xaml looks like this:
<TextBox Text="{Binding Foo.Name,Mode=TwoWay}"
Grid.Column="1" Grid.Row="0" Margin="2" />
The really strange thing is, when the user edits the name, the value in the list changes! (not while typing but after the focus leaves the field)
How does it do that? I haven't implemented the INotifyPropertyChanged interface on the Foo object!
So far I checked that it doesn't just refresh the whole list - only the selected item. But I don't know where I could set a breakpoint to check who's calling.
Update: thanks to casperOne for the link to the solution! I'll add a summary here in case it goes 404:
[..] actually you are encountering a another hidden aspect of WPF, that's it WPF's data binding engine will data bind to PropertyDescriptor instance which wraps the source property if the source object is a plain CLR object and doesn't implement INotifyPropertyChanged interface. And the data binding engine will try to subscribe to the property changed event through PropertyDescriptor.AddValueChanged() method. And when the target data bound element change the property values, data binding engine will call PropertyDescriptor.SetValue() method to transfer the changed value back to the source property, and it will simultaneously raise ValueChanged event to notify other subscribers (in this instance, the other subscribers will be the TextBlocks within the ListBox.
And if you are implementing INotifyPropertyChanged, you are fully responsible to implement the change notification in every setter of the properties which needs to be data bound to the UI. Otherwise, the change will be not synchronized as you'd expect.
This is a total guess, but I'm thinking that because you have two-way binding enabled, WPF is now aware of when it makes changes, and will update other items it knows is bound to the same instance.
So because you have changed the value of the Name property through the textbox, and WPF knows when you have changed that value, it does its best to update whatever else it knows is bound to it.
It uses reflection to set the value of that property. INotifyPropertyChanged is only needed if the TextBox needs to be informed of a change in the Name property of the Foo class.
Because they're databound to the same object. If you change the binding to
{Binding Foo.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
then they'll be in synch when the user types in the textbox.

Categories