我发现这样做的唯一方法是使用反射。以下代码获取绑定的对象。它还处理嵌套绑定{Binding Parent.Value}
,如果存在转换器 - 它返回转换后的值。对于项目为空的情况,该方法还返回项目的类型。
private static object GetBindedItem(FrameworkElement fe, out Type bindedItemType)
{
bindedItemType = null;
var exp = fe.GetBindingExpression(TextBox.TextProperty);
if (exp == null || exp.ParentBinding == null || exp.ParentBinding.Path == null
|| exp.ParentBinding.Path.Path == null)
return null;
string bindingPath = exp.ParentBinding.Path.Path;
string[] elements = bindingPath.Split('.');
var item = GetItem(fe.DataContext, elements, out bindedItemType);
// If a converter is used - don't ignore it
if (exp.ParentBinding.Converter != null)
{
var convOutput = exp.ParentBinding.Converter.Convert(item,
bindedItemType, exp.ParentBinding.ConverterParameter, CultureInfo.CurrentCulture);
if (convOutput != null)
{
item = convOutput;
bindedItemType = convOutput.GetType();
}
}
return item;
}
private static object GetItem(object data, string[] elements, out Type itemType)
{
if (elements.Length == 0)
{
itemType = data.GetType();
return data;
}
if (elements.Length == 1)
{
var accesor = data.GetType().GetProperty(elements[0]);
itemType = accesor.PropertyType;
return accesor.GetValue(data, null);
}
string[] innerElements = elements.Skip(1).ToArray();
object innerData = data.GetType().GetProperty(elements[0]).GetValue(data);
return GetItem(innerData, innerElements, out itemType);
}