Это должно сработать:
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
var multiBinding = new MultiBinding()
{
Converter = FallbackColorConverter.Instance,
Mode = BindingMode.TwoWay,
Bindings =
{
new Binding()
{
Source = this,
Path = new PropertyPath(CustomForegroundBackingProperty),
Mode = BindingMode.TwoWay
},
new Binding()
{
Source = this,
Path = new PropertyPath(ForegroundProperty),
Mode = BindingMode.OneWay
},
},
};
SetBinding(CustomForegroundProperty, multiBinding);
}
public Brush CustomForeground
{
get => (Brush)GetValue(CustomForegroundProperty);
set => SetValue(CustomForegroundProperty, value);
}
public static readonly DependencyProperty CustomForegroundProperty =
DependencyProperty.Register(nameof(CustomForeground), typeof(Brush), typeof(MyControl), new PropertyMetadata(null));
private static readonly DependencyProperty CustomForegroundBackingProperty =
DependencyProperty.Register("CustomForegroundBacking", typeof(Brush), typeof(MyControl), new PropertyMetadata(null));
private class FallbackColorConverter : IMultiValueConverter
{
public static readonly FallbackColorConverter Instance = new FallbackColorConverter();
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0] ?? values[1];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return new object[] { value };
}
}
}
Мы настроили два свойства DependencyProperties.CustomForegroundBackingProperty действует как фактическое хранилище для любых значений CustomForeground, которые пользователь устанавливает.CustomForegroundProperty просто действует как своего рода прокси.
Когда затем установить MultiBinding из ForegroundProperty и CustomForegroundBackingProperty в CustomForegroundProperty.Для MultiBinding установлено значение TwoWay (поэтому любое изменение на CustomForegroundProperty запускает привязку, как и любое изменение ForegroundProperty или CustomForegroundBackingProperty).
Мы устанавливаем привязку CustomForegroundBackingProperty к TwoWay (как мы хотим, чтобы записи в CustomForegroundProperty влиялиCustomForegroundBackingProperty), но мы устанавливаем привязку ForegroundProperty к OneWay, поскольку мы не хотим, чтобы это произошло.
Затем мы помещаем конвертер в MultiBinding.Когда конвертер выполняет запись в CustomForegroundProperty, он просматривает как CustomForegroundBackingProperty, так и ForegroundProperty и выбирает ForegroundProperty, если CustomForegroundBackingProperty равен null
.Это срабатывает, если изменяется либо ForegroundProperty, либо CustomForegroundBackingProperty.
Когда преобразователь пишет другим способом - т.е. пользователь пишет в CustomForegroundProperty - тогда мы просто возвращаем значение, которое они установили.Из-за режимов привязок в MultiBinding это означает, что для этого значения установлено значение CustomForegroundBackingProperty.