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

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

例如:

var selectedItemBindingExpression = GetBindingExpression(SelectedItemProperty);

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

【问题讨论】:

    标签: c# wpf silverlight xamarin.forms


    【解决方案1】:

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

    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; 
    }
    

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

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

    【讨论】:

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