この問題の回避策を見つけました。
主なアイデアは、バインドが必要な各パラメーターの添付プロパティを定義することです。
public class MarkupExtensionWithBindableParam : MarkupExtension
{
public BindingBase Param1 { get; set; } // its necessary to set parameter type as BindingBase to avoid exception that binding can't be used with non DependencyProperty
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
DependencyObject targetObject;
DependencyProperty targetProperty;
if (target != null && target.TargetObject is DependencyObject && target.TargetProperty is DependencyProperty)
{
targetObject = (DependencyObject)target.TargetObject;
targetProperty = (DependencyProperty)target.TargetProperty;
}
else
{
return this; // magic
}
// Bind the Param1 to attached property Param1BindingSinkProperty
BindingOperations.SetBinding(targetObject, MarkupExtensionWithBindableParam.Param1BindingSinkProperty, Param1);
// Now you can use Param1
// Param1 direct access example:
object param1Value = targetObject.GetValue(Param1BindingSinkProperty);
// Param1 use in binding example:
var param1InnerBinding = new Binding() { Source = targetObject, Path = new PropertyPath("(0).SomeInnerProperty", Param1BindingSinkProperty) }); // binding to Param1.SomeInnerProperty
return param1InnerBinding.ProvideValue(serviceProvider); // return binding to Param1.SomeInnerProperty
}
private static DependencyProperty Param1BindingSinkProperty = DependencyProperty.RegisterAttached("Param1BindingSink", typeof(object)// set the desired type of Param1 for at least runtime type safety check
, typeof(MarkupExtensionWithBindableParam ), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
}
使い方は簡単です:
<TextBlock Text="{local:MarkupExtensionWithBindableParam Param1={Binding Path='SomePathToParam1'}}"/>