Notification when the Source of a BindingExpression changes? - wpf

TestScenario:
I've got a Control with a DependencyProperty A.
I've got a ViewModel with a property A that I bind against the Control's A-Property using the OneWayToSource Binding. The Binding is updated explicitly by the Control.
I switch out the bound ViewModel instance at runtime, thereby changing the underlying Source of my Binding.
When this happens I would like an Event to fire that tells my control that I can now update the value of its DependencyProperty A. The reason is, that as soon as you change the bound ViewModel, the DependencyProperty A's DefaultValue is written to the Source.
Instead, I would like the control to come up with a proper value and update the source manually.
One might think that just listening to the DataContextChanged event solves the problem. However, when this Event gets fired, the Source of the BindingExpression still points to the old ViewModel.
The only hackaround I can come up with, is to use Dispatcher.BeginInvoke with the DispatcherPriority.DataBind priority in the EventHandler of DataContextChanged.
It works, but does not feel clean to me.
I am looking for an event in the Binding-class that notifies me about changes of the Source... however I cannot find one.
Thank you

Perhaps I'm not understanding the question completely, but can you just use the NotifyOnSourceUpdated or NotifyOnTargetUpdated properties (and the corresponding SourceUpdated or TargetUpdated events)?

Related

WPF what happens when a one way bound property is manually modified

I'm just curious. For example, if the width of a custom user control is bound to the actual width of some other usercontrol, but then the width in the usercontrol is manually changed during some event. Will the property just go out of sync? Will the binding not work correctly? or will the property just be out of sync until the next time the source property changes?
Some more differentiation required. First: What kind of binding is it? If you have a OneWay binding then you will get out of sync when the target gets modified.
TwoWay or OneWayToSource will cause an update of the source (feed back)
In the case of OneWay changing the value will not remote the binding, as #goose noted when the source will trigger a PropertyChanged event the target destination will be resynced again.
If you wish to remove the binding, call BindingExpression.ClearBinding with the DependencyProperty you want to clear or BindingExpression.ClearAllBindings.
When a one way bound property is modified the binding will no longer work correctly. Even when the property is altered afterwards using the set method and NotifyPropertyChanged properly the width will remain unchanged.

WPF Notify Property on a Child User Control

I have a user control UC_A that contains a user control UC_B. Each has a different view model as its data context, VM_A and VM_B respectively, both derived from INotifyPropertyChanged.
A command from VM_A changes stuff that affects a property in VM_B. UC_B has a binding to that property. How can I cause the binding to update? I tried OnPropertyChanged in VM_A but it does not do the job.
Any help would be appreciated.
If VM B changes, then the notification must be raised from there to notify UC B.
To add on what #flq said already,
I don't see what's the problem, if you implemented OnPropertyChanged properly it should just work.
i.e. when your View-model-A changes something in the view-model-B - then whatever property is changed in the VM-B should fire off the OnPropertyChanged - from the VM-B - and that'd 'land' into the UC-B lap, as it should.

wpf: TextChanged event fired on setting DataContext

I've got a simple View with a single textbox that gets databound to a simple ViewModel with a single string property.
I need to catch the TextChanged event of that textbox so that I can do a little validation magic.
The problem that I am running into is that the TextChanged event fires for that textbox when the DataContext is set for the View.
Is there a standard mechanism that I can use to determine if the event is firing because of the DataContext being set versus when the user is making changes?
Thanks!
As far as I know there is no such mechanism. What you should do instead is to do your validation magic using standard means of WPF. Please see the following link: http://msdn.microsoft.com/en-us/library/ms752347.aspx#data_validation.
Anyway, as long as you use MVVM you can always detect that text has changed in the setter of the bound property in your view model.

Update Dependency Property prior to program exit

I have created a dependency property of type Binary on a RichTextBox which allows me to bind to a FlowDocument which is in binary form (byte[]) within the ViewModel. This works well, the property converts to and back correctly.
Whenever the RichTextBox looses focus then the value of the dependency property is updated with the new binary representation of the FlowDocument.
My problem is that if I have been using the RichTextBox and I close the window, the RichTextBox does not lose focus and hence the dependency property is not updated with the new binary representation of the FlowDocument and therefore new changes are not commited to the database. In my ViewModel I have a method CleanUp which gets called when a ViewModel is getting ready to be disposed, where I can save the updated document.
How can I get the dependency property to update itself as the RichTextBox doesn't lose focus if the user clicks to close the window?
I brainstormed the following:
Tell the dependency property to update itself via a message broadcast. I am not clear on how to register a message listener within the dependency property.
Query the RichTextBox directly, get the Document, convert it to a binary object manually.
Get the view to move focus to a dummy control, so that the dependency property now updates itself.
What do you guys think?
Update: the on changed event for the dependency property adds a event handler which is waiting for the RichTextBox to loose focus. It is this handler that updates the dependency with its new value.
Use an UpdateSourceTrigger of "PropertyChanged"
Something like:
{Binding Path=MyProperty,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}
I had a similar problem once, the solution I used was to move the focus to a different control and I never had any problems with this.
In my case there were several editable controls in the window so I didn't have to use a dummy control.
What's stopping you from handling the closing/closed event of the Window and moving focus or updating the binding?

Synchronize Bindings of multiple Properties in a UserControl

I have an ugly race condition with a WPF usercontrol, which is some kind of extended ComboBox:
The UserControl mainly defines two bindable DependencyProperties, one is the selected item, another one is a list, from which the selected item can be chosen.
Both are bindable, so the control may be initialized with or without a selected item and both properties can be changed via binding (on DataContext change), further the selection may change due to user interaction.
The UserControl contains a ComboBox, whose ItemsSource and SelectedItem are synchronized with my list-property and SelectedItem of the UserControl - so far so good.
The trouble now is, that if both properties are changed (quasi simultaneously) from outside when setting a new DataContext with both values set, it occasionally happens that the SelectedItem is set correctly but the list update causes the selection to be reset to null overwriting the previously set value -> corrupting my DataContext.
To make it short: I need to find a way to "lock" my SelectedItem during list update - but just observing the PropertyChanged-Events is not enough, since I receive them AFTER the updates, where the state to remember is already lost. Further I cannot identify, if the selection change was caused by the user or by (correctly) the binding or (not desired) indirectly by the other binding...
I think I would need some BeforePropertyChanged or OnPropertyChanging event for my DependencyProperties - or another way to manage the ordering of simultanous updates of both properties.
Any suggestions welcome :)
Note that I talk of a list to select an item from, but actually it is some more complex structure that allows quick sorting and filtering, that is also the reason why I do not use an ItemsControl here, but I don't feel like that's relevant for the question.
This may not help the situation, and is probably not the right way to do this, however you spoke of an OnPropertyChanging event for your dependency properties.
It just so happens that when you create dependency properties you can specify a callback in the PropertyMetadata that fires when the property changes, which has both the old and the new values in its EventArgument.
Here is an example of a Text property with a callback
public static DependencyProperty TextProperty = DependencyProperty.Register
("Text", typeof(string),
typeof(DecimalTextBox),
new PropertyMetadata("", OnTextPropertyChanged));
The last parameter is the one you are looking for. The first parameter of the PropertyMetadata constructor is a default value for the property. The second one is where you register a propertychanged callback that happens when the property changes.
in this callback you can handle the bindings to make sure that you don't overwrite your datacontext's SelectedItem.
private static void OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var box = ((TextBox)sender);
if (((string)e.NewValue)==badvalue)
box.Text= e.OldValue);
}
To be honest I'm not sure how this helps you with your situation, as I would still not know how to check whether the null value is valid or not. (what I might do is not allow null values if there is an ItemsSource unless the itemssource is just changing [and I might use some kind of flag in the ItemsSource changed callback that gets reset once the selecteditem is changed]). I'm not very clued up on async, but you could perhaps put some sort of lock in here.
u_u

Resources