Skip to content

Reduce likelihood of binding leaks created by PropertyDescriptor fallback #11236

@Nintynuts

Description

@Nintynuts

In WPF you can bind to a control's DependencyProperty or a property on a view model (implementing INotifyPropertyChanged), which are fine, but if you bind to a property on an immutable model (not implementing INotifyPropertyChanged) it falls back to using a PropertyDescriptor.AddValueChanged listener, which causes a binding leak (reported by Snoop, documented here. As far as I can tell, this only makes some sense if it follows the WinForms pattern (a specific change event is present) or the property is writable (so multiple controls setting the value via the PropertyDescriptor will be notified about those changes, but not when changed directly in M/VM code).

Here's where the PropertyDescriptor accessor is chosen:

// 4. PropertyDescriptor (obtain from item - this is reputedly
// slower than obtaining from type, but the latter doesn't
// discover properties obtained from TypeDescriptorProvider -
// see bug 1713000).
// This supports the WinForms ValueChanged pattern.
if (accessor == null && item != null)
{
accessor = TypeDescriptor.GetProperties(item)[propertyName];
}

I've only recently become aware of this issue, but clearly it's been around a long time, and I wonder if it can be mostly fixed just by adding some checks before choosing to use a PropertyDescriptor.AddValueChanged listener, firstly looking for the WinForms event, and secondly checking for a public setter on the PropertyInfo for the instance being accessed. If neither of these are present, then it seems better to fall through to the PropertyInfo option below, which hopefully makes it effectively a one-time binding, but that can still be re-evaluated if a parent property that does notify changes.

I'm sure there are people who know this part of the framework much better than I, so please let me know if there is a fundamental problem with my suggestion, or if there is a better solution for avoiding this problem without requiring everything to implement INotifyPropertyChanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    InvestigateRequires further investigation by the WPF team.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions