dotnet / dotnet/wpf

One-Way Binding immediately lost when the target Dependency Property is internally updated

Open
#9,910 14 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

Hi,

I've been writing advanced WPF stuff for the last 8 years. This is the first time I notice this odd behavior of One-Way bindings in such a basic use case:

The One-Way binding is cleared by the WPF engine when the target Dependency Property (in a custom Control/UserControl) is internally updated (in code or via internal binding).

I prepared a very simple sample to reproduce that, to which I added a `BindingObserver` control that continuously outputs the state of the `BindingExpression` on the UI.

Here is the sample:
https://github.com/amine2050/wpf-lost-binding

Am I missing a basic knowledge of how One-Way bindings behave? Or is this a known issue? I could not find any literature about the topic.

### Reproduction Steps

- Start sample app
- Click on "Change Value" button => content of TextBox changes (binding is working)
- Type something in the TextBox, then Tab to update value
- Click on "Change Value" button => content of TextBox does not change anymore (binding is broken)

### Expected behavior

One-way binding to ViewModel is expected to continue working even after changing the value of the DependencyProperty (by changing TextBox content).

The new content of the TextBox should not propagate to the binding Source (which is correct here), but changes in the Source are expected to be reflected on the TextBox (this does not happen anymore).

I want the same behavior of a simple TextBox bound to ViewModel using One-Way binding.

### Actual behavior

One-way binding to ViewModel has been cleared by the WPF engine without any warnings or output. Changes in ViewModel are no loger propagating to UI.

### Regression?

I tested this with .NET 8.0 and .NET Framework 7.2.1 and got the same behavior. So no regression is known.

### Known Workarounds

The only workaround I found is to use Two-Way binding instead of One-Way. But this is not necessarily what I want actually.

### Impact

This applies to any custom Control/UserControl that has properties you want to change internally while allowing binding them using One-Way binding.

### Configuration

- .NET runtime 8.0.3
- Windows 10 Pro x64 build 19045.4957

### Other information

I added `PresentationTraceSources.TraceLevel=High` to the binding and got the following output when the binding gets broken:

```
System.Windows.Data Warning: 79 : BindingExpression (hash=53180767): Deactivate
System.Windows.Data Warning: 103 : BindingExpression (hash=53180767): Replace item at level 0 with {NullDataItem}
System.Windows.Data Warning: 63 : BindingExpression (hash=53180767): Detach
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.