API Request: BindingOperations.SetBinding for DependencyPropertyKey
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
We currently have `BindingOperations.SetBinding(DependencyObject, DependencyProperty, BindingBase)` to set bindings from C# code. Sometimes, it's useful to have dependency properties where we control how they get manipulated.
In most cases, `DependencyObject.SetValue(DependencyPropertyKey, object)` is good enough to achieve this level of control, but sometimes we actually do want to have the dependency property's value set from a binding.
As an example, here's a class with a dependency property called `Combined` whose value we want to ensure is always built up by running zero or more data-bound values through some `IMultiValueConverter` implementation:
```csharp
public sealed class C: DependencyObject
{
private static readonly DependencyPropertyKey CombinedPropertyKey =
DependencyProperty.RegisterReadOnly(nameof(Combined),
typeof(string),
typeof(C),
null);
public static readonly DependencyProperty CombinedProperty = CombinedPropertyKey.DependencyProperty;
private readonly List _combinedBindings = new List();
public string Combined => (string)GetValue(CombinedProperty);
public void CombineWithBinding(BindingBase combinedBinding)
{
_combinedBindings.Add(combinedBinding);
var multi = new MultiBinding { Converter = new CombinerConverter() };
foreach (var binding in _combinedBindings)
{
multi.Bindings.Add(binding);
}
// IMPOSSIBLE:
BindingOperations.SetBinding(this, CombinedPropertyKey, multi);
}
}
```
This design, if it were legal, ensures that anyone who has access to an instance of type `C` can **add more** data-bound elements to the combination, without any way to **change or remove** data bindings that have already been added by others (whether by accident or intentionally).
Today, the most reasonable approach I can come up with to achieve my goals is to switch from `RegisterReadOnly` to `Register` and just trust callers not to break this convention. There are other approaches that could work too for my weird use case, but I really like the semantics of having the caller being allowed to bring their own `BindingBase` to the table.
Contributor guide
Assessment
This issue has not been assessed yet.