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

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.

Related

Notification when the Source of a BindingExpression changes?

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)?

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?

What are the various WPF binding modes?

I do not understand the various data binding modes in WPF, such as:
One-Way
Two-Way
One-Time
etc...
What does each of these modes mean?
When should they be used?
OneWay: Use this when you want the bound property to update the user interface.
TwoWay: This has the same behavior as OneWay and OneWayToSource combined. The bound property will update the user interface, and changes in the user interface will update the bound property (You would use this with a TextBox or a Checkbox, for example.)
OneTime: This has the same behavior as OneWay, except it will only update the user interface one time. This should be your default choice for binding (for various reasons I won't elaborate on here). You should only use other types of bindings if you actually need the extra functionality.
OneWayToSource: This is the opposite of OneWay -- user interface value changes update the bound property.
If you don't specify anything, then the behavior will depend on the control that you are using.
For more info, see BindingMode enum on Microsoft Docs.
A binding consists of two entities:
The Source (Typically the ViewModel in MVVM scenarios)
The Target (The UI control)
The target has to be a DependencyObject (for binding to work) and the source can be either a DependencyObject or it should have some mechanism to imitate the WPF Binding system about it being changed (Implemeting INotifyPropetyChnaged interface).
MVVM recommends the ViewModel project to be free from any View related references and hence it is recommended to use INotifyPropertyChanged interface to make the Source object being heard by WPF binding.
Binding happens between a property of Source and a property of Target (has to be a DependencyProperty).
e.g. The TextPropertyof the TextBox class is DataBound to (say) UserName property of the view model.
WPF binding offers four types of Binding. Remember, Binding runs on UI thread unless otherwise you specify it to run otherwise.
OneWay: The target property will listen to the source property being changed and will update itself. If you programmatically change the ViewwModel's UserName property, it will reflect in the text box. This is of intermediate cost as the binding system watches only Source for changes.
TwoWay: The target property will listen to the source property being changed and will update itself. AND The source property will listen to the target property being changed and will update itself. Both the TextProperty and the UserName property will remain in sync and will update each other if one changes. This is most costly as the binding system has to watch both sides for change.
OneWayToSource: The Source property will change if the target property is changed. If the user changes the TextProperty, the UserName property will take up the changed value. This again is of intermediate cost as the binding system watches only Target for changes.
OneTime: This happens only once during the lifetime of Binding, the Target property will be updated with the Source property when the Binding happens. This is least costly and is advisable for scenarios where you have static data to be shown e.g. Label, TextBlock etc.
If you don't mention anything, every target property has a default binding mode associated with itself. E.g. the TextProperty of a TextBox has default binding mode as TwoWay. For the TextProperty of a TextBlock it is one way.
It is advisable that you choose the right mode as it can help you reduce the application latency especially in cases where you have large number of controls in your UI.
For more on MVVM here is an article written by me.

WPF: Bindings - Object not updated

I have a an object which is set to the DataContext in a Window. I have textboxes in the window which are bound to the properties on the object. There seems to be a delay however before the properties on the object are updated.
<TextBox x:Name="txtPropertyOne" Text="{Binding Path=PropertyOne,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
If I change the values in a few textboxes then quickly try to access the properties to which they map, sometimes there are changes which aren't reflected in the properties of the object. I thought that was what the PropertyChanged UpdateSourceTrigger was supposed to take care of.
If I change the values in a few
textboxes then quickly try to access
the properties to which they map
I can interpret this statement in two ways:
You're trying to access the values on a background thread. In that case, you may be accessing the properties before the UI thread has had a chance to do its thing.
You're using a separate message on the UI thread to check the values. Bindings are updated at a priority lower than Send and Normal. So if your message is priority Send or Normal it will be processed before any pending binding updates.
If this doesn't answer your question, please clarify what you mean by "quickly trying to access the properties".
The basic rule of WPF Databinding is simple:
The target property must be a
dependency property, and you're
already correct, it's bound to Text
property of TextBox.
The source property can be a CLR
object (other than any derived WPF's
DependencyObject), but the object
must employ or implement its own
INotifyPropertyChanged.
Have you you already implemented INotifyPropertyChanged on your object?

BindableAttribute, Combobox, Selectedvalue property - WinForms

I am deriving from combobox (WinForms) and am providing a new implementation for the Selectedvalue property.
It works fine as is, but any change to the selectedvalue property is not updating other controls bound to the same "binding context" to change their values accordingly.
I did try adding the BindableAttribute(true) to the property, but still it does nottrigger the change in value to the other linked controls.
The control's DataBindings.add(...) is all set up. And other controls are also bound to the same data filed on the same datasource.
Any ideas what i am doing wrong.
Have you called your base class' implementation of overridden methods? It's possible that failing to call the base class implementation is accidentally circumventing the code that fires various event plumbing.

Resources