如果您在后面的代码中创建绑定,那么您可以让它工作。例如一个简单的代码生成绑定是:
Binding binding = new Binding("BindingPath");
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(textBoxName, TextBox.TextProperty, binding);
由于此绑定中的路径(“BindingPath”)只是一个字符串,该字符串可以来自任何可用的对象。
不过,您需要挂钩数据项的创建以设置这些绑定。
基于您的 cmets 的进一步可能性:
This blog post 概述了一种通过从 MarkupExtension 继承来创建自定义绑定类的方法。您可以以此为起点,将我的建议包装成可重复使用的 xaml 标记,以用于您的特殊绑定案例。
更多想法:
好的,这是一个有趣的问题,所以我决定花一点时间看看我是否能想出一个可行的解决方案。对于以下代码示例的长度,我提前道歉...
基于我上面链接的博客文章的解决方案,我创建了这个类:
public class IndirectBinder : MarkupExtension
{
public string IndirectProperty { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
//try to get bound items for our custom work
DependencyObject targetObject;
DependencyProperty targetProperty;
bool status = TryGetTargetItems(serviceProvider, out targetObject, out targetProperty);
if (status)
{
Control targetControl = targetObject as Control;
if (targetControl == null) return null;
//Find the object to take the binding from
object dataContext = targetControl.DataContext;
if (dataContext == null) return null;
//Reflect out the indirect property and get the value
PropertyInfo pi = dataContext.GetType().GetProperty(IndirectProperty);
if (pi == null) return null;
string realProperty = pi.GetValue(dataContext, null) as string;
if (realProperty == null) return null;
//Create the binding against the inner property
Binding binding = new Binding(realProperty);
binding.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(targetObject, targetProperty, binding);
//Return the initial value of the binding
PropertyInfo realPi = dataContext.GetType().GetProperty(realProperty);
if (realPi == null) return null;
return realPi.GetValue(dataContext, null);
}
return null;
}
protected virtual bool TryGetTargetItems(IServiceProvider provider, out DependencyObject target, out DependencyProperty dp)
{
target = null;
dp = null;
if (provider == null) return false;
//create a binding and assign it to the target
IProvideValueTarget service = (IProvideValueTarget)provider.GetService(typeof(IProvideValueTarget));
if (service == null) return false;
//we need dependency objects / properties
target = service.TargetObject as DependencyObject;
dp = service.TargetProperty as DependencyProperty;
return target != null && dp != null;
}
您可以将此新标记与以下 xaml 一起使用:
<TextBox Text="{local:IndirectBinder IndirectProperty=FieldValuePath}"/>
其中 TextBox 可以是任何从控件继承的类,Text 可以是任何依赖属性。
显然,如果您需要公开任何其他数据绑定选项(例如单向或双向绑定),那么您需要向类添加更多属性。
虽然这是一个复杂的解决方案,但它比使用转换器的一个优点是最终创建的绑定是针对实际的内部属性而不是对象。这意味着它可以正确响应 PropertyChanged 事件。