Xamarin 表单 - GetBindingExpression

Posted

技术标签:

【中文标题】Xamarin 表单 - GetBindingExpression【英文标题】:Xamarin Forms - GetBindingExpression 【发布时间】:2018-01-02 13:08:25 【问题描述】:

在 Silverlight(和其他基于 XAML 的技术)中,有一个名为 GetBindingExpression 的方法,它允许我们检查给定依赖属性上的绑定。该方法位于 FrameworkElement 上,因此每个控件都可以让我们访问绑定表达式。

例如:

var selectedItemBindingExpression = GetBindingExpression(SelectedItemProperty);

但是,Xamarin Forms 中似乎没有等效项。有没有办法从 Xamarin Forms 中的 BindableProperty 属性获取绑定表达式?

【问题讨论】:

【参考方案1】:

我认为Xamarin.Forms 中没有任何公共 API 可用于访问 BindingExpression - 但您可以使用反射来访问关联的 BindingBindingExpression

public static class BindingObjectExtensions

    public static Binding GetBinding(this BindableObject self, BindableProperty property)
    
        var methodInfo = typeof(BindableObject).GetTypeInfo().GetDeclaredMethod("GetContext");
        var context = methodInfo?.Invoke(self, new[]  property );

        var propertyInfo = context?.GetType().GetTypeInfo().GetDeclaredField("Binding");
        return propertyInfo?.GetValue(context) as Binding;
    

    public static object GetBindingExpression(this Binding self)
    
        var fieldInfo = self?.GetType().GetTypeInfo().GetDeclaredField("_expression");
        return fieldInfo?.GetValue(self);
    

示例用法 - 获取绑定表达式

var expr = this.GetBinding(TextProperty).GetBindingExpression();

示例用法 - 获取绑定路径(07/27 更新)

//to access path - you can directly use the binding object
var binding = this.GetBinding(TextProperty);
var path = binding?.Path;

【讨论】:

优秀。我以前做过这种事情。 Xamarin 团队喜欢无缘无故地向我们隐瞒东西。 将对此进行测试。 也许添加一点来解释如何获取 BindableProperty?对于任何从静态条目中查找它的人,例如 _associatedObject.GetBinding(Entry.TextProperty)【参考方案2】:

改进了 Sharada Gururaj 的解决方案:

public static class BindingObjectExtensions

    private static MethodInfo _bindablePropertyGetContextMethodInfo = typeof(BindableObject).GetMethod("GetContext", BindingFlags.NonPublic | BindingFlags.Instance);
    private static FieldInfo _bindablePropertyContextBindingFieldInfo;

    public static Binding GetBinding(this BindableObject bindableObject, BindableProperty bindableProperty)
    
        object bindablePropertyContext = _bindablePropertyGetContextMethodInfo.Invoke(bindableObject, new[]  bindableProperty );

        if (bindablePropertyContext != null)
        
            FieldInfo propertyInfo = _bindablePropertyContextBindingFieldInfo = 
                _bindablePropertyContextBindingFieldInfo ?? 
                    bindablePropertyContext.GetType().GetField("Binding");

            return (Binding) propertyInfo.GetValue(bindablePropertyContext);
        

        return null; 

我的解决方案有以下改进:

    缓存通过反射获得的对象(提高性能) 删除了不必要的空检查 直接使用反射,使用IntrospectionExtensions是 不必要的 不需要 GetBindingExpression 方法(有关 绑定可以从 Binding 类中检索)

【讨论】:

嗨,Igor,欢迎来到 ***,你认为你可以添加一些解释,说明为什么这个答案是一个改进吗?它是否使用更新的 API,提供更多功能等。 嗨 sedders123,我的解决方案有以下改进 1) 缓存通过反射获得的对象(提高性能) 2) 我删除了不必要的 null 检查 3) 我直接使用反射,使用 IntrospectionExtensions 是不必要的 4) 不需要 GetBindingExpression 方法(所有关于绑定的信息都可以从 Binding 类中检索) 太棒了 :) 您能否编辑您的答案以包含此信息?将其添加到答案中可确保未来的用户可以轻松了解为什么这是一个与其他任何答案不同且可能更好的解决方案。

以上是关于Xamarin 表单 - GetBindingExpression的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin 和 Xamarin 表单的符号包(PDB 文件)

Xamarin 表单发送图像

使用 Xamarin.Mobile 读取 Xamarin 表单中的联系人时出错

重复服务呼叫 - Xamarin 表单

如何将 android 活动导航到 xamarin 表单

TeamCity 上的 Xamarin 表单:Xamarin.Forms 任务与目标不匹配